Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import java.io.File;
import java.io.IOException;
import java.nio.file.NoSuchFileException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
Expand Down Expand Up @@ -63,10 +64,15 @@ public static void createCacheStorages(NodeFileTree ft, IgniteLogger log) throws
public static void removeTmpSnapshotFiles(SnapshotFileTree sft, boolean err, IgniteLogger log) {
NodeFileTree tmpFt = sft.tempFileTree();

removeTmpDir(tmpFt.root(), err, log);
U.delete(tmpFt.nodeStorage());

for (File tmpDrStorage : tmpFt.extraStorages().values())
removeTmpDir(tmpDrStorage.getParentFile(), err, log);
for (File tmpDrStorage : tmpFt.extraStorages().values()) {
U.delete(tmpDrStorage);

deleteSnapshotTempRoot(tmpDrStorage.getParentFile(), err, log);
}

deleteSnapshotTempRoot(tmpFt.root(), err, log);
}

/**
Expand Down Expand Up @@ -104,20 +110,20 @@ public static Set<String> nodeStorages(DataStorageConfiguration dsCfg) throws Ig
}

/**
* @param dir Directory to remove
* @param err If {@code true} then operation ends with error.
* @param root Snapshot temporary root.
* @param err {@code True} if snapshot processing finished with an error.
* @param log Logger.
*/
private static void removeTmpDir(File dir, boolean err, IgniteLogger log) {
U.delete(dir);

// Delete snapshot directory if no other files exists.
private static void deleteSnapshotTempRoot(File root, boolean err, IgniteLogger log) {
try {
if (U.fileCount(dir.toPath()) == 0 || err)
U.delete(dir.toPath());
if (err || U.fileCount(root.toPath()) == 0)
U.delete(root.toPath());
}
catch (NoSuchFileException ignored) {
// Snapshot temporary root has already been removed.
}
catch (IOException e) {
log.error("Snapshot directory doesn't exist [snpName=" + dir.getName() + ", dir=" + dir.getParentFile() + ']');
log.error("Failed to clean up snapshot temporary root [dir=" + root + ']', e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@
import org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager;
import org.apache.ignite.internal.processors.cache.persistence.file.FileVersionCheckingFactory;
import org.apache.ignite.internal.processors.cache.persistence.file.RandomAccessFileIOFactory;
import org.apache.ignite.internal.processors.cache.persistence.filename.FileTreeUtils;
import org.apache.ignite.internal.processors.cache.persistence.filename.NodeFileTree;
import org.apache.ignite.internal.processors.cache.persistence.filename.SnapshotFileTree;
import org.apache.ignite.internal.processors.cache.persistence.partstate.GroupPartitionId;
import org.apache.ignite.internal.util.GridCloseableIteratorAdapter;
Expand Down Expand Up @@ -647,6 +649,70 @@ public void testFullSnapshotCreationLog() throws Exception {
assertFalse(noMatchParams.check());
}

/**
* Tests that snapshot temporary root is not removed on successful cleanup if it still contains files after
* node-specific storage has been removed.
*/
@Test
public void testSnapshotTmpRootIsNotRemovedIfNotEmptyOnSuccess() throws Exception {
IgniteEx ignite = startGridWithCache(dfltCacheCfg, CACHE_KEYS_RANGE);

SnapshotFileTree sft = snapshotFileTree(ignite, SNAPSHOT_NAME);

NodeFileTree tmpFt = sft.tempFileTree();

File root = tmpFt.root();
File nodeStorage = tmpFt.nodeStorage();

assertTrue(nodeStorage.mkdirs());

File extraFile = new File(root, "unexpected-tmp-file");

assertTrue(extraFile.createNewFile());

try {
FileTreeUtils.removeTmpSnapshotFiles(sft, false, log);

assertFalse("Node-specific temporary storage must be removed: " + nodeStorage, nodeStorage.exists());

assertTrue("Snapshot temporary root must not be removed if it is not empty: " + root, root.exists());

assertTrue("Unexpected temporary file must not be removed on successful cleanup: " + extraFile,
extraFile.exists());
}
finally {
U.delete(root);
}
}

/**
* Tests that snapshot temporary root is removed on cleanup after an error even if it still contains files after
* node-specific storage has been removed.
*/
@Test
public void testSnapshotTmpRootIsRemovedIfNotEmptyOnError() throws Exception {
IgniteEx ignite = startGridWithCache(dfltCacheCfg, CACHE_KEYS_RANGE);

SnapshotFileTree sft = snapshotFileTree(ignite, SNAPSHOT_NAME);

NodeFileTree tmpFt = sft.tempFileTree();

File root = tmpFt.root();
File nodeStorage = tmpFt.nodeStorage();

assertTrue(nodeStorage.mkdirs());

File extraFile = new File(root, "unexpected-tmp-file");

assertTrue(extraFile.createNewFile());

FileTreeUtils.removeTmpSnapshotFiles(sft, true, log);

assertFalse("Node-specific temporary storage must be removed: " + nodeStorage, nodeStorage.exists());

assertFalse("Snapshot temporary root must be removed on error: " + root, root.exists());
}

/**
* @param ignite Ignite instance to set factory.
* @param factory New factory to use.
Expand Down
Loading