This is an automated email from the ASF dual-hosted git repository.

mmuzaf pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 5c7ace1  IGNITE-16194 Fix snapshot restore fails if metadata is 
missing on any blt node.  (#9690)
5c7ace1 is described below

commit 5c7ace19c06ee5f643c64d5cc422240c7dcb6dca
Author: Pavel Pereslegin <[email protected]>
AuthorDate: Fri Dec 24 12:50:54 2021 +0300

    IGNITE-16194 Fix snapshot restore fails if metadata is missing on any blt 
node.  (#9690)
---
 .../snapshot/IgniteSnapshotManager.java            |  9 +++--
 .../IgniteSnapshotRestoreFromRemoteTest.java       | 41 ++++++++++++++++++++++
 2 files changed, 48 insertions(+), 2 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 9be0829..f8c4abb 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
@@ -1241,9 +1241,14 @@ public class IgniteSnapshotManager extends 
GridCacheSharedManagerAdapter
         A.notNullOrEmpty(snpName, "Snapshot name cannot be null or empty.");
         A.ensure(U.alphanumericUnderscore(snpName), "Snapshot name must 
satisfy the following name pattern: a-zA-Z0-9_");
 
+        File snpDir = snapshotLocalDir(snpName);
+
+        if (!(snpDir.exists() && snpDir.isDirectory()))
+            return Collections.emptyList();
+
         List<File> smfs = new ArrayList<>();
 
-        try (DirectoryStream<Path> ds = 
Files.newDirectoryStream(snapshotLocalDir(snpName).toPath())) {
+        try (DirectoryStream<Path> ds = 
Files.newDirectoryStream(snpDir.toPath())) {
             for (Path d : ds) {
                 if (Files.isRegularFile(d) && 
d.getFileName().toString().toLowerCase().endsWith(SNAPSHOT_METAFILE_EXT))
                     smfs.add(d.toFile());
@@ -1254,7 +1259,7 @@ public class IgniteSnapshotManager extends 
GridCacheSharedManagerAdapter
         }
 
         if (smfs.isEmpty())
-            throw new IgniteException("Snapshot metadata files not found: " + 
snpName);
+            return Collections.emptyList();
 
         Map<String, SnapshotMetadata> metasMap = new HashMap<>();
         SnapshotMetadata prev = null;
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotRestoreFromRemoteTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotRestoreFromRemoteTest.java
index 56ef3c2..fa75b56 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotRestoreFromRemoteTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotRestoreFromRemoteTest.java
@@ -44,6 +44,8 @@ import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.internal.TestRecordingCommunicationSpi;
 import 
org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionDemandMessage;
 import 
org.apache.ignite.internal.processors.cache.persistence.partstate.GroupPartitionId;
+import org.apache.ignite.internal.processors.cache.verify.IdleVerifyResultV2;
+import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.G;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteFuture;
@@ -59,6 +61,7 @@ import static 
org.apache.ignite.events.EventType.EVT_CLUSTER_SNAPSHOT_RESTORE_FI
 import static 
org.apache.ignite.events.EventType.EVT_CLUSTER_SNAPSHOT_RESTORE_STARTED;
 import static 
org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.partId;
 import static 
org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.resolveSnapshotWorkDirectory;
+import static org.apache.ignite.testframework.GridTestUtils.assertContains;
 
 /** */
 public class IgniteSnapshotRestoreFromRemoteTest extends 
IgniteClusterSnapshotRestoreBaseTest {
@@ -178,6 +181,44 @@ public class IgniteSnapshotRestoreFromRemoteTest extends 
IgniteClusterSnapshotRe
 
     /** @throws Exception If failed. */
     @Test
+    public void testRestoreFromAnEmptyNode() throws Exception {
+        startDedicatedGrids(SECOND_CLUSTER_PREFIX, 2);
+
+        copyAndShuffle(snpParts, G.allGrids());
+
+        // Start a new node without snapshot working directory.
+        IgniteEx emptyNode = startDedicatedGrid(SECOND_CLUSTER_PREFIX, 2);
+
+        emptyNode.cluster().state(ClusterState.ACTIVE);
+
+        emptyNode.cache(DEFAULT_CACHE_NAME).destroy();
+        awaitPartitionMapExchange();
+
+        // Ensure that the snapshot check command succeeds.
+        IdleVerifyResultV2 res =
+            
emptyNode.context().cache().context().snapshotMgr().checkSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+
+        StringBuilder buf = new StringBuilder();
+        res.print(buf::append, true);
+
+        assertTrue(F.isEmpty(res.exceptions()));
+        assertPartitionsSame(res);
+        assertContains(log, buf.toString(), "The check procedure has finished, 
no conflicts have been found");
+
+        // Restore all cache groups.
+        emptyNode.snapshot().restoreSnapshot(SNAPSHOT_NAME, null).get(TIMEOUT);
+
+        awaitPartitionMapExchange(true, true, null, true);
+
+        for (Ignite grid : G.allGrids()) {
+            assertCacheKeys(grid.cache(DEFAULT_CACHE_NAME), CACHE_KEYS_RANGE);
+            assertCacheKeys(grid.cache(CACHE1), CACHE_KEYS_RANGE);
+            assertCacheKeys(grid.cache(CACHE2), CACHE_KEYS_RANGE);
+        }
+    }
+
+    /** @throws Exception If failed. */
+    @Test
     public void testRestoreNoRebalance() throws Exception {
         IgniteEx scc = startDedicatedGrids(SECOND_CLUSTER_PREFIX, 2);
         scc.cluster().state(ClusterState.ACTIVE);

Reply via email to