This is an automated email from the ASF dual-hosted git repository. nizhikov 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 dd777fbbf77 IGNITE-19144 Check flag for snapshot restore implemented (#10612) dd777fbbf77 is described below commit dd777fbbf77a1ad6d51f3d62e784b4f4027da3c1 Author: Nikolay <nizhi...@apache.org> AuthorDate: Thu Mar 30 10:53:00 2023 +0300 IGNITE-19144 Check flag for snapshot restore implemented (#10612) --- .../snapshot/SnapshotRestoreCommand.java | 14 ++++- .../snapshot/SnapshotRestoreCommandOption.java | 5 +- .../apache/ignite/util/GridCommandHandlerTest.java | 70 ++++++++++++++-------- .../snapshot/AbstractSnapshotVerificationTask.java | 21 ++++++- .../snapshot/IgniteSnapshotManager.java | 25 +++++--- .../snapshot/SnapshotHandlerContext.java | 20 ++++++- .../snapshot/SnapshotHandlerRestoreTask.java | 20 +++++-- .../persistence/snapshot/SnapshotMXBeanImpl.java | 9 ++- .../snapshot/SnapshotPartitionsVerifyHandler.java | 6 ++ .../snapshot/SnapshotPartitionsVerifyTask.java | 25 ++++++-- .../snapshot/SnapshotPartitionsVerifyTaskArg.java | 15 ++++- .../SnapshotPartitionsVerifyTaskResult.java | 13 ++-- .../snapshot/SnapshotRestoreProcess.java | 11 +++- .../visor/snapshot/VisorSnapshotRestoreTask.java | 9 ++- .../snapshot/VisorSnapshotRestoreTaskArg.java | 15 ++++- .../snapshot/IgniteClusterSnapshotCheckTest.java | 26 +++++--- .../IncrementalSnapshotCheckBeforeRestoreTest.java | 27 +++++---- ...ridCommandHandlerClusterByClassTest_help.output | 3 +- ...andHandlerClusterByClassWithSSLTest_help.output | 3 +- 19 files changed, 251 insertions(+), 86 deletions(-) diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/snapshot/SnapshotRestoreCommand.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/snapshot/SnapshotRestoreCommand.java index bd14ef67619..41fadff89d7 100644 --- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/snapshot/SnapshotRestoreCommand.java +++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/snapshot/SnapshotRestoreCommand.java @@ -31,6 +31,7 @@ import org.apache.ignite.internal.visor.snapshot.VisorSnapshotRestoreTaskArg; import static org.apache.ignite.internal.commandline.CommandList.SNAPSHOT; import static org.apache.ignite.internal.commandline.CommandLogger.optional; +import static org.apache.ignite.internal.commandline.snapshot.SnapshotRestoreCommandOption.CHECK; import static org.apache.ignite.internal.commandline.snapshot.SnapshotRestoreCommandOption.GROUPS; import static org.apache.ignite.internal.commandline.snapshot.SnapshotRestoreCommandOption.INCREMENT; import static org.apache.ignite.internal.commandline.snapshot.SnapshotRestoreCommandOption.SOURCE; @@ -90,6 +91,7 @@ public class SnapshotRestoreCommand extends SnapshotSubcommand { Integer incIdx = null; Set<String> grpNames = null; boolean sync = false; + boolean check = false; if (restoreAction != null) argIter.nextArg(null); @@ -147,9 +149,15 @@ public class SnapshotRestoreCommand extends SnapshotSubcommand { sync = true; } + else if (option == CHECK) { + if (check) + throw new IllegalArgumentException(CHECK.argName() + " arg specified twice."); + + check = true; + } } - cmdArg = new VisorSnapshotRestoreTaskArg(snpName, snpPath, incIdx, sync, restoreAction, grpNames); + cmdArg = new VisorSnapshotRestoreTaskArg(snpName, snpPath, incIdx, sync, restoreAction, grpNames, check); } /** {@inheritDoc} */ @@ -161,12 +169,14 @@ public class SnapshotRestoreCommand extends SnapshotSubcommand { startParams.put(SOURCE.argName() + " " + SOURCE.arg(), SOURCE.description()); startParams.put(INCREMENT.argName() + " " + INCREMENT.arg(), INCREMENT.description()); startParams.put(SYNC.argName(), SYNC.description()); + startParams.put(CHECK.argName(), CHECK.description()); usage(log, "Restore snapshot:", SNAPSHOT, startParams, RESTORE.toString(), SNAPSHOT_NAME_ARG, optional(INCREMENT.argName(), INCREMENT.arg()), optional(GROUPS.argName(), GROUPS.arg()), optional(SOURCE.argName(), SOURCE.arg()), - optional(SYNC.argName())); + optional(SYNC.argName()), + optional(CHECK.argName())); usage(log, "Snapshot restore operation status (Command deprecated. Use '" + SNAPSHOT + ' ' + SnapshotSubcommands.STATUS + "' instead):", SNAPSHOT, params, RESTORE.toString(), SNAPSHOT_NAME_ARG, "--status"); usage(log, "Cancel snapshot restore operation (Command deprecated. Use '" + SNAPSHOT + ' ' diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/snapshot/SnapshotRestoreCommandOption.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/snapshot/SnapshotRestoreCommandOption.java index fa1fe23cb65..9889d9696ed 100644 --- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/snapshot/SnapshotRestoreCommandOption.java +++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/snapshot/SnapshotRestoreCommandOption.java @@ -37,7 +37,10 @@ public enum SnapshotRestoreCommandOption implements CommandArg { /** Synchronous execution flag. */ SYNC(SnapshotCreateCommandOption.SYNC.argName(), SnapshotCreateCommandOption.SYNC.arg(), - SnapshotCreateCommandOption.SYNC.description()); + SnapshotCreateCommandOption.SYNC.description()), + + /** Check snapshot before restore. */ + CHECK("--check", null, "Check snapshot data integrity before restore (slow!). Similar to the \"check\" command."); /** Name. */ private final String name; diff --git a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java index a76fb684890..0e8ab25d3d2 100644 --- a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java +++ b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java @@ -3301,7 +3301,11 @@ public class GridCommandHandlerTest extends GridCommandHandlerClusterPerMethodAb assertContains(log, testOut.toString(), "Invalid argument: --sync."); assertEquals(EXIT_CODE_INVALID_ARGUMENTS, execute(h, "--snapshot", "restore", snpName, "blah")); - assertContains(log, testOut.toString(), "Invalid argument: blah. Possible options: --groups, --src, --increment, --sync."); + assertContains( + log, + testOut.toString(), + "Invalid argument: blah. Possible options: --groups, --src, --increment, --sync, --check." + ); assertEquals(EXIT_CODE_INVALID_ARGUMENTS, execute(h, "--snapshot", "restore", snpName, "--status", "--sync")); assertContains(log, testOut.toString(), "Invalid argument: --sync. Action \"--status\" does not support specified option."); @@ -3310,7 +3314,11 @@ public class GridCommandHandlerTest extends GridCommandHandlerClusterPerMethodAb assertContains(log, testOut.toString(), "Invalid argument: --start."); assertEquals(EXIT_CODE_INVALID_ARGUMENTS, execute(h, "--snapshot", "restore", snpName, "--start", "blah")); - assertContains(log, testOut.toString(), "Invalid argument: blah. Possible options: --groups, --src, --increment, --sync."); + assertContains( + log, + testOut.toString(), + "Invalid argument: blah. Possible options: --groups, --src, --increment, --sync, --check." + ); autoConfirmation = true; @@ -3351,7 +3359,7 @@ public class GridCommandHandlerTest extends GridCommandHandlerClusterPerMethodAb ig.cluster().state(ACTIVE); injectTestSystemOut(); - injectTestSystemIn(CONFIRM_MSG); + injectTestSystemIn(CONFIRM_MSG, CONFIRM_MSG); createCacheAndPreload(ig, cacheName1, keysCnt, 32, null); createCacheAndPreload(ig, cacheName2, keysCnt, 32, null); @@ -3377,7 +3385,7 @@ public class GridCommandHandlerTest extends GridCommandHandlerClusterPerMethodAb assertEquals(EXIT_CODE_INVALID_ARGUMENTS, execute(h, "--snapshot", "restore", snpName, cacheName1)); assertContains(log, testOut.toString(), - "Invalid argument: " + cacheName1 + ". Possible options: --groups, --src, --increment, --sync."); + "Invalid argument: " + cacheName1 + ". Possible options: --groups, --src, --increment, --sync, --check."); // Restore single cache group. assertEquals(EXIT_CODE_OK, execute(h, "--snapshot", "restore", snpName, "--groups", cacheName1)); @@ -3432,32 +3440,44 @@ public class GridCommandHandlerTest extends GridCommandHandlerClusterPerMethodAb awaitPartitionMapExchange(); - assertNull(ig.cache(cacheName1)); - assertNull(ig.cache(cacheName2)); - assertNull(ig.cache(cacheName3)); + for (boolean check: new boolean[] {false, true}) { + assertNull(ig.cache(cacheName1)); + assertNull(ig.cache(cacheName2)); + assertNull(ig.cache(cacheName3)); - // Restore all public cache groups. - assertEquals(EXIT_CODE_OK, execute(h, "--snapshot", "restore", snpName)); - String out = testOut.toString(); - assertContains(log, out, "Warning: command will restore ALL USER-CREATED CACHE GROUPS from the snapshot"); - assertContains(log, out, "Snapshot cache group restore operation started [name=" + snpName); + // Restore all public cache groups. + if (check) + assertEquals(EXIT_CODE_OK, execute(h, "--snapshot", "restore", snpName, "--check")); + else + assertEquals(EXIT_CODE_OK, execute(h, "--snapshot", "restore", snpName)); - waitForCondition(() -> ig.cache(cacheName1) != null, getTestTimeout()); - waitForCondition(() -> ig.cache(cacheName2) != null, getTestTimeout()); - waitForCondition(() -> ig.cache(cacheName3) != null, getTestTimeout()); + String out = testOut.toString(); + assertContains(log, out, "Warning: command will restore ALL USER-CREATED CACHE GROUPS from the snapshot"); + assertContains(log, out, "Snapshot cache group restore operation started [name=" + snpName); - cache1 = ig.cache(cacheName1); - cache2 = ig.cache(cacheName2); - cache3 = ig.cache(cacheName3); + waitForCondition(() -> ig.cache(cacheName1) != null, getTestTimeout()); + waitForCondition(() -> ig.cache(cacheName2) != null, getTestTimeout()); + waitForCondition(() -> ig.cache(cacheName3) != null, getTestTimeout()); - assertNotNull(cache1); - assertNotNull(cache2); - assertNotNull(cache3); + cache1 = ig.cache(cacheName1); + cache2 = ig.cache(cacheName2); + cache3 = ig.cache(cacheName3); - for (int i = 0; i < keysCnt; i++) { - assertEquals(cacheName1, Integer.valueOf(i), cache1.get(i)); - assertEquals(cacheName2, Integer.valueOf(i), cache2.get(i)); - assertEquals(cacheName3, Integer.valueOf(i), cache2.get(i)); + assertNotNull(cache1); + assertNotNull(cache2); + assertNotNull(cache3); + + for (int i = 0; i < keysCnt; i++) { + assertEquals(cacheName1, Integer.valueOf(i), cache1.get(i)); + assertEquals(cacheName2, Integer.valueOf(i), cache2.get(i)); + assertEquals(cacheName3, Integer.valueOf(i), cache2.get(i)); + } + + cache1.destroy(); + cache2.destroy(); + cache3.destroy(); + + awaitPartitionMapExchange(); } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/AbstractSnapshotVerificationTask.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/AbstractSnapshotVerificationTask.java index 8bfcab0c7d2..7be4333bc97 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/AbstractSnapshotVerificationTask.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/AbstractSnapshotVerificationTask.java @@ -81,8 +81,16 @@ public abstract class AbstractSnapshotVerificationTask extends if (meta == null) continue; - jobs.put(createJob(meta.snapshotName(), arg.snapshotPath(), meta.consistentId(), arg.cacheGroupNames()), - e.getKey()); + jobs.put( + createJob( + meta.snapshotName(), + arg.snapshotPath(), + meta.consistentId(), + arg.cacheGroupNames(), + arg.check() + ), + e.getKey() + ); if (allMetas.isEmpty()) break; @@ -126,7 +134,14 @@ public abstract class AbstractSnapshotVerificationTask extends * @param path Snapshot directory path. * @param constId Snapshot metadata file name. * @param groups Cache groups to be restored from the snapshot. May be empty if all cache groups are being restored. + * @param check If {@code true} check snapshot before restore. * @return Compute job. */ - protected abstract ComputeJob createJob(String name, @Nullable String path, String constId, Collection<String> groups); + protected abstract ComputeJob createJob( + String name, + @Nullable String path, + String constId, + Collection<String> groups, + boolean check + ); } 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 9cf0cab4a49..5c675e29be8 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 @@ -318,6 +318,9 @@ public class IgniteSnapshotManager extends GridCacheSharedManagerAdapter /** Default value of {@link IgniteSystemProperties#IGNITE_SNAPSHOT_SEQUENTIAL_WRITE}. */ public static final boolean DFLT_IGNITE_SNAPSHOT_SEQUENTIAL_WRITE = true; + /** Default value of check flag. */ + public static final boolean DFLT_CHECK_ON_RESTORE = false; + /** @deprecated Use #SNP_RUNNING_DIR_KEY instead. */ @Deprecated private static final String SNP_RUNNING_KEY = "snapshot-running"; @@ -1169,7 +1172,7 @@ public class IgniteSnapshotManager extends GridCacheSharedManagerAdapter ); SnapshotHandlerContext ctx = new SnapshotHandlerContext(meta, req.groups(), cctx.localNode(), snpDir, - req.streamerWarning()); + req.streamerWarning(), true); req.meta(meta); @@ -1772,7 +1775,7 @@ public class IgniteSnapshotManager extends GridCacheSharedManagerAdapter cctx.kernalContext().security().authorize(ADMIN_SNAPSHOT); - return checkSnapshot(name, snpPath, null, false, incIdx).chain(f -> { + return checkSnapshot(name, snpPath, null, false, incIdx, true).chain(f -> { try { return f.get(); } @@ -1793,6 +1796,7 @@ public class IgniteSnapshotManager extends GridCacheSharedManagerAdapter * @param includeCustomHandlers {@code True} to invoke all user-defined {@link SnapshotHandlerType#RESTORE} * handlers, otherwise only system consistency check will be performed. * @param incIdx Incremental snapshot index. + * @param check If {@code true} check snapshot integrity. * @return Future with the result of execution snapshot partitions verify task, which besides calculating partition * hashes of {@link IdleVerifyResultV2} also contains the snapshot metadata distribution across the cluster. */ @@ -1801,7 +1805,8 @@ public class IgniteSnapshotManager extends GridCacheSharedManagerAdapter @Nullable String snpPath, @Nullable Collection<String> grps, boolean includeCustomHandlers, - int incIdx + int incIdx, + boolean check ) { A.notNullOrEmpty(name, "Snapshot name cannot be null or empty."); A.ensure(U.alphanumericUnderscore(name), "Snapshot name must satisfy the following name pattern: a-zA-Z0-9_"); @@ -1901,7 +1906,7 @@ public class IgniteSnapshotManager extends GridCacheSharedManagerAdapter kctx0.task().execute( cls, - new SnapshotPartitionsVerifyTaskArg(grps, metas, snpPath), + new SnapshotPartitionsVerifyTaskArg(grps, metas, snpPath, check), options(new ArrayList<>(metas.keySet())) ).listen(f1 -> { if (f1.error() == null) @@ -2262,7 +2267,7 @@ public class IgniteSnapshotManager extends GridCacheSharedManagerAdapter /** {@inheritDoc} */ @Override public IgniteFuture<Void> restoreSnapshot(String name, @Nullable Collection<String> grpNames) { - return restoreSnapshot(name, null, grpNames, 0); + return restoreSnapshot(name, null, grpNames, 0, DFLT_CHECK_ON_RESTORE); } /** {@inheritDoc} */ @@ -2273,7 +2278,7 @@ public class IgniteSnapshotManager extends GridCacheSharedManagerAdapter ) { A.ensure(incIdx > 0, "Incremental snapshot index must be greater than 0."); - return restoreSnapshot(name, null, grpNames, incIdx); + return restoreSnapshot(name, null, grpNames, incIdx, DFLT_CHECK_ON_RESTORE); } /** @@ -2285,7 +2290,7 @@ public class IgniteSnapshotManager extends GridCacheSharedManagerAdapter * @return Future which will be completed when restore operation finished. */ public IgniteFutureImpl<Void> restoreSnapshot(String name, @Nullable String snpPath, @Nullable Collection<String> grpNames) { - return restoreSnapshot(name, snpPath, grpNames, 0); + return restoreSnapshot(name, snpPath, grpNames, 0, DFLT_CHECK_ON_RESTORE); } /** @@ -2295,13 +2300,15 @@ public class IgniteSnapshotManager extends GridCacheSharedManagerAdapter * @param snpPath Snapshot directory path. * @param grpNames Cache groups to be restored or {@code null} to restore all cache groups from the snapshot. * @param incIdx Index of incremental snapshot. + * @param check If {@code true} check snapshot before restore. * @return Future which will be completed when restore operation finished. */ public IgniteFutureImpl<Void> restoreSnapshot( String name, @Nullable String snpPath, @Nullable Collection<String> grpNames, - int incIdx + int incIdx, + boolean check ) { A.notNullOrEmpty(name, "Snapshot name cannot be null or empty."); A.ensure(U.alphanumericUnderscore(name), "Snapshot name must satisfy the following name pattern: a-zA-Z0-9_"); @@ -2309,7 +2316,7 @@ public class IgniteSnapshotManager extends GridCacheSharedManagerAdapter cctx.kernalContext().security().authorize(ADMIN_SNAPSHOT); - return restoreCacheGrpProc.start(name, snpPath, grpNames, incIdx); + return restoreCacheGrpProc.start(name, snpPath, grpNames, incIdx, check); } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotHandlerContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotHandlerContext.java index 091a4f3aa0c..ceceb3c785b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotHandlerContext.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotHandlerContext.java @@ -41,6 +41,9 @@ public class SnapshotHandlerContext { /** Warning flag of concurrent inconsistent-by-nature streamer updates. */ private final boolean streamerWrn; + /** If {@code true} check snapshot integrity. */ + private final boolean check; + /** * @param metadata Snapshot metadata. * @param grps The names of the cache groups on which the operation is performed. @@ -48,14 +51,22 @@ public class SnapshotHandlerContext { * @param locNode Local node. * @param snpDir The full path to the snapshot files. * @param streamerWrn {@code True} if concurrent streaming updates occurred during snapshot operation. + * @param check If {@code true} check snapshot integrity. */ - public SnapshotHandlerContext(SnapshotMetadata metadata, @Nullable Collection<String> grps, ClusterNode locNode, - File snpDir, boolean streamerWrn) { + public SnapshotHandlerContext( + SnapshotMetadata metadata, + @Nullable Collection<String> grps, + ClusterNode locNode, + File snpDir, + boolean streamerWrn, + boolean check + ) { this.metadata = metadata; this.grps = grps; this.locNode = locNode; this.snpDir = snpDir; this.streamerWrn = streamerWrn; + this.check = check; } /** @@ -93,4 +104,9 @@ public class SnapshotHandlerContext { public boolean streamerWarning() { return streamerWrn; } + + /** @return If {@code true} check snapshot integrity. */ + public boolean check() { + return check; + } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotHandlerRestoreTask.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotHandlerRestoreTask.java index 958dc9211fe..28154d8ff8c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotHandlerRestoreTask.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotHandlerRestoreTask.java @@ -53,9 +53,10 @@ public class SnapshotHandlerRestoreTask extends AbstractSnapshotVerificationTask String name, @Nullable String path, String constId, - Collection<String> groups + Collection<String> groups, + boolean check ) { - return new SnapshotHandlerRestoreJob(name, path, constId, groups); + return new SnapshotHandlerRestoreJob(name, path, constId, groups, check); } /** {@inheritDoc} */ @@ -122,17 +123,28 @@ public class SnapshotHandlerRestoreTask extends AbstractSnapshotVerificationTask /** Snapshot directory path. */ private final String snpPath; + /** If {@code true} check snapshot before restore. */ + private final boolean check; + /** * @param snpName Snapshot name. * @param snpPath Snapshot directory path. * @param consistentId String representation of the consistent node ID. * @param grps Cache group names. + * @param check If {@code true} check snapshot before restore. */ - public SnapshotHandlerRestoreJob(String snpName, @Nullable String snpPath, String consistentId, Collection<String> grps) { + public SnapshotHandlerRestoreJob( + String snpName, + @Nullable String snpPath, + String consistentId, + Collection<String> grps, + boolean check + ) { this.snpName = snpName; this.snpPath = snpPath; this.consistentId = consistentId; this.grps = grps; + this.check = check; } /** {@inheritDoc} */ @@ -143,7 +155,7 @@ public class SnapshotHandlerRestoreTask extends AbstractSnapshotVerificationTask SnapshotMetadata meta = snpMgr.readSnapshotMetadata(snpDir, consistentId); return snpMgr.handlers().invokeAll(SnapshotHandlerType.RESTORE, - new SnapshotHandlerContext(meta, grps, ignite.localNode(), snpDir, false)); + new SnapshotHandlerContext(meta, grps, ignite.localNode(), snpDir, false, check)); } catch (IgniteCheckedException | IOException e) { throw new IgniteException(e); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotMXBeanImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotMXBeanImpl.java index d1998ddb751..899ad04d51d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotMXBeanImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotMXBeanImpl.java @@ -29,6 +29,7 @@ import org.apache.ignite.lang.IgniteFuture; import org.apache.ignite.mxbean.SnapshotMXBean; import org.apache.ignite.spi.metric.IntMetric; +import static org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.DFLT_CHECK_ON_RESTORE; import static org.apache.ignite.internal.processors.cache.persistence.snapshot.SnapshotRestoreProcess.SNAPSHOT_RESTORE_METRICS; /** @@ -91,7 +92,13 @@ public class SnapshotMXBeanImpl implements SnapshotMXBean { Set<String> grpNamesSet = F.isEmpty(grpNames) ? null : Arrays.stream(grpNames.split(",")).map(String::trim).filter(s -> !s.isEmpty()).collect(Collectors.toSet()); - IgniteFuture<Void> fut = mgr.restoreSnapshot(name, F.isEmpty(path) ? null : path, grpNamesSet, incIdx); + IgniteFuture<Void> fut = mgr.restoreSnapshot( + name, + F.isEmpty(path) ? null : path, + grpNamesSet, + incIdx, + DFLT_CHECK_ON_RESTORE + ); if (fut.isDone()) fut.get(); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotPartitionsVerifyHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotPartitionsVerifyHandler.java index 90a7b71fe4e..9973c1e2426 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotPartitionsVerifyHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotPartitionsVerifyHandler.java @@ -148,6 +148,12 @@ public class SnapshotPartitionsVerifyHandler implements SnapshotHandler<Map<Part boolean punchHoleEnabled = isPunchHoleEnabled(opCtx, grpDirs.keySet()); + if (!opCtx.check()) { + log.info("Snapshot data integrity check skipped [snpName=" + meta.snapshotName() + ']'); + + return Collections.emptyMap(); + } + Map<PartitionKeyV2, PartitionHashRecordV2> res = new ConcurrentHashMap<>(); ThreadLocal<ByteBuffer> buff = ThreadLocal.withInitial(() -> ByteBuffer.allocateDirect(meta.pageSize()) .order(ByteOrder.nativeOrder())); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotPartitionsVerifyTask.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotPartitionsVerifyTask.java index 243ecca85a5..333f49a7b0e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotPartitionsVerifyTask.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotPartitionsVerifyTask.java @@ -52,8 +52,14 @@ public class SnapshotPartitionsVerifyTask extends AbstractSnapshotVerificationTa private static final long serialVersionUID = 0L; /** {@inheritDoc} */ - @Override protected ComputeJob createJob(String name, String path, String constId, Collection<String> groups) { - return new VisorVerifySnapshotPartitionsJob(name, path, constId, groups); + @Override protected ComputeJob createJob( + String name, + String path, + String constId, + Collection<String> groups, + boolean check + ) { + return new VisorVerifySnapshotPartitionsJob(name, path, constId, groups, check); } /** {@inheritDoc} */ @@ -86,22 +92,28 @@ public class SnapshotPartitionsVerifyTask extends AbstractSnapshotVerificationTa /** Set of cache groups to be checked in the snapshot or {@code empty} to check everything. */ private final Collection<String> rqGrps; + /** If {@code true} check snapshot before restore. */ + private final boolean check; + /** * @param snpName Snapshot name to validate. * @param consId Consistent snapshot metadata file name. * @param rqGrps Set of cache groups to be checked in the snapshot or {@code empty} to check everything. * @param snpPath Snapshot directory path. + * @param check If {@code true} check snapshot before restore. */ public VisorVerifySnapshotPartitionsJob( String snpName, @Nullable String snpPath, String consId, - Collection<String> rqGrps + Collection<String> rqGrps, + boolean check ) { this.snpName = snpName; this.consId = consId; this.rqGrps = rqGrps; this.snpPath = snpPath; + this.check = check; } /** {@inheritDoc} */ @@ -118,7 +130,7 @@ public class SnapshotPartitionsVerifyTask extends AbstractSnapshotVerificationTa SnapshotMetadata meta = cctx.snapshotMgr().readSnapshotMetadata(snpDir, consId); return new SnapshotPartitionsVerifyHandler(cctx) - .invoke(new SnapshotHandlerContext(meta, rqGrps, ignite.localNode(), snpDir, false)); + .invoke(new SnapshotHandlerContext(meta, rqGrps, ignite.localNode(), snpDir, false, check)); } catch (IgniteCheckedException | IOException e) { throw new IgniteException(e); @@ -136,12 +148,13 @@ public class SnapshotPartitionsVerifyTask extends AbstractSnapshotVerificationTa VisorVerifySnapshotPartitionsJob job = (VisorVerifySnapshotPartitionsJob)o; return snpName.equals(job.snpName) && consId.equals(job.consId) && - Objects.equals(rqGrps, job.rqGrps) && Objects.equals(snpPath, job.snpPath); + Objects.equals(rqGrps, job.rqGrps) && Objects.equals(snpPath, job.snpPath) && + Objects.equals(check, job.check); } /** {@inheritDoc} */ @Override public int hashCode() { - return Objects.hash(snpName, consId, rqGrps, snpPath); + return Objects.hash(snpName, consId, rqGrps, snpPath, check); } } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotPartitionsVerifyTaskArg.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotPartitionsVerifyTaskArg.java index bcf6343a2a5..74d9f769910 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotPartitionsVerifyTaskArg.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotPartitionsVerifyTaskArg.java @@ -44,6 +44,9 @@ public class SnapshotPartitionsVerifyTaskArg extends VisorDataTransferObject { /** Snapshot directory path. */ private String snpPath; + /** If {@code true} check snapshot integrity. */ + private boolean check; + /** Default constructor. */ public SnapshotPartitionsVerifyTaskArg() { // No-op. @@ -53,15 +56,18 @@ public class SnapshotPartitionsVerifyTaskArg extends VisorDataTransferObject { * @param grpNames Cache group names to be verified. * @param clusterMetas The map of distribution of snapshot metadata pieces across the cluster. * @param snpPath Snapshot directory path. + * @param check If {@code true} check snapshot integrity. */ public SnapshotPartitionsVerifyTaskArg( Collection<String> grpNames, Map<ClusterNode, List<SnapshotMetadata>> clusterMetas, - @Nullable String snpPath + @Nullable String snpPath, + boolean check ) { this.grpNames = grpNames; this.clusterMetas = clusterMetas; this.snpPath = snpPath; + this.check = check; } /** @@ -85,11 +91,17 @@ public class SnapshotPartitionsVerifyTaskArg extends VisorDataTransferObject { return snpPath; } + /** @return If {@code true} check snapshot integrity. */ + public boolean check() { + return check; + } + /** {@inheritDoc} */ @Override protected void writeExternalData(ObjectOutput out) throws IOException { U.writeCollection(out, grpNames); U.writeMap(out, clusterMetas); U.writeString(out, snpPath); + out.writeBoolean(check); } /** {@inheritDoc} */ @@ -97,6 +109,7 @@ public class SnapshotPartitionsVerifyTaskArg extends VisorDataTransferObject { grpNames = U.readCollection(in); clusterMetas = U.readMap(in); snpPath = U.readString(in); + check = in.readBoolean(); } /** {@inheritDoc} */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotPartitionsVerifyTaskResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotPartitionsVerifyTaskResult.java index 31d9b15b99a..902a3ae5e35 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotPartitionsVerifyTaskResult.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotPartitionsVerifyTaskResult.java @@ -32,6 +32,7 @@ import org.apache.ignite.internal.processors.cache.verify.IdleVerifyResultV2; import org.apache.ignite.internal.util.GridStringBuilder; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.U; +import org.jetbrains.annotations.Nullable; /** * The result of execution snapshot partitions verify task which besides calculating partition hashes of @@ -45,7 +46,7 @@ public class SnapshotPartitionsVerifyTaskResult extends IgniteDataTransferObject private Map<ClusterNode, List<SnapshotMetadata>> metas; /** Result of cluster nodes partitions comparison. */ - private IdleVerifyResultV2 idleRes; + @Nullable private IdleVerifyResultV2 idleRes; /** Default constructor. */ public SnapshotPartitionsVerifyTaskResult() { @@ -58,7 +59,7 @@ public class SnapshotPartitionsVerifyTaskResult extends IgniteDataTransferObject */ public SnapshotPartitionsVerifyTaskResult( Map<ClusterNode, List<SnapshotMetadata>> metas, - IdleVerifyResultV2 idleRes + @Nullable IdleVerifyResultV2 idleRes ) { this.metas = metas; this.idleRes = idleRes; @@ -77,10 +78,12 @@ public class SnapshotPartitionsVerifyTaskResult extends IgniteDataTransferObject * @param printer Consumer for handle formatted result. */ public void print(Consumer<String> printer) { - idleRes.print(printer, true); + if (idleRes != null) { + idleRes.print(printer, true); - if (!F.isEmpty(idleVerifyResult().exceptions())) - return; + if (!F.isEmpty(idleRes.exceptions())) + return; + } Collection<String> wrns = F.flatCollections(F.viewReadOnly( F.flatCollections(metas.values()).stream().distinct().collect(Collectors.toList()), diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotRestoreProcess.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotRestoreProcess.java index 715663d354a..2abd6f65a97 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotRestoreProcess.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotRestoreProcess.java @@ -258,9 +258,16 @@ public class SnapshotRestoreProcess { * @param snpPath Snapshot directory path. * @param cacheGrpNames Cache groups to be restored or {@code null} to restore all cache groups from the snapshot. * @param incIdx Index of incremental snapshot. + * @param check If {@code true} check snapshot before restore. * @return Future that will be completed when the restore operation is complete and the cache groups are started. */ - public IgniteFutureImpl<Void> start(String snpName, @Nullable String snpPath, @Nullable Collection<String> cacheGrpNames, int incIdx) { + public IgniteFutureImpl<Void> start( + String snpName, + @Nullable String snpPath, + @Nullable Collection<String> cacheGrpNames, + int incIdx, + boolean check + ) { IgniteSnapshotManager snpMgr = ctx.cache().context().snapshotMgr(); ClusterSnapshotFuture fut0; @@ -326,7 +333,7 @@ public class SnapshotRestoreProcess { snpMgr.recordSnapshotEvent(snpName, msg, EventType.EVT_CLUSTER_SNAPSHOT_RESTORE_STARTED); - snpMgr.checkSnapshot(snpName, snpPath, cacheGrpNames, true, incIdx).listen(f -> { + snpMgr.checkSnapshot(snpName, snpPath, cacheGrpNames, true, incIdx, check).listen(f -> { if (f.error() != null) { finishProcess(fut0.rqId, f.error()); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotRestoreTask.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotRestoreTask.java index fad625cf3fb..a1d99b30eff 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotRestoreTask.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotRestoreTask.java @@ -67,8 +67,13 @@ public class VisorSnapshotRestoreTask extends VisorSnapshotOneNodeTask<VisorSnap /** {@inheritDoc} */ @Override protected String run(VisorSnapshotRestoreTaskArg arg) throws IgniteException { - IgniteFutureImpl<Void> fut = ignite.context().cache().context().snapshotMgr() - .restoreSnapshot(arg.snapshotName(), arg.snapshotPath(), arg.groupNames(), arg.incrementIndex()); + IgniteFutureImpl<Void> fut = ignite.context().cache().context().snapshotMgr().restoreSnapshot( + arg.snapshotName(), + arg.snapshotPath(), + arg.groupNames(), + arg.incrementIndex(), + arg.check() + ); IgniteSnapshotManager.ClusterSnapshotFuture snpFut = fut.internalFuture() instanceof IgniteSnapshotManager.ClusterSnapshotFuture ? diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotRestoreTaskArg.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotRestoreTaskArg.java index 07c18fe59c0..d08d304873b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotRestoreTaskArg.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotRestoreTaskArg.java @@ -41,6 +41,9 @@ public class VisorSnapshotRestoreTaskArg extends VisorSnapshotCreateTaskArg { /** Incremental snapshot index. */ private int incIdx; + /** If {@code true} check snapshot before restore. */ + private boolean check; + /** Default constructor. */ public VisorSnapshotRestoreTaskArg() { // No-op. @@ -53,6 +56,7 @@ public class VisorSnapshotRestoreTaskArg extends VisorSnapshotCreateTaskArg { * @param sync Synchronous execution flag. * @param action Snapshot restore operation management action. * @param grpNames Cache group names. + * @param check If {@code true} check snapshot before restore. */ public VisorSnapshotRestoreTaskArg( String snpName, @@ -60,13 +64,15 @@ public class VisorSnapshotRestoreTaskArg extends VisorSnapshotCreateTaskArg { @Nullable Integer incIdx, boolean sync, VisorSnapshotRestoreTaskAction action, - @Nullable Collection<String> grpNames + @Nullable Collection<String> grpNames, + boolean check ) { super(snpName, snpPath, sync, false); this.action = action; this.grpNames = grpNames; this.incIdx = incIdx == null ? 0 : incIdx; + this.check = check; } /** @return Cache group names. */ @@ -84,12 +90,18 @@ public class VisorSnapshotRestoreTaskArg extends VisorSnapshotCreateTaskArg { return incIdx; } + /** @return If {@code true} check snapshot before restore. */ + public boolean check() { + return check; + } + /** {@inheritDoc} */ @Override protected void writeExternalData(ObjectOutput out) throws IOException { super.writeExternalData(out); U.writeEnum(out, action); U.writeCollection(out, grpNames); out.writeInt(incIdx); + out.writeBoolean(check); } /** {@inheritDoc} */ @@ -98,6 +110,7 @@ public class VisorSnapshotRestoreTaskArg extends VisorSnapshotCreateTaskArg { action = U.readEnum(in, VisorSnapshotRestoreTaskAction.class); grpNames = U.readCollection(in); incIdx = in.readInt(); + check = in.readBoolean(); } /** {@inheritDoc} */ diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotCheckTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotCheckTest.java index c9832ae4ecc..398c150bf92 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotCheckTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotCheckTest.java @@ -365,7 +365,11 @@ public class IgniteClusterSnapshotCheckTest extends AbstractSnapshotSelfTest { corruptPartitionFile(ignite, SNAPSHOT_NAME, dfltCacheCfg, PART_ID); - IdleVerifyResultV2 res = snp(ignite).checkSnapshot(SNAPSHOT_NAME, null).get().idleVerifyResult(); + IdleVerifyResultV2 res = snp(ignite).checkSnapshot(SNAPSHOT_NAME, null, null, false, -1, false).get().idleVerifyResult(); + + assertEquals("Check must be disabled", 0, res.exceptions().size()); + + res = snp(ignite).checkSnapshot(SNAPSHOT_NAME, null, null, false, -1, true).get().idleVerifyResult(); StringBuilder b = new StringBuilder(); res.print(b::append, true); @@ -498,11 +502,19 @@ public class IgniteClusterSnapshotCheckTest extends AbstractSnapshotSelfTest { CacheFilterEnum.USER, true)); - IdleVerifyResultV2 snpVerifyRes = ignite.compute().execute(new TestSnapshotPartitionsVerifyTask(), - new SnapshotPartitionsVerifyTaskArg(new HashSet<>(), Collections.singletonMap(ignite.cluster().localNode(), - Collections.singletonList(snp(ignite).readSnapshotMetadata(snp(ignite).snapshotLocalDir(SNAPSHOT_NAME), - (String)ignite.configuration().getConsistentId()))), null)) - .idleVerifyResult(); + IdleVerifyResultV2 snpVerifyRes = ignite.compute().execute( + new TestSnapshotPartitionsVerifyTask(), + new SnapshotPartitionsVerifyTaskArg( + new HashSet<>(), + Collections.singletonMap(ignite.cluster().localNode(), + Collections.singletonList(snp(ignite).readSnapshotMetadata( + snp(ignite).snapshotLocalDir(SNAPSHOT_NAME), + (String)ignite.configuration().getConsistentId() + ))), + null, + true + ) + ).idleVerifyResult(); Map<PartitionKeyV2, List<PartitionHashRecordV2>> idleVerifyHashes = jobResults.get(TestVisorBackupPartitionsTask.class); Map<PartitionKeyV2, List<PartitionHashRecordV2>> snpCheckHashes = jobResults.get(TestVisorBackupPartitionsTask.class); @@ -622,7 +634,7 @@ public class IgniteClusterSnapshotCheckTest extends AbstractSnapshotSelfTest { corruptPartitionFile(ignite, SNAPSHOT_NAME, ccfg1, PART_ID); - return snp(ignite).checkSnapshot(SNAPSHOT_NAME, null, cachesToCheck, false, 0).get(TIMEOUT); + return snp(ignite).checkSnapshot(SNAPSHOT_NAME, null, cachesToCheck, false, 0, true).get(TIMEOUT); } /** diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/incremental/IncrementalSnapshotCheckBeforeRestoreTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/incremental/IncrementalSnapshotCheckBeforeRestoreTest.java index 3211fea31e1..bc35aed2012 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/incremental/IncrementalSnapshotCheckBeforeRestoreTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/incremental/IncrementalSnapshotCheckBeforeRestoreTest.java @@ -36,6 +36,7 @@ import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.testframework.GridTestUtils; import org.junit.Test; +import static org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.DFLT_CHECK_ON_RESTORE; import static org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.snapshotMetaFileName; import static org.junit.Assume.assumeFalse; @@ -96,7 +97,7 @@ public class IncrementalSnapshotCheckBeforeRestoreTest extends AbstractSnapshotS for (IgniteEx n: F.asList(grid(0), grid(GRID_CNT))) { for (int i = 0; i <= incSnpCnt; i++) { - SnapshotPartitionsVerifyTaskResult res = snp(n).checkSnapshot(SNP, null, null, false, i) + SnapshotPartitionsVerifyTaskResult res = snp(n).checkSnapshot(SNP, null, null, false, i, DFLT_CHECK_ON_RESTORE) .get(getTestTimeout()); assertTrue(res.exceptions().isEmpty()); @@ -113,7 +114,7 @@ public class IncrementalSnapshotCheckBeforeRestoreTest extends AbstractSnapshotS for (IgniteEx n : F.asList(grid(0), grid(GRID_CNT))) { GridTestUtils.assertThrows( log, - () -> snp(n).checkSnapshot(SNP, null, null, false, 1).get(getTestTimeout()), + () -> snp(n).checkSnapshot(SNP, null, null, false, 1, DFLT_CHECK_ON_RESTORE).get(getTestTimeout()), IgniteCheckedException.class, "No incremental snapshot found"); } @@ -121,7 +122,7 @@ public class IncrementalSnapshotCheckBeforeRestoreTest extends AbstractSnapshotS createIncrementalSnapshots(1); for (IgniteEx n : F.asList(grid(0), grid(GRID_CNT))) { - SnapshotPartitionsVerifyTaskResult res = snp(n).checkSnapshot(SNP, null, null, false, 1) + SnapshotPartitionsVerifyTaskResult res = snp(n).checkSnapshot(SNP, null, null, false, 1, DFLT_CHECK_ON_RESTORE) .get(getTestTimeout()); assertTrue(res.exceptions().isEmpty()); @@ -142,7 +143,7 @@ public class IncrementalSnapshotCheckBeforeRestoreTest extends AbstractSnapshotS for (IgniteEx n : F.asList(srv, grid(GRID_CNT))) { GridTestUtils.assertThrows( log, - () -> snp(n).checkSnapshot(SNP, null, null, false, 1).get(getTestTimeout()), + () -> snp(n).checkSnapshot(SNP, null, null, false, 1, DFLT_CHECK_ON_RESTORE).get(getTestTimeout()), IgniteCheckedException.class, "Failed to find snapshot metafile"); } @@ -157,7 +158,7 @@ public class IncrementalSnapshotCheckBeforeRestoreTest extends AbstractSnapshotS U.delete(snp(srv).incrementalSnapshotLocalDir(SNP, null, 1)); for (IgniteEx n : F.asList(srv, grid(GRID_CNT))) { - SnapshotPartitionsVerifyTaskResult res = snp(n).checkSnapshot(SNP, null, null, false, 0) + SnapshotPartitionsVerifyTaskResult res = snp(n).checkSnapshot(SNP, null, null, false, 0, DFLT_CHECK_ON_RESTORE) .get(getTestTimeout()); assertTrue(res.exceptions().isEmpty()); @@ -168,7 +169,7 @@ public class IncrementalSnapshotCheckBeforeRestoreTest extends AbstractSnapshotS GridTestUtils.assertThrows( log, - () -> snp(n).checkSnapshot(SNP, null, null, false, inc).get(getTestTimeout()), + () -> snp(n).checkSnapshot(SNP, null, null, false, inc, DFLT_CHECK_ON_RESTORE).get(getTestTimeout()), IgniteCheckedException.class, "No incremental snapshot found"); } @@ -184,7 +185,7 @@ public class IncrementalSnapshotCheckBeforeRestoreTest extends AbstractSnapshotS deleteWalSegment(0); for (IgniteEx n : F.asList(srv, grid(GRID_CNT))) { - SnapshotPartitionsVerifyTaskResult res = snp(n).checkSnapshot(SNP, null, null, false, 0) + SnapshotPartitionsVerifyTaskResult res = snp(n).checkSnapshot(SNP, null, null, false, 0, DFLT_CHECK_ON_RESTORE) .get(getTestTimeout()); assertTrue(res.exceptions().isEmpty()); @@ -195,7 +196,7 @@ public class IncrementalSnapshotCheckBeforeRestoreTest extends AbstractSnapshotS GridTestUtils.assertThrows( log, - () -> snp(n).checkSnapshot(SNP, null, null, false, inc).get(getTestTimeout()), + () -> snp(n).checkSnapshot(SNP, null, null, false, inc, DFLT_CHECK_ON_RESTORE).get(getTestTimeout()), IgniteCheckedException.class, "No WAL segments found for incremental snapshot"); } @@ -212,7 +213,7 @@ public class IncrementalSnapshotCheckBeforeRestoreTest extends AbstractSnapshotS GridTestUtils.assertThrows( log, - () -> snp(srv).checkSnapshot(SNP, null, null, false, 1).get(getTestTimeout()), + () -> snp(srv).checkSnapshot(SNP, null, null, false, 1, DFLT_CHECK_ON_RESTORE).get(getTestTimeout()), IgniteCheckedException.class, "Missed WAL segment"); } @@ -227,7 +228,7 @@ public class IncrementalSnapshotCheckBeforeRestoreTest extends AbstractSnapshotS GridTestUtils.assertThrows( log, - () -> snp(srv).checkSnapshot(SNP, null, null, false, 1).get(getTestTimeout()), + () -> snp(srv).checkSnapshot(SNP, null, null, false, 1, DFLT_CHECK_ON_RESTORE).get(getTestTimeout()), IgniteCheckedException.class, "Missed WAL segment"); } @@ -247,7 +248,7 @@ public class IncrementalSnapshotCheckBeforeRestoreTest extends AbstractSnapshotS GridTestUtils.assertThrows( log, - () -> snp(srv).checkSnapshot(SNP, null, null, false, 1).get(getTestTimeout()), + () -> snp(srv).checkSnapshot(SNP, null, null, false, 1, DFLT_CHECK_ON_RESTORE).get(getTestTimeout()), IgniteCheckedException.class, "Missed WAL segments"); } @@ -277,7 +278,7 @@ public class IncrementalSnapshotCheckBeforeRestoreTest extends AbstractSnapshotS for (IgniteEx n : F.asList(srv, grid(GRID_CNT))) { GridTestUtils.assertThrows( log, - () -> snp(n).checkSnapshot(SNP, null, null, false, 1).get(getTestTimeout()), + () -> snp(n).checkSnapshot(SNP, null, null, false, 1, DFLT_CHECK_ON_RESTORE).get(getTestTimeout()), IgniteCheckedException.class, "Incremental snapshot doesn't match full snapshot"); } @@ -308,7 +309,7 @@ public class IncrementalSnapshotCheckBeforeRestoreTest extends AbstractSnapshotS for (IgniteEx n : F.asList(srv, grid(GRID_CNT))) { GridTestUtils.assertThrows( log, - () -> snp(n).checkSnapshot(SNP, null, null, false, 1).get(getTestTimeout()), + () -> snp(n).checkSnapshot(SNP, null, null, false, 1, DFLT_CHECK_ON_RESTORE).get(getTestTimeout()), IgniteCheckedException.class, "Incremental snapshot meta has wrong index"); } diff --git a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output index 43e32619693..ef8ff50fb03 100644 --- a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output +++ b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output @@ -170,7 +170,7 @@ This utility can do the following commands: --src path - Path to the directory where the snapshot files are located. If not specified, the default configured snapshot directory will be used. Restore snapshot: - control.(sh|bat) --snapshot restore snapshot_name [--increment incrementIndex] [--groups group1,...groupN] [--src path] [--sync] + control.(sh|bat) --snapshot restore snapshot_name [--increment incrementIndex] [--groups group1,...groupN] [--src path] [--sync] [--check] Parameters: snapshot_name - Snapshot name. In case incremental snapshot (--incremental) full snapshot name must be provided. @@ -178,6 +178,7 @@ This utility can do the following commands: --src path - Path to the directory where the snapshot files are located. If not specified, the default configured snapshot directory will be used. --increment incrementIndex - Incremental snapshot index. The command will restore snapshot and after that all its increments sequentially from 1 to the specified index. --sync - Run the operation synchronously, the command will wait for the entire operation to complete. Otherwise, it will be performed in the background, and the command will immediately return control. + --check - Check snapshot data integrity before restore (slow!). Similar to the "check" command. Snapshot restore operation status (Command deprecated. Use '--snapshot status' instead): control.(sh|bat) --snapshot restore snapshot_name --status diff --git a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output index 43e32619693..ef8ff50fb03 100644 --- a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output +++ b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output @@ -170,7 +170,7 @@ This utility can do the following commands: --src path - Path to the directory where the snapshot files are located. If not specified, the default configured snapshot directory will be used. Restore snapshot: - control.(sh|bat) --snapshot restore snapshot_name [--increment incrementIndex] [--groups group1,...groupN] [--src path] [--sync] + control.(sh|bat) --snapshot restore snapshot_name [--increment incrementIndex] [--groups group1,...groupN] [--src path] [--sync] [--check] Parameters: snapshot_name - Snapshot name. In case incremental snapshot (--incremental) full snapshot name must be provided. @@ -178,6 +178,7 @@ This utility can do the following commands: --src path - Path to the directory where the snapshot files are located. If not specified, the default configured snapshot directory will be used. --increment incrementIndex - Incremental snapshot index. The command will restore snapshot and after that all its increments sequentially from 1 to the specified index. --sync - Run the operation synchronously, the command will wait for the entire operation to complete. Otherwise, it will be performed in the background, and the command will immediately return control. + --check - Check snapshot data integrity before restore (slow!). Similar to the "check" command. Snapshot restore operation status (Command deprecated. Use '--snapshot status' instead): control.(sh|bat) --snapshot restore snapshot_name --status