From 220f59f9b7bb00e05f77aa425d84b79f9fd4cd74 Mon Sep 17 00:00:00 2001 From: Nikita Amelchev Date: Wed, 28 Dec 2022 22:31:09 +0300 Subject: [PATCH] IGNITE-18463 Fixed snapshot cancel if one path is configured for several nodes (#10462) --- .../snapshot/IgniteSnapshotManager.java | 61 ++++++++++--------- .../ignite/internal/util/IgniteUtils.java | 4 +- .../IgniteClusterSnapshotSelfTest.java | 6 +- 3 files changed, 37 insertions(+), 34 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotManager.java index 4bf57ead78130..3fa01e50df554 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotManager.java @@ -669,54 +669,57 @@ public void deleteSnapshot(File snpDir, String folderName) { try { File binDir = binaryWorkDir(snpDir.getAbsolutePath(), folderName); File nodeDbDir = new File(snpDir.getAbsolutePath(), databaseRelativePath(folderName)); + File smf = new File(snpDir, snapshotMetaFileName(folderName)); U.delete(binDir); U.delete(nodeDbDir); + U.delete(smf); File marshDir = mappingFileStoreWorkDir(snpDir.getAbsolutePath()); - // Concurrently traverse the snapshot marshaller directory and delete all files. - Files.walkFileTree(marshDir.toPath(), new SimpleFileVisitor() { - @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { - U.delete(file); - - return FileVisitResult.CONTINUE; - } - - @Override public FileVisitResult visitFileFailed(Path file, IOException exc) { - // Skip files which can be concurrently removed from FileTree. - return FileVisitResult.CONTINUE; - } - - @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) { - dir.toFile().delete(); - - if (log.isInfoEnabled() && exc != null) - log.info("Marshaller directory cleaned with an exception: " + exc.getMessage()); - - return FileVisitResult.CONTINUE; - } - }); + deleteDirectory(marshDir); File binMetadataDfltDir = new File(snpDir, DFLT_BINARY_METADATA_PATH); File marshallerDfltDir = new File(snpDir, DFLT_MARSHALLER_PATH); - U.delete(binMetadataDfltDir); - U.delete(marshallerDfltDir); + deleteDirectory(binMetadataDfltDir); + deleteDirectory(marshallerDfltDir); File db = new File(snpDir, DB_DEFAULT_FOLDER); - if (!db.exists() || F.isEmpty(db.list())) { - marshDir.delete(); - db.delete(); - U.delete(snpDir); - } + db.delete(); + snpDir.delete(); } catch (IOException e) { throw new IgniteException(e); } } + /** Concurrently traverse the directory and delete all files. */ + private void deleteDirectory(File dir) throws IOException { + Files.walkFileTree(dir.toPath(), new SimpleFileVisitor() { + @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { + U.delete(file); + + return FileVisitResult.CONTINUE; + } + + @Override public FileVisitResult visitFileFailed(Path file, IOException exc) { + // Skip files which can be concurrently removed from FileTree. + return FileVisitResult.CONTINUE; + } + + @Override public FileVisitResult postVisitDirectory(Path dir, IOException e) { + dir.toFile().delete(); + + if (log.isInfoEnabled() && e != null) + log.info("Snapshot directory cleaned with an exception [dir=" + dir + ", e=" + e.getMessage() + ']'); + + return FileVisitResult.CONTINUE; + } + }); + } + /** * @param snpName Snapshot name. * @return Local snapshot directory for snapshot with given name. diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java index 6e22cb72b8cd1..4e6754e2a4cc2 100755 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java @@ -3735,7 +3735,7 @@ public static E withCause(E e, @Nullable Throwable cause) } /** - * Deletes file or directory with all sub-directories and files. + * Deletes file or directory with all sub-directories and files. Not thread-safe. * * @param file File or directory to delete. * @return {@code true} if and only if the file or directory is successfully deleted, @@ -3756,7 +3756,7 @@ public static int sizeInMegabytes(long sizeInBytes) { } /** - * Deletes file or directory with all sub-directories and files. + * Deletes file or directory with all sub-directories and files. Not thread-safe. * * @param path File or directory to delete. * @return {@code true} if and only if the file or directory is successfully deleted, diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotSelfTest.java index ea33a9a9646ee..06a97542ce1fa 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotSelfTest.java @@ -1200,9 +1200,9 @@ public void testClusterSnapshotFromClientDisconnected() throws Exception { /** @throws Exception If fails. */ @Test public void testClusterSnapshotInProgressCancelled() throws Exception { - IgniteEx srv = startGridsWithCache(1, dfltCacheCfg, CACHE_KEYS_RANGE); - IgniteEx startCli = startClientGrid(1); - IgniteEx killCli = startClientGrid(2); + IgniteEx srv = startGridsWithCache(3, dfltCacheCfg, CACHE_KEYS_RANGE); + IgniteEx startCli = startClientGrid(3); + IgniteEx killCli = startClientGrid(4); doSnapshotCancellationTest(startCli, Collections.singletonList(srv), srv.cache(dfltCacheCfg.getName()), snpName -> killCli.snapshot().cancelSnapshot(snpName).get());