Skip to content

Commit

Permalink
IGNITE-20589 Lazy creation of snapshot dir for in-memory cluster (#10981
Browse files Browse the repository at this point in the history
)
  • Loading branch information
nizhikov authored Oct 10, 2023
1 parent aa75904 commit e3e3ede
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@
import static org.apache.ignite.internal.pagemem.PageIdUtils.pageIndex;
import static org.apache.ignite.internal.pagemem.PageIdUtils.toDetailString;
import static org.apache.ignite.internal.processors.cache.GridCacheUtils.baselineNode;
import static org.apache.ignite.internal.processors.cache.GridCacheUtils.isPersistenceEnabled;
import static org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl.binaryWorkDir;
import static org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl.resolveBinaryWorkDir;
import static org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.INDEX_FILE_NAME;
Expand Down Expand Up @@ -415,7 +416,7 @@ public class IgniteSnapshotManager extends GridCacheSharedManagerAdapter
* Working directory for loaded snapshots from the remote nodes and storing
* temporary partition delta-files of locally started snapshot process.
*/
private File tmpWorkDir;
private @Nullable File tmpWorkDir;

/** Factory to working with delta as file storage. */
private volatile FileIOFactory ioFactory = new RandomAccessFileIOFactory();
Expand Down Expand Up @@ -535,11 +536,15 @@ public static String partDeltaFileName(int partId) {

pdsSettings = cctx.kernalContext().pdsFolderResolver().resolveFolders();

locSnpDir = resolveSnapshotWorkDirectory(ctx.config());
tmpWorkDir = U.resolveWorkDirectory(pdsSettings.persistentStoreNodePath().getAbsolutePath(), DFLT_SNAPSHOT_TMP_DIR, true);
boolean persistenceEnabled = isPersistenceEnabled(cctx.gridConfig());

U.ensureDirectory(locSnpDir, "snapshot work directory", log);
U.ensureDirectory(tmpWorkDir, "temp directory for snapshot creation", log);
if (persistenceEnabled) {
tmpWorkDir = U.resolveWorkDirectory(pdsSettings.persistentStoreNodePath().getAbsolutePath(), DFLT_SNAPSHOT_TMP_DIR, true);

U.ensureDirectory(tmpWorkDir, "temp directory for snapshot creation", log);
}

initLocalSnapshotDirectory(persistenceEnabled);

ctx.internalSubscriptionProcessor().registerDistributedConfigurationListener(
new DistributedConfigurationLifecycleListener() {
Expand Down Expand Up @@ -691,19 +696,23 @@ public static String partDeltaFileName(int partId) {
})),
Function.identity());

Arrays.stream(locSnpDir.listFiles())
.filter(File::isDirectory)
.map(dumpDir ->
Paths.get(dumpDir.getAbsolutePath(), DB_DEFAULT_FOLDER, pdsSettings.folderName(), DUMP_LOCK).toFile())
.filter(File::exists)
.map(File::getParentFile)
.forEach(lockedDumpDir -> {
log.warning("Found locked dump dir. " +
"This means, dump creation not finished prior to node fail. " +
"Directory will be deleted: " + lockedDumpDir);

U.delete(lockedDumpDir);
});
File[] files = locSnpDir.listFiles();

if (files != null) {
Arrays.stream(files)
.filter(File::isDirectory)
.map(dumpDir ->
Paths.get(dumpDir.getAbsolutePath(), DB_DEFAULT_FOLDER, pdsSettings.folderName(), DUMP_LOCK).toFile())
.filter(File::exists)
.map(File::getParentFile)
.forEach(lockedDumpDir -> {
log.warning("Found locked dump dir. " +
"This means, dump creation not finished prior to node fail. " +
"Directory will be deleted: " + lockedDumpDir);

U.delete(lockedDumpDir);
});
}
}

/** {@inheritDoc} */
Expand Down Expand Up @@ -898,6 +907,19 @@ public File snapshotTmpDir() {
return tmpWorkDir;
}

/** */
private void initLocalSnapshotDirectory(boolean create) {
try {
locSnpDir = resolveSnapshotWorkDirectory(cctx.kernalContext().config(), create);

if (create)
U.ensureDirectory(locSnpDir, "snapshot work directory", log);
}
catch (IgniteCheckedException e) {
throw new IgniteException(e);
}
}

/**
* @param req Request on snapshot creation.
* @return Future which will be completed when a snapshot has been started.
Expand Down Expand Up @@ -1127,6 +1149,9 @@ private IgniteInternalFuture<SnapshotOperationResponse> initLocalFullSnapshot(
Collection<Integer> comprGrpIds,
boolean withMetaStorage
) {
if (!isPersistenceEnabled(cctx.gridConfig()))
initLocalSnapshotDirectory(true);

Map<Integer, Set<Integer>> parts = new HashMap<>();

// Prepare collection of pairs group and appropriate cache partition to be snapshot.
Expand Down Expand Up @@ -2971,9 +2996,18 @@ static String databaseRelativePath(String folderName) {
* @return Snapshot directory resolved through given configuration.
*/
public static File resolveSnapshotWorkDirectory(IgniteConfiguration cfg) {
return resolveSnapshotWorkDirectory(cfg, true);
}

/**
* @param cfg Ignite configuration.
* @param create If {@code true} then create resolved directory if not exists.
* @return Snapshot directory resolved through given configuration.
*/
public static File resolveSnapshotWorkDirectory(IgniteConfiguration cfg, boolean create) {
try {
return U.resolveWorkDirectory(cfg.getWorkDirectory() == null ? U.defaultWorkDirectory() : cfg.getWorkDirectory(),
cfg.getSnapshotPath(), false);
cfg.getSnapshotPath(), false, create);
}
catch (IgniteCheckedException e) {
throw new IgniteException(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10025,7 +10025,21 @@ public static void nullifyHomeDirectory() {
* @return Resolved work directory.
* @throws IgniteCheckedException If failed.
*/
public static File resolveWorkDirectory(String workDir, String path, boolean delIfExist)
public static File resolveWorkDirectory(String workDir, String path, boolean delIfExist) throws IgniteCheckedException {
return resolveWorkDirectory(workDir, path, delIfExist, true);
}

/**
* Resolves work directory.
*
* @param workDir Work directory.
* @param path Path to resolve.
* @param delIfExist Flag indicating whether to delete the specify directory or not.
* @param create If {@code true} then directory must be created if not exists.
* @return Resolved work directory.
* @throws IgniteCheckedException If failed.
*/
public static File resolveWorkDirectory(String workDir, String path, boolean delIfExist, boolean create)
throws IgniteCheckedException {
File dir = new File(path);

Expand All @@ -10041,6 +10055,9 @@ public static File resolveWorkDirectory(String workDir, String path, boolean del
throw new IgniteCheckedException("Failed to delete directory: " + dir);
}

if (!create)
return dir;

if (!mkdirs(dir))
throw new IgniteCheckedException("Directory does not exist and cannot be created: " + dir);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import org.apache.ignite.internal.processors.cacheobject.UserCacheObjectImpl;
import org.apache.ignite.internal.processors.dr.GridDrType;
import org.apache.ignite.internal.util.typedef.internal.CU;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.platform.model.User;
import org.apache.ignite.testframework.ListeningTestLogger;
import org.apache.ignite.testframework.LogListener;
Expand All @@ -52,10 +53,12 @@

import static java.nio.file.StandardOpenOption.READ;
import static java.nio.file.StandardOpenOption.WRITE;
import static org.apache.ignite.configuration.IgniteConfiguration.DFLT_SNAPSHOT_DIRECTORY;
import static org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.CACHE_DATA_FILENAME;
import static org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.CACHE_DIR_PREFIX;
import static org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.PART_FILE_PREFIX;
import static org.apache.ignite.internal.processors.cache.persistence.filename.PdsFolderResolver.DB_DEFAULT_FOLDER;
import static org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.DFLT_SNAPSHOT_TMP_DIR;
import static org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.DUMP_LOCK;
import static org.apache.ignite.internal.processors.cache.persistence.snapshot.dump.AbstractCacheDumpTest.DMP_NAME;
import static org.apache.ignite.internal.processors.cache.persistence.snapshot.dump.AbstractCacheDumpTest.KEYS_CNT;
Expand Down Expand Up @@ -96,6 +99,21 @@ public class IgniteCacheDumpSelf2Test extends GridCommonAbstractTest {
cleanPersistenceDir();
}

/** */
@Test
public void testSnapshotDirectoryCreatedLazily() throws Exception {
try (IgniteEx ign = startGrid(new IgniteConfiguration())) {
File snpDir = new File(U.defaultWorkDirectory(), DFLT_SNAPSHOT_DIRECTORY);
File tmpSnpDir = new File(
ign.context().pdsFolderResolver().resolveFolders().persistentStoreNodePath().getAbsolutePath(),
DFLT_SNAPSHOT_TMP_DIR
);

assertFalse(snpDir + " must created lazily for in-memory node", snpDir.exists());
assertFalse(tmpSnpDir + " must created lazily for in-memory node", tmpSnpDir.exists());
}
}

/** */
@Test
public void testDumpFailIfNoCaches() throws Exception {
Expand Down

0 comments on commit e3e3ede

Please sign in to comment.