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);