This is an automated email from the ASF dual-hosted git repository.
timoninmaxim 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 370693a0c0e IGNITE-22182 : Move snapshop metadata validation to
SnapshotMetadataVerificationTask (#11346)
370693a0c0e is described below
commit 370693a0c0e02d1b8f8c144cc8d2e1c7b3721fc1
Author: Vladimir Steshin <[email protected]>
AuthorDate: Wed May 29 14:14:18 2024 +0300
IGNITE-22182 : Move snapshop metadata validation to
SnapshotMetadataVerificationTask (#11346)
---
.../snapshot/SnapshotCompressionBasicTest.java | 11 ++-
...CommandHandlerCheckIncrementalSnapshotTest.java | 4 +-
.../apache/ignite/util/GridCommandHandlerTest.java | 6 +-
.../snapshot/AbstractSnapshotVerificationTask.java | 32 -------
.../snapshot/IgniteSnapshotManager.java | 81 ++--------------
.../snapshot/SnapshotMetadataVerificationTask.java | 103 +++++++++++++++++++--
.../SnapshotMetadataVerificationTaskArg.java | 23 ++++-
.../snapshot/SnapshotPartitionsVerifyHandler.java | 17 +---
.../snapshot/SnapshotRestoreProcess.java | 34 +------
.../cache/persistence/snapshot/dump/Dump.java | 2 +-
.../snapshot/EncryptedSnapshotTest.java | 36 +++----
.../snapshot/IgniteClusterSnapshotCheckTest.java | 14 +--
.../snapshot/dump/IgniteCacheDumpSelf2Test.java | 7 +-
.../IncrementalSnapshotCheckBeforeRestoreTest.java | 24 +++--
.../IncrementalSnapshotRestoreTest.java | 10 +-
15 files changed, 189 insertions(+), 215 deletions(-)
diff --git
a/modules/compress/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotCompressionBasicTest.java
b/modules/compress/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotCompressionBasicTest.java
index 9820303e51a..08a4acbb1cd 100644
---
a/modules/compress/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotCompressionBasicTest.java
+++
b/modules/compress/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotCompressionBasicTest.java
@@ -217,9 +217,14 @@ public class SnapshotCompressionBasicTest extends
AbstractSnapshotSelfTest {
G.allGrids().forEach(this::failCompressionProcessor);
- for (String snpName: Arrays.asList(SNAPSHOT_WITH_HOLES,
SNAPSHOT_WITHOUT_HOLES)) {
- GridTestUtils.assertThrows(log, () ->
ignite.snapshot().restoreSnapshot(snpName, null).get(TIMEOUT),
- IgniteException.class, "Snapshot contains compressed cache
groups");
+ for (String snpName : Arrays.asList(SNAPSHOT_WITH_HOLES,
SNAPSHOT_WITHOUT_HOLES)) {
+ GridTestUtils.assertThrowsAnyCause(
+ log,
+ () -> ignite.snapshot().restoreSnapshot(snpName,
null).get(TIMEOUT),
+ IllegalStateException.class,
+ "from snapshot '" + snpName + "' are compressed while disk
page compression is disabled. To check " +
+ "these groups please start Ignite with ignite-compress"
+ );
}
}
diff --git
a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerCheckIncrementalSnapshotTest.java
b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerCheckIncrementalSnapshotTest.java
index 6fe71e0fc46..cbee596138c 100644
---
a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerCheckIncrementalSnapshotTest.java
+++
b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerCheckIncrementalSnapshotTest.java
@@ -54,7 +54,6 @@ import org.junit.runners.Parameterized;
import static org.apache.ignite.cluster.ClusterState.ACTIVE;
import static
org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_INVALID_ARGUMENTS;
import static
org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_OK;
-import static
org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_UNEXPECTED_ERROR;
import static org.apache.ignite.testframework.GridTestUtils.assertContains;
import static org.apache.ignite.testframework.GridTestUtils.assertNotContains;
import static
org.apache.ignite.testframework.GridTestUtils.runMultiThreadedAsync;
@@ -183,7 +182,8 @@ public class GridCommandHandlerCheckIncrementalSnapshotTest
extends GridCommandH
assertContains(log, testOut.toString(), "--increment argument
specified twice");
// Non existent increment.
- assertEquals(EXIT_CODE_UNEXPECTED_ERROR, execute(cmd, "--snapshot",
"check", SNP, "--increment", "2"));
+ assertEquals(EXIT_CODE_INVALID_ARGUMENTS, execute(cmd, "--snapshot",
"check", SNP, "--increment", "2"));
+ assertContains(log, testOut.toString(), "No incremental snapshot found
[snpName=" + SNP);
autoConfirmation = true;
}
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 75342041ff6..e6129be3662 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
@@ -3582,7 +3582,8 @@ public class GridCommandHandlerTest extends
GridCommandHandlerClusterPerMethodAb
assertContains(log, testOut.toString(), "--increment argument
specified twice");
// Non existent increment.
- assertEquals(EXIT_CODE_UNEXPECTED_ERROR, execute("--snapshot",
"restore", snpName, "--increment", "2", "--sync"));
+ assertEquals(EXIT_CODE_INVALID_ARGUMENTS, execute("--snapshot",
"restore", snpName, "--increment", "2", "--sync"));
+ assertContains(log, testOut.toString(), "No incremental snapshot
found [snpName=" + snpName);
}
finally {
autoConfirmation = autoConfirmation0;
@@ -3647,8 +3648,7 @@ public class GridCommandHandlerTest extends
GridCommandHandlerClusterPerMethodAb
execute("--snapshot", "restore", snpName, "--src", "A",
"--src", "B"));
assertContains(log, testOut.toString(), "--src argument specified
twice");
- // The check command simply prints the results of the check, it
always ends with a zero exit code.
- assertEquals(EXIT_CODE_OK, execute("--snapshot", "check",
snpName));
+ assertEquals(EXIT_CODE_INVALID_ARGUMENTS, execute("--snapshot",
"check", snpName));
assertContains(log, testOut.toString(), "Snapshot does not exists
[snapshot=" + snpName);
assertEquals(EXIT_CODE_OK, execute("--snapshot", "check", snpName,
"--src", snpDir.getAbsolutePath()));
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 6e1159c4b8f..cff0b0e110d 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
@@ -23,7 +23,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteException;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.compute.ComputeJob;
@@ -64,14 +63,6 @@ public abstract class AbstractSnapshotVerificationTask
extends
Map<ComputeJob, ClusterNode> jobs = new HashMap<>();
Set<SnapshotMetadata> allMetas = new HashSet<>();
clusterMetas.values().forEach(allMetas::addAll);
-
- try {
- checkMissedMetadata(allMetas);
- }
- catch (IgniteCheckedException e) {
- throw new
IgniteSnapshotVerifyException(F.asMap(ignite.localNode(), new
IgniteException(e.getMessage())));
- }
-
metas.putAll(clusterMetas);
while (!allMetas.isEmpty()) {
@@ -107,29 +98,6 @@ public abstract class AbstractSnapshotVerificationTask
extends
return ComputeJobResultPolicy.WAIT;
}
- /**
- * Ensures that all parts of the snapshot are available according to the
metadata.
- *
- * @param clusterMetas List of snapshot metadata found in the cluster.
- * @throws IgniteCheckedException If some metadata is missing.
- */
- public static void checkMissedMetadata(Collection<SnapshotMetadata>
clusterMetas) throws IgniteCheckedException {
- Set<String> missed = null;
-
- for (SnapshotMetadata meta : clusterMetas) {
- if (missed == null)
- missed = new HashSet<>(meta.baselineNodes());
-
- missed.remove(meta.consistentId());
-
- if (missed.isEmpty())
- break;
- }
-
- if (!missed.isEmpty())
- throw new IgniteCheckedException("Some metadata is missing from
the snapshot: " + missed);
- }
-
/**
* @param name Snapshot name.
* @param path Snapshot directory path.
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 30b54fb3180..3b5f294bb06 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
@@ -1903,86 +1903,19 @@ public class IgniteSnapshotManager extends
GridCacheSharedManagerAdapter
Collection<ClusterNode> bltNodes =
F.view(cctx.discovery().serverNodes(AffinityTopologyVersion.NONE),
(node) -> CU.baselineNode(node, kctx0.state().clusterState()));
- SnapshotMetadataVerificationTaskArg taskArg = new
SnapshotMetadataVerificationTaskArg(name, snpPath, incIdx);
+ Collection<Integer> grpIds = grps == null ? Collections.emptySet() :
F.viewReadOnly(grps, CU::cacheId);
+
+ SnapshotMetadataVerificationTaskArg taskArg = new
SnapshotMetadataVerificationTaskArg(name, snpPath, incIdx, grpIds);
kctx0.task().execute(
SnapshotMetadataVerificationTask.class,
taskArg,
options(bltNodes)
).listen(f0 -> {
- if (f0.error() == null && F.isEmpty(f0.result().exceptions())) {
- Map<ClusterNode, List<SnapshotMetadata>> metas =
f0.result().meta();
-
- Map<Integer, String> grpIds = grps == null ?
Collections.emptyMap() :
- grps.stream().collect(Collectors.toMap(CU::cacheId, v ->
v));
-
- byte[] masterKeyDigest =
kctx0.config().getEncryptionSpi().masterKeyDigest();
-
- for (List<SnapshotMetadata> nodeMetas : metas.values()) {
- for (SnapshotMetadata meta : nodeMetas) {
- byte[] snpMasterKeyDigest = meta.masterKeyDigest();
-
- if (masterKeyDigest == null && snpMasterKeyDigest !=
null) {
- res.onDone(new
SnapshotPartitionsVerifyTaskResult(metas, new IdleVerifyResultV2(
- Collections.singletonMap(cctx.localNode(), new
IllegalArgumentException("Snapshot '" +
- meta.snapshotName() + "' has encrypted
caches while encryption is disabled. To " +
- "restore this snapshot, start Ignite with
configured encryption and the same " +
- "master key.")))));
-
- return;
- }
-
- if (snpMasterKeyDigest != null &&
!Arrays.equals(snpMasterKeyDigest, masterKeyDigest)) {
- res.onDone(new
SnapshotPartitionsVerifyTaskResult(metas, new IdleVerifyResultV2(
- Collections.singletonMap(cctx.localNode(), new
IllegalArgumentException("Snapshot '" +
- meta.snapshotName() + "' has different
master key digest. To restore this " +
- "snapshot, start Ignite with the same
master key.")))));
-
- return;
- }
-
- if (meta.hasCompressedGroups() &&
grpIds.keySet().stream().anyMatch(meta::isGroupWithCompression)) {
- try {
-
kctx0.compress().checkPageCompressionSupported();
- }
- catch (IgniteCheckedException e) {
- String grpWithCompr =
grpIds.entrySet().stream()
- .filter(grp ->
meta.isGroupWithCompression(grp.getKey()))
-
.map(Map.Entry::getValue).collect(Collectors.joining(", "));
-
- String msg = "Requested cache groups [" +
grpWithCompr + "] for check " +
- "from snapshot '" + meta.snapshotName() +
"' are compressed while " +
- "disk page compression is disabled. To
check these groups please " +
- "start Ignite with ignite-compress module
in classpath";
-
- res.onDone(new
SnapshotPartitionsVerifyTaskResult(metas, new IdleVerifyResultV2(
- Collections.singletonMap(cctx.localNode(),
new IllegalArgumentException(msg)))));
+ SnapshotMetadataVerificationTaskResult metasRes = f0.result();
- return;
- }
- }
-
- grpIds.keySet().removeAll(meta.partitions().keySet());
- }
- }
-
- if (!grpIds.isEmpty()) {
- res.onDone(new SnapshotPartitionsVerifyTaskResult(metas,
- new
IdleVerifyResultV2(Collections.singletonMap(cctx.localNode(),
- new IllegalArgumentException("Cache group(s) was
not " +
- "found in the snapshot [groups=" +
grpIds.values() + ", snapshot=" + name + ']')))));
-
- return;
- }
-
- if (metas.isEmpty()) {
- res.onDone(new SnapshotPartitionsVerifyTaskResult(metas,
- new
IdleVerifyResultV2(Collections.singletonMap(cctx.localNode(),
- new IllegalArgumentException("Snapshot does not
exists [snapshot=" + name +
- (snpPath != null ? ", baseDir=" + snpPath :
"") + ']')))));
-
- return;
- }
+ if (f0.error() == null && F.isEmpty(metasRes.exceptions())) {
+ Map<ClusterNode, List<SnapshotMetadata>> metas =
metasRes.meta();
Class<? extends AbstractSnapshotVerificationTask> cls;
@@ -2007,7 +1940,7 @@ public class IgniteSnapshotManager extends
GridCacheSharedManagerAdapter
}
else {
if (f0.error() == null)
- res.onDone(new
IgniteSnapshotVerifyException(f0.result().exceptions()));
+ res.onDone(new
IgniteSnapshotVerifyException(metasRes.exceptions()));
else if (f0.error() instanceof IgniteSnapshotVerifyException)
res.onDone(new SnapshotPartitionsVerifyTaskResult(null,
new
IdleVerifyResultV2(((IgniteSnapshotVerifyException)f0.error()).exceptions())));
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotMetadataVerificationTask.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotMetadataVerificationTask.java
index 1695ad692ef..c1e38b8c7b8 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotMetadataVerificationTask.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotMetadataVerificationTask.java
@@ -20,9 +20,14 @@ package
org.apache.ignite.internal.processors.cache.persistence.snapshot;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.stream.Collectors;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteException;
@@ -38,11 +43,11 @@ import
org.apache.ignite.internal.processors.cache.persistence.wal.FileDescripto
import
org.apache.ignite.internal.processors.cache.persistence.wal.FileWriteAheadLogManager;
import
org.apache.ignite.internal.processors.cache.persistence.wal.reader.IgniteWalIteratorFactory;
import org.apache.ignite.internal.processors.task.GridInternal;
+import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.resources.IgniteInstanceResource;
import org.apache.ignite.resources.LoggerResource;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import static
org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.incrementalSnapshotWalsDir;
@@ -53,11 +58,20 @@ public class SnapshotMetadataVerificationTask
/** Serial version uid. */
private static final long serialVersionUID = 0L;
+ /** */
+ private SnapshotMetadataVerificationTaskArg arg;
+
+ /** */
+ @IgniteInstanceResource
+ private transient IgniteEx ignite;
+
/** {@inheritDoc} */
@Override public @NotNull Map<? extends ComputeJob, ClusterNode> map(
List<ClusterNode> subgrid,
SnapshotMetadataVerificationTaskArg arg
) throws IgniteException {
+ this.arg = arg;
+
Map<ComputeJob, ClusterNode> map = U.newHashMap(subgrid.size());
for (ClusterNode node : subgrid)
@@ -88,19 +102,24 @@ public class SnapshotMetadataVerificationTask
}
/** {@inheritDoc} */
- @Override public List<SnapshotMetadata> execute() throws
IgniteException {
+ @Override public List<SnapshotMetadata> execute() {
IgniteSnapshotManager snpMgr =
ignite.context().cache().context().snapshotMgr();
List<SnapshotMetadata> snpMeta =
snpMgr.readSnapshotMetadatas(arg.snapshotName(), arg.snapshotPath());
+ for (SnapshotMetadata meta : snpMeta)
+ checkMeta(meta);
+
if (arg.incrementIndex() > 0) {
List<SnapshotMetadata> metas = snpMeta.stream()
.filter(m ->
m.consistentId().equals(ignite.localNode().consistentId()))
.collect(Collectors.toList());
if (metas.size() != 1) {
- throw new IgniteException("Failed to find snapshot
metafile [metas=" + metas +
- ", snpName=" + arg.snapshotName() + ", snpPath=" +
arg.snapshotPath() + ']');
+ throw new IgniteException("Failed to find single snapshot
metafile on local node [locNodeId="
+ + ignite.localNode().consistentId() + ", metas=" +
snpMeta + ", snpName=" + arg.snapshotName()
+ + ", snpPath=" + arg.snapshotPath() + "]. Incremental
snapshots requires exactly one meta file " +
+ "per node because they don't support restoring on a
different topology.");
}
checkIncrementalSnapshots(metas.get(0), arg);
@@ -109,6 +128,49 @@ public class SnapshotMetadataVerificationTask
return snpMeta;
}
+ /** */
+ private void checkMeta(SnapshotMetadata meta) {
+ byte[] snpMasterKeyDigest = meta.masterKeyDigest();
+ byte[] masterKeyDigest =
ignite.context().config().getEncryptionSpi().masterKeyDigest();
+
+ if (masterKeyDigest == null && snpMasterKeyDigest != null) {
+ throw new IllegalStateException("Snapshot '" +
meta.snapshotName() + "' has encrypted caches " +
+ "while encryption is disabled. To restore this snapshot,
start Ignite with configured " +
+ "encryption and the same master key.");
+ }
+
+ if (snpMasterKeyDigest != null &&
!Arrays.equals(snpMasterKeyDigest, masterKeyDigest)) {
+ throw new IllegalStateException("Snapshot '" +
meta.snapshotName() + "' has different master " +
+ "key digest. To restore this snapshot, start Ignite with
the same master key.");
+ }
+
+ Collection<Integer> grpIds = new HashSet<>(F.isEmpty(arg.grpIds())
? meta.cacheGroupIds() : arg.grpIds());
+
+ if (meta.hasCompressedGroups() &&
grpIds.stream().anyMatch(meta::isGroupWithCompression)) {
+ try {
+
ignite.context().compress().checkPageCompressionSupported();
+ }
+ catch (NullPointerException | IgniteCheckedException e) {
+ String grpWithCompr =
grpIds.stream().filter(meta::isGroupWithCompression)
+ .map(String::valueOf).collect(Collectors.joining(",
"));
+
+ String msg = "Requested cache groups [" + grpWithCompr +
"] for check " +
+ "from snapshot '" + meta.snapshotName() + "' are
compressed while " +
+ "disk page compression is disabled. To check these
groups please " +
+ "start Ignite with ignite-compress module in
classpath";
+
+ throw new IllegalStateException(msg);
+ }
+ }
+
+ grpIds.removeAll(meta.partitions().keySet());
+
+ if (!grpIds.isEmpty() && !new
HashSet<>(meta.cacheGroupIds()).containsAll(grpIds)) {
+ throw new IllegalArgumentException("Cache group(s) was not
found in the snapshot [groups=" + grpIds +
+ ", snapshot=" + arg.snapshotName() + ']');
+ }
+ }
+
/** Checks that all incremental snapshots are present, contain correct
metafile and WAL segments. */
public void checkIncrementalSnapshots(SnapshotMetadata fullMeta,
SnapshotMetadataVerificationTaskArg arg) {
try {
@@ -121,7 +183,7 @@ public class SnapshotMetadataVerificationTask
File incSnpDir =
snpMgr.incrementalSnapshotLocalDir(arg.snapshotName(), arg.snapshotPath(), inc);
if (!incSnpDir.exists()) {
- throw new IgniteException("No incremental snapshot
found " +
+ throw new IllegalArgumentException("No incremental
snapshot found " +
"[snpName=" + arg.snapshotName() + ", snpPath=" +
arg.snapshotPath() + ", incrementIndex=" + inc + ']');
}
@@ -132,7 +194,7 @@ public class SnapshotMetadataVerificationTask
IncrementalSnapshotMetadata incMeta =
snpMgr.readFromFile(metafile);
if (!incMeta.matchBaseSnapshot(fullMeta)) {
- throw new IgniteException("Incremental snapshot
doesn't match full snapshot " +
+ throw new IllegalArgumentException("Incremental
snapshot doesn't match full snapshot " +
"[incMeta=" + incMeta + ", fullMeta=" + fullMeta +
']');
}
@@ -187,13 +249,14 @@ public class SnapshotMetadataVerificationTask
}
/** {@inheritDoc} */
- @Override public @Nullable SnapshotMetadataVerificationTaskResult
reduce(List<ComputeJobResult> results) throws IgniteException {
+ @Override public SnapshotMetadataVerificationTaskResult
reduce(List<ComputeJobResult> results) throws IgniteException {
Map<ClusterNode, List<SnapshotMetadata>> reduceRes = new HashMap<>();
Map<ClusterNode, Exception> exs = new HashMap<>();
SnapshotMetadata first = null;
+ Set<String> baselineMetasLeft = Collections.emptySet();
- for (ComputeJobResult res: results) {
+ for (ComputeJobResult res : results) {
if (res.getException() != null) {
exs.put(res.getNode(), res.getException());
@@ -203,9 +266,14 @@ public class SnapshotMetadataVerificationTask
List<SnapshotMetadata> metas = res.getData();
for (SnapshotMetadata meta : metas) {
- if (first == null)
+ if (first == null) {
first = meta;
+ baselineMetasLeft = new HashSet<>(meta.baselineNodes());
+ }
+
+ baselineMetasLeft.remove(meta.consistentId());
+
if (!first.sameSnapshot(meta)) {
exs.put(res.getNode(),
new IgniteException("An error occurred during
comparing snapshot metadata from cluster nodes " +
@@ -219,6 +287,23 @@ public class SnapshotMetadataVerificationTask
}
}
+ if (first == null && exs.isEmpty()) {
+ assert !results.isEmpty();
+
+ for (ComputeJobResult res : results) {
+ Exception e = new IllegalArgumentException("Snapshot does not
exists [snapshot=" + arg.snapshotName()
+ + (arg.snapshotPath() != null ? ", baseDir=" +
arg.snapshotPath() : "") + ", consistentId="
+ + res.getNode().consistentId() + ']');
+
+ exs.put(res.getNode(), e);
+ }
+ }
+
+ if (!F.isEmpty(baselineMetasLeft) && F.isEmpty(exs)) {
+ exs.put(ignite.localNode(), new IgniteException("No snapshot
metadatas found for the baseline nodes " +
+ "with consistent ids: " + String.join(", ",
baselineMetasLeft)));
+ }
+
return new SnapshotMetadataVerificationTaskResult(reduceRes, exs);
}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotMetadataVerificationTaskArg.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotMetadataVerificationTaskArg.java
index 9fa3d55a51f..6bc69b2c7d3 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotMetadataVerificationTaskArg.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotMetadataVerificationTaskArg.java
@@ -19,6 +19,7 @@ package
org.apache.ignite.internal.processors.cache.persistence.snapshot;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
+import java.util.Collection;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.internal.visor.VisorDataTransferObject;
@@ -40,6 +41,9 @@ public class SnapshotMetadataVerificationTaskArg extends
VisorDataTransferObject
/** Incremental snapshot index. */
private int incIdx;
+ /** Cache group ids. */
+ @Nullable private Collection<Integer> grpIds;
+
/** Default constructor. */
public SnapshotMetadataVerificationTaskArg() {
// No-op.
@@ -49,10 +53,16 @@ public class SnapshotMetadataVerificationTaskArg extends
VisorDataTransferObject
* @param snpName Snapshot name.
* @param snpPath Snapshot directory path.
*/
- public SnapshotMetadataVerificationTaskArg(String snpName, @Nullable
String snpPath, int incIdx) {
+ public SnapshotMetadataVerificationTaskArg(String snpName, @Nullable
String snpPath, int incIdx, Collection<Integer> grpIds) {
this.snpName = snpName;
this.snpPath = snpPath;
this.incIdx = incIdx;
+ this.grpIds = grpIds;
+ }
+
+ /** {@inheritDoc} */
+ @Override public byte getProtocolVersion() {
+ return V2;
}
/**
@@ -76,11 +86,19 @@ public class SnapshotMetadataVerificationTaskArg extends
VisorDataTransferObject
return incIdx;
}
+ /**
+ * @return Cache group ids.
+ */
+ @Nullable public Collection<Integer> grpIds() {
+ return grpIds;
+ }
+
/** {@inheritDoc} */
@Override protected void writeExternalData(ObjectOutput out) throws
IOException {
U.writeString(out, snpName);
U.writeString(out, snpPath);
out.writeInt(incIdx);
+ U.writeCollection(out, grpIds);
}
/** {@inheritDoc} */
@@ -88,6 +106,9 @@ public class SnapshotMetadataVerificationTaskArg extends
VisorDataTransferObject
snpName = U.readString(in);
snpPath = U.readString(in);
incIdx = in.readInt();
+
+ if (protoVer > V1)
+ grpIds = U.readCollection(in);
}
/** {@inheritDoc} */
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 d54a1a06d0b..8f569b66f09 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
@@ -171,16 +171,15 @@ public class SnapshotPartitionsVerifyHandler implements
SnapshotHandler<Map<Part
", meta=" + meta + ']');
}
- // This will throw if compression disabled. Calculation before other
checks.
- boolean punchHoleEnabled = isPunchHoleEnabled(opCtx, grpDirs.keySet());
-
if (!opCtx.check()) {
log.info("Snapshot data integrity check skipped [snpName=" +
meta.snapshotName() + ']');
return Collections.emptyMap();
}
- return meta.dump() ? checkDumpFiles(opCtx, partFiles) :
checkSnapshotFiles(opCtx, grpDirs, meta, partFiles, punchHoleEnabled);
+ return meta.dump()
+ ? checkDumpFiles(opCtx, partFiles)
+ : checkSnapshotFiles(opCtx, grpDirs, meta, partFiles,
isPunchHoleEnabled(opCtx, grpDirs.keySet()));
}
/** */
@@ -477,16 +476,6 @@ public class SnapshotPartitionsVerifyHandler implements
SnapshotHandler<Map<Part
Path snapshotDir = opCtx.snapshotDirectory().toPath();
if (meta.hasCompressedGroups() &&
grpIds.stream().anyMatch(meta::isGroupWithCompression)) {
- try {
-
cctx.kernalContext().compress().checkPageCompressionSupported();
- }
- catch (IgniteCheckedException e) {
- throw new IgniteException("Snapshot contains compressed cache
groups " +
- "[grps=[" +
grpIds.stream().filter(meta::isGroupWithCompression).collect(Collectors.toList())
+
- "], snpName=" + meta.snapshotName() + "], but compression
module is not enabled. " +
- "Make sure that ignite-compress module is in classpath.");
- }
-
try {
cctx.kernalContext().compress().checkPageCompressionSupported(snapshotDir,
meta.pageSize());
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 d1a1ac35868..70ab72f39bd 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
@@ -402,12 +402,8 @@ public class SnapshotRestoreProcess {
return;
}
- if (!reqGrpIds.isEmpty()) {
- finishProcess(fut0.rqId, new
IllegalArgumentException(OP_REJECT_MSG + "Cache group(s) was not " +
- "found in the snapshot [groups=" + reqGrpIds.values() + ",
snapshot=" + snpName + ']'));
-
- return;
- }
+ assert reqGrpIds.isEmpty() : "Cache group(s) was not found in the
snapshot [groups=" + reqGrpIds.values()
+ + ", snapshot=" + snpName + ']';
Collection<UUID> bltNodes =
F.viewReadOnly(ctx.discovery().discoCache().aliveBaselineNodes(), F.node2id());
@@ -778,7 +774,6 @@ public class SnapshotRestoreProcess {
// Collect the cache configurations and prepare a temporary directory
for copying files.
// Metastorage can be restored only manually by directly copying files.
- boolean skipCompressCheck = false;
for (SnapshotMetadata meta : metas) {
for (File snpCacheDir :
cctx.snapshotMgr().snapshotCacheDirectories(req.snapshotName(),
req.snapshotPath(), meta.folderName(),
name -> !METASTORAGE_CACHE_NAME.equals(name))) {
@@ -787,29 +782,6 @@ public class SnapshotRestoreProcess {
if (!F.isEmpty(req.groups()) &&
!req.groups().contains(grpName))
continue;
- if (!skipCompressCheck &&
meta.isGroupWithCompression(CU.cacheId(grpName))) {
- try {
- File path =
ctx.pdsFolderResolver().resolveFolders().persistentStoreRootPath();
-
-
ctx.compress().checkPageCompressionSupported(path.toPath(), meta.pageSize());
- }
- catch (Exception e) {
- String grpWithCompr = F.isEmpty(req.groups()) ? ""
- : req.groups().stream().filter(s ->
meta.isGroupWithCompression(CU.cacheId(grpName)))
- .collect(Collectors.joining(", "));
-
- String msg = "Requested cache groups [" + grpWithCompr
+ "] for restore " +
- "from snapshot '" + meta.snapshotName() + "' are
compressed while " +
- "disk page compression is disabled. To restore
these groups please " +
- "start Ignite with configured disk page
compression";
-
- throw new IgniteCheckedException(msg);
- }
- finally {
- skipCompressCheck = true;
- }
- }
-
File cacheDir =
pageStore.cacheWorkDir(snpCacheDir.getName().startsWith(CACHE_GRP_DIR_PREFIX),
grpName);
if (cacheDir.exists()) {
@@ -972,8 +944,6 @@ public class SnapshotRestoreProcess {
Set<SnapshotMetadata> allMetas =
opCtx0.metasPerNode.values().stream().flatMap(List::stream).collect(Collectors.toSet());
- AbstractSnapshotVerificationTask.checkMissedMetadata(allMetas);
-
IgniteSnapshotManager snpMgr = ctx.cache().context().snapshotMgr();
synchronized (this) {
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/dump/Dump.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/dump/Dump.java
index f0e64a88e2a..c26c56f88b1 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/dump/Dump.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/dump/Dump.java
@@ -287,7 +287,7 @@ public class Dump implements AutoCloseable {
boolean encrypted = meta.encryptionKey() != null;
if (encrypted && !Arrays.equals(meta.masterKeyDigest(),
encSpi.masterKeyDigest())) {
- throw new IllegalArgumentException("Dump '" +
+ throw new IllegalStateException("Dump '" +
meta.snapshotName() + "' has different master key digest. To
restore this " +
"dump, provide the same master key.");
}
diff --git
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/EncryptedSnapshotTest.java
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/EncryptedSnapshotTest.java
index a3913b600d7..53faea615ca 100644
---
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/EncryptedSnapshotTest.java
+++
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/EncryptedSnapshotTest.java
@@ -29,7 +29,6 @@ import org.apache.ignite.cluster.ClusterState;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.internal.IgniteEx;
import org.apache.ignite.internal.encryption.AbstractEncryptionTest;
-import org.apache.ignite.internal.management.cache.IdleVerifyResultV2;
import org.apache.ignite.internal.util.distributed.FullMessage;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.G;
@@ -144,8 +143,8 @@ public class EncryptedSnapshotTest extends
AbstractSnapshotSelfTest {
GridTestUtils.assertThrowsAnyCause(
log,
() -> snp(ig1).restoreSnapshot(SNAPSHOT_NAME,
Collections.singletonList(dfltCacheCfg.getName())).get(TIMEOUT),
- IgniteCheckedException.class,
- "different master key digest"
+ IllegalStateException.class,
+ "Snapshot '" + SNAPSHOT_NAME + "' has different master key digest."
);
}
@@ -200,16 +199,14 @@ public class EncryptedSnapshotTest extends
AbstractSnapshotSelfTest {
masterKeyName = AbstractEncryptionTest.MASTER_KEY_NAME_2;
- ig = startGrids(2);
-
- IdleVerifyResultV2 snpCheckRes = snp(ig).checkSnapshot(SNAPSHOT_NAME,
null).get().idleVerifyResult();
+ IgniteEx ig2 = startGrids(2);
- for (Exception e : snpCheckRes.exceptions().values()) {
- if (e.getMessage().contains("different master key digest"))
- return;
- }
-
- throw new IllegalStateException("Snapshot validation must contain
error due to different master key.");
+ GridTestUtils.assertThrowsAnyCause(
+ log,
+ () -> snp(ig2).checkSnapshot(SNAPSHOT_NAME,
null).get().idleVerifyResult(),
+ IllegalStateException.class,
+ "Snapshot '" + SNAPSHOT_NAME + "' has different master key digest."
+ );
}
/** @throws Exception If fails. */
@@ -244,15 +241,12 @@ public class EncryptedSnapshotTest extends
AbstractSnapshotSelfTest {
ig.cluster().state(ACTIVE);
- IdleVerifyResultV2 snpCheckRes =
snp(ig).checkSnapshot(SNAPSHOT_NAME, null).get().idleVerifyResult();
-
- for (Exception e : snpCheckRes.exceptions().values()) {
- if (e.getMessage().contains("has encrypted caches while
encryption is disabled"))
- return;
- }
-
- throw new IllegalStateException("Snapshot validation must contain
error due to encryption is currently " +
- "disabled.");
+ GridTestUtils.assertThrowsAnyCause(
+ log,
+ () -> snp(ig).checkSnapshot(SNAPSHOT_NAME,
null).get().idleVerifyResult(),
+ IllegalStateException.class,
+ "has encrypted caches while encryption is disabled"
+ );
}
finally {
if (tmpSnpDir != null)
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 eaa1e0795bc..c2472141e82 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
@@ -97,6 +97,7 @@ import static
org.apache.ignite.internal.processors.cache.persistence.snapshot.I
import static org.apache.ignite.internal.processors.dr.GridDrType.DR_NONE;
import static org.apache.ignite.testframework.GridTestUtils.assertContains;
import static org.apache.ignite.testframework.GridTestUtils.assertNotContains;
+import static
org.apache.ignite.testframework.GridTestUtils.assertThrowsAnyCause;
import static org.apache.ignite.testframework.GridTestUtils.waitForCondition;
/**
@@ -198,13 +199,12 @@ public class IgniteClusterSnapshotCheckTest extends
AbstractSnapshotSelfTest {
assertTrue(smfs[0].toString(), smfs[0].exists());
assertTrue(U.delete(smfs[0]));
- IdleVerifyResultV2 res = snp(ignite).checkSnapshot(SNAPSHOT_NAME,
null).get().idleVerifyResult();
-
- StringBuilder b = new StringBuilder();
- res.print(b::append, true);
-
- assertFalse(F.isEmpty(res.exceptions()));
- assertContains(log, b.toString(), "Some metadata is missing from the
snapshot");
+ assertThrowsAnyCause(
+ log,
+ () -> snp(ignite).checkSnapshot(SNAPSHOT_NAME,
null).get().idleVerifyResult(),
+ IgniteException.class,
+ "No snapshot metadatas found for the baseline nodes with
consistent ids: "
+ );
}
/** @throws Exception If fails. */
diff --git
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/dump/IgniteCacheDumpSelf2Test.java
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/dump/IgniteCacheDumpSelf2Test.java
index 158f4369a5f..81dbd9a87cf 100644
---
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/dump/IgniteCacheDumpSelf2Test.java
+++
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/dump/IgniteCacheDumpSelf2Test.java
@@ -135,6 +135,7 @@ import static
org.apache.ignite.internal.processors.cache.persistence.snapshot.d
import static
org.apache.ignite.internal.processors.cache.persistence.snapshot.dump.DumpEntrySerializer.HEADER_SZ;
import static org.apache.ignite.testframework.GridTestUtils.assertContains;
import static org.apache.ignite.testframework.GridTestUtils.assertThrows;
+import static
org.apache.ignite.testframework.GridTestUtils.assertThrowsAnyCause;
import static org.apache.ignite.testframework.GridTestUtils.waitForCondition;
/** */
@@ -945,7 +946,7 @@ public class IgniteCacheDumpSelf2Test extends
GridCommonAbstractTest {
log
).run(), IgniteException.class, "Encryption SPI required to read
encrypted dump");
- assertThrows(
+ assertThrowsAnyCause(
null,
() -> {
EncryptionSpi encSpi = encryptionSpi();
@@ -973,8 +974,10 @@ public class IgniteCacheDumpSelf2Test extends
GridCommonAbstractTest {
),
log
).run();
+
+ return null;
},
- IgniteException.class,
+ IllegalStateException.class,
"Dump '" + DMP_NAME + "' has different master key digest"
);
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 1ebae1956e9..6ebc4b64610 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
@@ -112,11 +112,12 @@ public class IncrementalSnapshotCheckBeforeRestoreTest
extends AbstractSnapshotS
createFullSnapshot();
for (IgniteEx n : F.asList(grid(0), grid(GRID_CNT))) {
- GridTestUtils.assertThrows(
+ GridTestUtils.assertThrowsAnyCause(
log,
() -> snp(n).checkSnapshot(SNP, null, null, false, 1,
DFLT_CHECK_ON_RESTORE).get(getTestTimeout()),
- IgniteCheckedException.class,
- "No incremental snapshot found");
+ IllegalArgumentException.class,
+ "No incremental snapshot found"
+ );
}
createIncrementalSnapshots(1);
@@ -145,7 +146,8 @@ public class IncrementalSnapshotCheckBeforeRestoreTest
extends AbstractSnapshotS
log,
() -> snp(n).checkSnapshot(SNP, null, null, false, 1,
DFLT_CHECK_ON_RESTORE).get(getTestTimeout()),
IgniteCheckedException.class,
- "Failed to find snapshot metafile");
+ "Failed to find single snapshot metafile on local node
[locNodeId=" + srv.localNode().consistentId()
+ );
}
}
@@ -167,11 +169,12 @@ public class IncrementalSnapshotCheckBeforeRestoreTest
extends AbstractSnapshotS
for (int i = 1; i <= 2; i++) {
final int inc = i;
- GridTestUtils.assertThrows(
+ GridTestUtils.assertThrowsAnyCause(
log,
() -> snp(n).checkSnapshot(SNP, null, null, false, inc,
DFLT_CHECK_ON_RESTORE).get(getTestTimeout()),
- IgniteCheckedException.class,
- "No incremental snapshot found");
+ IllegalArgumentException.class,
+ "No incremental snapshot found"
+ );
}
}
}
@@ -276,11 +279,12 @@ public class IncrementalSnapshotCheckBeforeRestoreTest
extends AbstractSnapshotS
meta.incrementalSnapshotPointer()), incMetaFile);
for (IgniteEx n : F.asList(srv, grid(GRID_CNT))) {
- GridTestUtils.assertThrows(
+ GridTestUtils.assertThrowsAnyCause(
log,
() -> snp(n).checkSnapshot(SNP, null, null, false, 1,
DFLT_CHECK_ON_RESTORE).get(getTestTimeout()),
- IgniteCheckedException.class,
- "Incremental snapshot doesn't match full snapshot");
+ IllegalArgumentException.class,
+ "Incremental snapshot doesn't match full snapshot"
+ );
}
}
diff --git
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/incremental/IncrementalSnapshotRestoreTest.java
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/incremental/IncrementalSnapshotRestoreTest.java
index d1ac0e93b5a..ac58c9cba57 100644
---
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/incremental/IncrementalSnapshotRestoreTest.java
+++
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/incremental/IncrementalSnapshotRestoreTest.java
@@ -352,10 +352,12 @@ public class IncrementalSnapshotRestoreTest extends
AbstractIncrementalSnapshotT
restartWithCleanPersistence();
- GridTestUtils.assertThrowsAnyCause(log, () ->
- grid(0).snapshot().restoreSnapshot(SNP, null,
2).get(getTestTimeout()),
- IgniteSnapshotVerifyException.class,
- "No incremental snapshot found");
+ GridTestUtils.assertThrowsAnyCause(
+ log,
+ () -> grid(0).snapshot().restoreSnapshot(SNP, null,
2).get(getTestTimeout()),
+ IllegalArgumentException.class,
+ "No incremental snapshot found"
+ );
}
/** */