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 38176e7ea2d IGNITE-18999 Only primary snapshot mode (#10603)
38176e7ea2d is described below

commit 38176e7ea2db6b22f074edd3054b211ef83e1ac5
Author: Nikolay <[email protected]>
AuthorDate: Fri Mar 31 11:38:42 2023 +0300

    IGNITE-18999 Only primary snapshot mode (#10603)
---
 .../snapshot/SnapshotCompressionBasicTest.java     |  19 ++-
 .../snapshot/SnapshotCreateCommand.java            |   2 +-
 .../snapshot/IgniteSnapshotManager.java            |  58 +++++--
 .../persistence/snapshot/SnapshotMXBeanImpl.java   |   9 +-
 .../persistence/snapshot/SnapshotMetadata.java     |  23 ++-
 .../snapshot/SnapshotOperationRequest.java         |  13 +-
 .../snapshot/SnapshotRestoreProcess.java           |  37 ++++-
 .../visor/snapshot/VisorSnapshotCreateTask.java    |   3 +-
 .../visor/snapshot/VisorSnapshotCreateTaskArg.java |  13 +-
 .../snapshot/VisorSnapshotRestoreTaskArg.java      |   2 +-
 .../snapshot/AbstractSnapshotSelfTest.java         | 181 ++++++++++++++++++++-
 .../snapshot/EncryptedSnapshotTest.java            |  31 ++--
 .../snapshot/IgniteClusterSnapshotCheckTest.java   |  33 ++--
 .../snapshot/IgniteClusterSnapshotDeltaTest.java   |  26 ++-
 .../snapshot/IgniteClusterSnapshotHandlerTest.java |  18 +-
 .../IgniteClusterSnapshotRestoreSelfTest.java      |  18 +-
 .../snapshot/IgniteClusterSnapshotSelfTest.java    | 107 ++++++------
 .../IgniteClusterSnapshotStreamerTest.java         |  23 ++-
 .../IgniteClusterSnapshotWalRecordTest.java        |   4 +-
 .../snapshot/IgniteSnapshotConsistencyTest.java    |  17 +-
 .../snapshot/IgniteSnapshotMXBeanTest.java         |   6 +-
 .../snapshot/IgniteSnapshotManagerSelfTest.java    |  20 ++-
 .../snapshot/IgniteSnapshotRemoteRequestTest.java  |  12 +-
 .../IgniteSnapshotRestoreFromRemoteTest.java       |   2 +-
 .../IgniteSnapshotWithMetastorageTest.java         |   6 +-
 .../snapshot/IncrementalSnapshotTest.java          |  27 +--
 .../persistence/snapshot/PlainSnapshotTest.java    |  14 +-
 .../IncrementalSnapshotCheckBeforeRestoreTest.java |   4 +-
 .../testframework/junits/GridAbstractTest.java     |   8 +-
 .../IgniteClusterSnapshotCheckWithIndexesTest.java |   6 +-
 .../snapshot/IgniteClusterSnapshotMetricsTest.java |  12 +-
 ...niteClusterSnapshotRestoreWithIndexingTest.java |  17 +-
 .../IgniteClusterSnapshotWithIndexesTest.java      |   9 +-
 33 files changed, 574 insertions(+), 206 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 4d3ca153935..d895b430b94 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
@@ -23,11 +23,13 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.StandardOpenOption;
+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.Objects;
 import java.util.Set;
@@ -82,7 +84,7 @@ public class SnapshotCompressionBasicTest extends 
AbstractSnapshotSelfTest {
     protected static final String SNAPSHOT_WITH_HOLES = 
"testSnapshotWithHoles";
 
     /** */
-    protected static final long TIMEOUT = 30_000;
+    protected static final long TIMEOUT = 120_000;
 
     /** */
     protected static final Map<String, String> CACHES = new HashMap<>();
@@ -106,10 +108,15 @@ public class SnapshotCompressionBasicTest extends 
AbstractSnapshotSelfTest {
         COMPRESSED_CACHES.add("cache3");
     }
 
-    /** */
-    @Parameterized.Parameters(name = "Encryption={0}")
-    public static Collection<Boolean> encryptionParams() {
-        return Collections.singletonList(false);
+    /** Parameters. */
+    @Parameterized.Parameters(name = "encryption={0}, onlyPrimay={1}")
+    public static Collection<Object[]> params() {
+        List<Object[]> res = new ArrayList<>();
+
+        for (boolean onlyPrimary: new boolean[] {true, false})
+            res.add(new Object[] { false, onlyPrimary});
+
+        return res;
     }
 
     /** {@inheritDoc} */
@@ -322,7 +329,7 @@ public class SnapshotCompressionBasicTest extends 
AbstractSnapshotSelfTest {
         G.allGrids().forEach(i -> failCompressionProcessor(i, 
SNAPSHOT_WITHOUT_HOLES));
 
         for (String snpName : Arrays.asList(SNAPSHOT_WITH_HOLES, 
SNAPSHOT_WITHOUT_HOLES)) {
-            ignite.snapshot().createSnapshot(snpName).get(TIMEOUT);
+            snp(ignite).createSnapshot(snpName, null, false, 
onlyPrimary).get(TIMEOUT);
 
             IdleVerifyResultV2 res = 
ignite.context().cache().context().snapshotMgr().checkSnapshot(snpName, null)
                 .get().idleVerifyResult();
diff --git 
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/snapshot/SnapshotCreateCommand.java
 
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/snapshot/SnapshotCreateCommand.java
index f0773be9306..663e54fc954 100644
--- 
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/snapshot/SnapshotCreateCommand.java
+++ 
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/snapshot/SnapshotCreateCommand.java
@@ -82,7 +82,7 @@ public class SnapshotCreateCommand extends SnapshotSubcommand 
{
             }
         }
 
-        cmdArg = new VisorSnapshotCreateTaskArg(snpName, snpPath, sync, 
incremental);
+        cmdArg = new VisorSnapshotCreateTaskArg(snpName, snpPath, sync, 
incremental, false);
     }
 
     /** {@inheritDoc} */
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 5c675e29be8..a87b84dab8e 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
@@ -1122,7 +1122,23 @@ public class IgniteSnapshotManager extends 
GridCacheSharedManagerAdapter
             if (cctx.cache().cacheGroup(grpId) == null)
                 continue;
 
-            parts.put(grpId, null);
+            CacheGroupContext grpCtx = cctx.cache().cacheGroup(grpId);
+
+            AffinityTopologyVersion topVer = grpCtx.affinity().lastVersion();
+
+            if (req.onlyPrimary()) {
+                Set<Integer> include = new 
HashSet<>(grpCtx.affinity().primaryPartitions(cctx.localNodeId(), topVer));
+
+                include.remove(INDEX_PARTITION);
+
+                if (log.isInfoEnabled())
+                    log.info("Snapshot only primary partitions " +
+                        "[grpId=" + grpId + ", grpName=" + 
grpCtx.cacheOrGroupName() + ", parts=" + include + ']');
+
+                parts.put(grpId, include);
+            }
+            else
+                parts.put(grpId, null);
         }
 
         IgniteInternalFuture<?> task0;
@@ -1168,7 +1184,8 @@ public class IgniteSnapshotManager extends 
GridCacheSharedManagerAdapter
                     blts,
                     res.parts(),
                     res.snapshotPointer(),
-                    cctx.gridConfig().getEncryptionSpi().masterKeyDigest()
+                    cctx.gridConfig().getEncryptionSpi().masterKeyDigest(),
+                    req.onlyPrimary()
                 );
 
                 SnapshotHandlerContext ctx = new SnapshotHandlerContext(meta, 
req.groups(), cctx.localNode(), snpDir,
@@ -2083,12 +2100,12 @@ public class IgniteSnapshotManager extends 
GridCacheSharedManagerAdapter
 
     /** {@inheritDoc} */
     @Override public IgniteFuture<Void> createSnapshot(String name) {
-        return createSnapshot(name, null, false);
+        return createSnapshot(name, null, false, false);
     }
 
     /** {@inheritDoc} */
     @Override public IgniteFuture<Void> createIncrementalSnapshot(String name) 
{
-        return createSnapshot(name, null, true);
+        return createSnapshot(name, null, true, false);
     }
 
     /**
@@ -2096,11 +2113,19 @@ public class IgniteSnapshotManager extends 
GridCacheSharedManagerAdapter
      *
      * @param name Snapshot unique name which satisfies the following name 
pattern [a-zA-Z0-9_].
      * @param snpPath Snapshot directory path.
+     * @param incremental Incremental snapshot flag.
+     * @param onlyPrimary If {@code true} snapshot only primary copies of 
partitions.
      * @return Future which will be completed when a process ends.
      */
-    public IgniteFutureImpl<Void> createSnapshot(String name, @Nullable String 
snpPath, boolean incremental) {
+    public IgniteFutureImpl<Void> createSnapshot(
+        String name,
+        @Nullable String snpPath,
+        boolean incremental,
+        boolean onlyPrimary
+    ) {
         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_");
+        A.ensure(!(incremental && onlyPrimary), "Only primary not supported 
for incremental snapshots");
 
         try {
             cctx.kernalContext().security().authorize(ADMIN_SNAPSHOT);
@@ -2125,7 +2150,7 @@ public class IgniteSnapshotManager extends 
GridCacheSharedManagerAdapter
                 return new 
IgniteSnapshotFutureImpl(cctx.kernalContext().closure()
                     .callAsync(
                         BALANCE,
-                        new CreateSnapshotCallable(name, incremental),
+                        new CreateSnapshotCallable(name, incremental, 
onlyPrimary),
                         
options(Collections.singletonList(crd)).withFailoverDisabled()
                     ));
             }
@@ -2207,7 +2232,8 @@ public class IgniteSnapshotManager extends 
GridCacheSharedManagerAdapter
                 grps,
                 bltNodeIds,
                 incremental,
-                incIdx
+                incIdx,
+                onlyPrimary
             ));
 
             String msg =
@@ -3540,8 +3566,14 @@ public class IgniteSnapshotManager extends 
GridCacheSharedManagerAdapter
             if (isDone())
                 return;
 
-            if (stopChecker.getAsBoolean())
-                throw new TransmissionCancelledException("Future cancelled 
prior to the all requested partitions processed.");
+            if (stopChecker.getAsBoolean()) {
+                TransmissionCancelledException err =
+                    new TransmissionCancelledException("Future cancelled prior 
to the all requested partitions processed.");
+
+                acceptException(err);
+
+                throw err;
+            }
 
             try {
                 partHnd.accept(part, null);
@@ -4477,6 +4509,9 @@ public class IgniteSnapshotManager extends 
GridCacheSharedManagerAdapter
         /** Incremental flag. */
         private final boolean incremental;
 
+        /** If {@code true} snapshot only primary copies of partitions. */
+        private final boolean onlyPrimary;
+
         /** Auto-injected grid instance. */
         @IgniteInstanceResource
         private transient IgniteEx ignite;
@@ -4484,9 +4519,10 @@ public class IgniteSnapshotManager extends 
GridCacheSharedManagerAdapter
         /**
          * @param snpName Snapshot name.
          */
-        public CreateSnapshotCallable(String snpName, boolean incremental) {
+        public CreateSnapshotCallable(String snpName, boolean incremental, 
boolean onlyPrimary) {
             this.snpName = snpName;
             this.incremental = incremental;
+            this.onlyPrimary = onlyPrimary;
         }
 
         /** {@inheritDoc} */
@@ -4494,7 +4530,7 @@ public class IgniteSnapshotManager extends 
GridCacheSharedManagerAdapter
             if (incremental)
                 ignite.snapshot().createIncrementalSnapshot(snpName).get();
             else
-                ignite.snapshot().createSnapshot(snpName).get();
+                
ignite.context().cache().context().snapshotMgr().createSnapshot(snpName, null, 
false, onlyPrimary).get();
 
             return null;
         }
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 899ad04d51d..59032be79e5 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
@@ -52,7 +52,7 @@ public class SnapshotMXBeanImpl implements SnapshotMXBean {
 
     /** {@inheritDoc} */
     @Override public void createSnapshot(String snpName, String snpPath) {
-        IgniteFuture<Void> fut = mgr.createSnapshot(snpName, 
F.isEmpty(snpPath) ? null : snpPath, false);
+        IgniteFuture<Void> fut = mgr.createSnapshot(snpName, 
F.isEmpty(snpPath) ? null : snpPath, false, false);
 
         if (fut.isDone())
             fut.get();
@@ -60,7 +60,12 @@ public class SnapshotMXBeanImpl implements SnapshotMXBean {
 
     /** {@inheritDoc} */
     @Override public void createIncrementalSnapshot(String fullSnapshot, 
String fullSnapshotPath) {
-        IgniteFuture<Void> fut = mgr.createSnapshot(fullSnapshot, 
F.isEmpty(fullSnapshotPath) ? null : fullSnapshotPath, true);
+        IgniteFuture<Void> fut = mgr.createSnapshot(
+            fullSnapshot,
+            F.isEmpty(fullSnapshotPath) ? null : fullSnapshotPath,
+            true,
+            false
+        );
 
         if (fut.isDone())
             fut.get();
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotMetadata.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotMetadata.java
index cd0517ff790..2f2a3abb9dd 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotMetadata.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotMetadata.java
@@ -98,6 +98,9 @@ public class SnapshotMetadata implements Serializable {
     /** */
     private boolean hasComprGrps;
 
+    /** If {@code true} snapshot only primary copies of partitions. */
+    private boolean onlyPrimary;
+
     /**
      * @param rqId Unique request id.
      * @param snpName Snapshot name.
@@ -108,6 +111,7 @@ public class SnapshotMetadata implements Serializable {
      * @param bltNodes The set of affected by snapshot baseline nodes.
      * @param snpRecPtr WAL pointer to {@link ClusterSnapshotRecord} if exists.
      * @param masterKeyDigest Master key digest for encrypted caches.
+     * @param onlyPrimary If {@code true} snapshot only primary copies of 
partitions.
      */
     public SnapshotMetadata(
         UUID rqId,
@@ -120,7 +124,8 @@ public class SnapshotMetadata implements Serializable {
         Set<String> bltNodes,
         Set<GroupPartitionId> pairs,
         @Nullable WALPointer snpRecPtr,
-        @Nullable byte[] masterKeyDigest
+        @Nullable byte[] masterKeyDigest,
+        boolean onlyPrimary
     ) {
         this.rqId = rqId;
         this.snpName = snpName;
@@ -131,6 +136,7 @@ public class SnapshotMetadata implements Serializable {
         this.bltNodes = bltNodes;
         this.snpRecPtr = snpRecPtr;
         this.masterKeyDigest = masterKeyDigest;
+        this.onlyPrimary = onlyPrimary;
 
         if (!F.isEmpty(compGrpIds)) {
             hasComprGrps = true;
@@ -217,6 +223,11 @@ public class SnapshotMetadata implements Serializable {
         return snpRecPtr;
     }
 
+    /** @return If {@code true} snapshot only primary copies of partitions. */
+    public boolean onlyPrimary() {
+        return onlyPrimary;
+    }
+
     /** Save the state of this <tt>HashMap</tt> partitions and cache groups to 
a stream. */
     private void writeObject(java.io.ObjectOutputStream s)
         throws java.io.IOException {
@@ -282,7 +293,8 @@ public class SnapshotMetadata implements Serializable {
             pageSize() == compare.pageSize() &&
             Objects.equals(cacheGroupIds(), compare.cacheGroupIds()) &&
             Arrays.equals(masterKeyDigest, compare.masterKeyDigest) &&
-            Objects.equals(baselineNodes(), compare.baselineNodes());
+            Objects.equals(baselineNodes(), compare.baselineNodes()) &&
+            onlyPrimary == compare.onlyPrimary;
     }
 
     /**
@@ -325,13 +337,14 @@ public class SnapshotMetadata implements Serializable {
             Objects.equals(bltNodes, meta.bltNodes) &&
             Arrays.equals(masterKeyDigest, meta.masterKeyDigest) &&
             Objects.equals(warnings, meta.warnings) &&
-            Objects.equals(hasComprGrps, hasComprGrps) &&
-            Objects.equals(comprGrpIds, comprGrpIds);
+            Objects.equals(hasComprGrps, meta.hasComprGrps) &&
+            Objects.equals(comprGrpIds, meta.comprGrpIds) &&
+            onlyPrimary == meta.onlyPrimary;
     }
 
     /** {@inheritDoc} */
     @Override public int hashCode() {
-        return Objects.hash(rqId, snpName, consId, grpIds, bltNodes);
+        return Objects.hash(rqId, snpName, consId, grpIds, bltNodes, 
onlyPrimary);
     }
 
     /** {@inheritDoc} */
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotOperationRequest.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotOperationRequest.java
index d04f0206831..b9283a84154 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotOperationRequest.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/SnapshotOperationRequest.java
@@ -85,6 +85,9 @@ public class SnapshotOperationRequest implements Serializable 
{
     /** Index of incremental snapshot. */
     private final int incIdx;
 
+    /** If {@code true} snapshot only primary copies of partitions. */
+    private final boolean onlyPrimary;
+
     /**
      * @param reqId Request ID.
      * @param opNodeId Operational node ID.
@@ -94,6 +97,7 @@ public class SnapshotOperationRequest implements Serializable 
{
      * @param nodes Baseline node IDs that must be alive to complete the 
operation.
      * @param incremental {@code True} if incremental snapshot requested.
      * @param incIdx Incremental snapshot index.
+     * @param onlyPrimary If {@code true} snapshot only primary copies of 
partitions.
      */
     public SnapshotOperationRequest(
         UUID reqId,
@@ -103,7 +107,8 @@ public class SnapshotOperationRequest implements 
Serializable {
         @Nullable Collection<String> grps,
         Set<UUID> nodes,
         boolean incremental,
-        int incIdx
+        int incIdx,
+        boolean onlyPrimary
     ) {
         this.reqId = reqId;
         this.opNodeId = opNodeId;
@@ -113,6 +118,7 @@ public class SnapshotOperationRequest implements 
Serializable {
         this.snpPath = snpPath;
         this.incremental = incremental;
         this.incIdx = incIdx;
+        this.onlyPrimary = onlyPrimary;
         startTime = U.currentTimeMillis();
     }
 
@@ -182,6 +188,11 @@ public class SnapshotOperationRequest implements 
Serializable {
         return incIdx;
     }
 
+    /** @return If {@code true} snapshot only primary copies of partitions. */
+    public boolean onlyPrimary() {
+        return onlyPrimary;
+    }
+
     /** @return Start time. */
     public long startTime() {
         return startTime;
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 2abd6f65a97..71354436dba 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
@@ -358,6 +358,21 @@ public class SnapshotRestoreProcess {
             Map<Integer, String> reqGrpIds = cacheGrpNames == null ? 
Collections.emptyMap() :
                 cacheGrpNames.stream().collect(Collectors.toMap(CU::cacheId, v 
-> v));
 
+            Optional<SnapshotMetadata> firstMeta = 
metas.values().iterator().next()
+                .stream()
+                .findFirst();
+
+            if (!firstMeta.isPresent()) {
+                finishProcess(
+                    fut0.rqId,
+                    new IllegalArgumentException(OP_REJECT_MSG + "No snapshot 
metadata read")
+                );
+
+                return;
+            }
+
+            boolean onlyPrimary = firstMeta.get().onlyPrimary();
+
             for (Map.Entry<ClusterNode, List<SnapshotMetadata>> entry : 
metas.entrySet()) {
                 dataNodes.add(entry.getKey().id());
 
@@ -368,6 +383,15 @@ public class SnapshotRestoreProcess {
                         snpBltNodes = new HashSet<>(meta.baselineNodes());
 
                     reqGrpIds.keySet().removeAll(meta.partitions().keySet());
+
+                    if (onlyPrimary != meta.onlyPrimary()) {
+                        finishProcess(
+                            fut0.rqId,
+                            new IllegalArgumentException(OP_REJECT_MSG + "Only 
primary value different on nodes")
+                        );
+
+                        return;
+                    }
                 }
             }
 
@@ -395,7 +419,8 @@ public class SnapshotRestoreProcess {
                 cacheGrpNames,
                 new HashSet<>(bltNodes),
                 false,
-                incIdx
+                incIdx,
+                onlyPrimary
             );
 
             prepareRestoreProc.start(req.requestId(), req);
@@ -1103,8 +1128,14 @@ public class SnapshotRestoreProcess {
                             m.getValue(),
                             opCtx0.stopChecker,
                             (snpFile, t) -> {
-                                if (opCtx0.stopChecker.getAsBoolean())
-                                    throw new 
IgniteInterruptedException("Snapshot remote operation request cancelled.");
+                                if (opCtx0.stopChecker.getAsBoolean()) {
+                                    completeListExceptionally(
+                                        rmtAwaitParts,
+                                        new 
IgniteInterruptedException("Snapshot remote operation request cancelled.")
+                                    );
+
+                                    return;
+                                }
 
                                 if (t != null) {
                                     opCtx0.errHnd.accept(t);
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotCreateTask.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotCreateTask.java
index 4d86d5f30c8..98224415ab8 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotCreateTask.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotCreateTask.java
@@ -55,7 +55,8 @@ public class VisorSnapshotCreateTask extends 
VisorSnapshotOneNodeTask<VisorSnaps
             IgniteFutureImpl<Void> fut = 
ignite.context().cache().context().snapshotMgr().createSnapshot(
                 arg.snapshotName(),
                 arg.snapshotPath(),
-                arg.incremental()
+                arg.incremental(),
+                arg.onlyPrimary()
             );
 
             IgniteSnapshotManager.ClusterSnapshotFuture snpFut =
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotCreateTaskArg.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotCreateTaskArg.java
index eadfab88551..284a4ad825e 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotCreateTaskArg.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotCreateTaskArg.java
@@ -35,6 +35,9 @@ public class VisorSnapshotCreateTaskArg extends 
VisorSnapshotCheckTaskArg {
     /** Incremental snapshot flag. */
     private boolean inc;
 
+    /** Only primary flag. */
+    private boolean onlyPrimary;
+
     /** Default constructor. */
     public VisorSnapshotCreateTaskArg() {
         // No-op.
@@ -46,11 +49,12 @@ public class VisorSnapshotCreateTaskArg extends 
VisorSnapshotCheckTaskArg {
      * @param sync Synchronous execution flag.
      * @param inc Incremental snapshot flag.
      */
-    public VisorSnapshotCreateTaskArg(String snpName, String snpPath, boolean 
sync, boolean inc) {
+    public VisorSnapshotCreateTaskArg(String snpName, String snpPath, boolean 
sync, boolean inc, boolean onlyPrimary) {
         super(snpName, snpPath);
 
         this.sync = sync;
         this.inc = inc;
+        this.onlyPrimary = onlyPrimary;
     }
 
     /** @return Synchronous execution flag. */
@@ -63,12 +67,18 @@ public class VisorSnapshotCreateTaskArg extends 
VisorSnapshotCheckTaskArg {
         return inc;
     }
 
+    /** @return Only primary flag. */
+    public boolean onlyPrimary() {
+        return onlyPrimary;
+    }
+
     /** {@inheritDoc} */
     @Override protected void writeExternalData(ObjectOutput out) throws 
IOException {
         super.writeExternalData(out);
 
         out.writeBoolean(sync);
         out.writeBoolean(inc);
+        out.writeBoolean(onlyPrimary);
     }
 
     /** {@inheritDoc} */
@@ -77,6 +87,7 @@ public class VisorSnapshotCreateTaskArg extends 
VisorSnapshotCheckTaskArg {
 
         sync = in.readBoolean();
         inc = in.readBoolean();
+        onlyPrimary = in.readBoolean();
     }
 
     /** {@inheritDoc} */
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 d08d304873b..295ff9dff0a 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
@@ -67,7 +67,7 @@ public class VisorSnapshotRestoreTaskArg extends 
VisorSnapshotCreateTaskArg {
         @Nullable Collection<String> grpNames,
         boolean check
     ) {
-        super(snpName, snpPath, sync, false);
+        super(snpName, snpPath, sync, false, false);
 
         this.action = action;
         this.grpNames = grpNames;
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/AbstractSnapshotSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/AbstractSnapshotSelfTest.java
index 740ba459fee..802497a2d72 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/AbstractSnapshotSelfTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/AbstractSnapshotSelfTest.java
@@ -28,7 +28,6 @@ import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -41,6 +40,7 @@ import java.util.concurrent.Executor;
 import java.util.function.BiFunction;
 import java.util.function.Consumer;
 import java.util.function.Function;
+import java.util.function.Predicate;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 import org.apache.ignite.Ignite;
@@ -74,6 +74,7 @@ import org.apache.ignite.internal.pagemem.wal.WALIterator;
 import 
org.apache.ignite.internal.pagemem.wal.record.IncrementalSnapshotFinishRecord;
 import 
org.apache.ignite.internal.pagemem.wal.record.IncrementalSnapshotStartRecord;
 import org.apache.ignite.internal.pagemem.wal.record.WALRecord;
+import org.apache.ignite.internal.processors.cache.CacheGroupContext;
 import org.apache.ignite.internal.processors.cache.CacheGroupDescriptor;
 import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
 import 
org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager;
@@ -83,6 +84,7 @@ import 
org.apache.ignite.internal.processors.cache.persistence.wal.crc.FastCrc;
 import 
org.apache.ignite.internal.processors.cache.persistence.wal.reader.IgniteWalIteratorFactory;
 import org.apache.ignite.internal.processors.marshaller.MappedName;
 import 
org.apache.ignite.internal.processors.resource.GridSpringResourceContext;
+import org.apache.ignite.internal.util.future.IgniteFutureImpl;
 import org.apache.ignite.internal.util.tostring.GridToStringInclude;
 import org.apache.ignite.internal.util.typedef.G;
 import org.apache.ignite.internal.util.typedef.internal.CU;
@@ -111,10 +113,14 @@ import static 
org.apache.ignite.cluster.ClusterState.ACTIVE;
 import static org.apache.ignite.cluster.ClusterState.INACTIVE;
 import static 
org.apache.ignite.configuration.DataStorageConfiguration.DFLT_PAGE_SIZE;
 import static org.apache.ignite.events.EventType.EVTS_CLUSTER_SNAPSHOT;
+import static 
org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.CACHE_DIR_PREFIX;
+import static 
org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.CACHE_GRP_DIR_PREFIX;
 import static 
org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.FILE_SUFFIX;
 import static 
org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.PART_FILE_PREFIX;
+import static 
org.apache.ignite.internal.processors.cache.persistence.metastorage.MetaStorage.METASTORAGE_DIR_NAME;
 import static 
org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.CP_SNAPSHOT_REASON;
 import static 
org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.DFLT_SNAPSHOT_TMP_DIR;
+import static 
org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.databaseRelativePath;
 import static 
org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.incrementalSnapshotWalsDir;
 import static 
org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.resolveSnapshotWorkDirectory;
 import static 
org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.snapshotMetaFileName;
@@ -158,6 +164,9 @@ public abstract class AbstractSnapshotSelfTest extends 
GridCommonAbstractTest {
     /** Master key name. */
     protected String masterKeyName;
 
+    /** */
+    protected int[] primaries;
+
     /** Cache value builder. */
     protected Function<Integer, Object> valBuilder = String::valueOf;
 
@@ -172,13 +181,24 @@ public abstract class AbstractSnapshotSelfTest extends 
GridCommonAbstractTest {
     @Parameterized.Parameter
     public boolean encryption;
 
+    /** . */
+    @Parameterized.Parameter(1)
+    public boolean onlyPrimary;
+
     /** Parameters. */
-    @Parameterized.Parameters(name = "Encryption={0}")
-    public static Collection<Boolean> encryptionParams() {
-        if (DISK_PAGE_COMPRESSION != DiskPageCompression.DISABLED)
-            return Collections.singletonList(false);
+    @Parameterized.Parameters(name = "encryption={0}, onlyPrimay={1}")
+    public static Collection<Object[]> params() {
+        boolean[] encVals = DISK_PAGE_COMPRESSION != 
DiskPageCompression.DISABLED
+            ? new boolean[] {false}
+            : new boolean[] {false, true};
+
+        List<Object[]> res = new ArrayList<>();
+
+        for (boolean enc: encVals)
+            for (boolean onlyPrimary: new boolean[] {true, false})
+                res.add(new Object[] { enc, onlyPrimary});
 
-        return Arrays.asList(false, true);
+        return res;
     }
 
     /** {@inheritDoc} */
@@ -442,6 +462,12 @@ public abstract class AbstractSnapshotSelfTest extends 
GridCommonAbstractTest {
 
         ig.events().localListen(e -> locEvts.add(e.type()), 
EVTS_CLUSTER_SNAPSHOT);
 
+        if (dfltCacheCfg != null) {
+            primaries = ig.cacheNames().contains(dfltCacheCfg.getName())
+                ? 
ig.affinity(dfltCacheCfg.getName()).primaryPartitions(ig.localNode())
+                : null;
+        }
+
         return ig;
     }
 
@@ -529,12 +555,32 @@ public abstract class AbstractSnapshotSelfTest extends 
GridCommonAbstractTest {
      * @throws Exception if failed.
      */
     protected IgniteEx startGridsWithSnapshot(int nodesCnt, int keysCnt, 
boolean startClient) throws Exception {
+        return startGridsWithSnapshot(nodesCnt, keysCnt, startClient, false);
+    }
+
+    /**
+     * @param nodesCnt Nodes count.
+     * @param keysCnt Number of keys to create.
+     * @param startClient {@code True} to start an additional client node.
+     * @param skipCheck Skip check of snapshot.
+     * @return Ignite coordinator instance.
+     * @throws Exception if failed.
+     */
+    protected IgniteEx startGridsWithSnapshot(
+        int nodesCnt,
+        int keysCnt,
+        boolean startClient,
+        boolean skipCheck
+    ) throws Exception {
         IgniteEx ignite = startGridsWithCache(nodesCnt, keysCnt, 
valueBuilder(), dfltCacheCfg);
 
         if (startClient)
             ignite = startClientGrid("client");
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        snp(ignite).createSnapshot(SNAPSHOT_NAME, null, false, 
onlyPrimary).get(TIMEOUT);
+
+        if (!skipCheck)
+            checkSnapshot(SNAPSHOT_NAME, null);
 
         ignite.cache(dfltCacheCfg.getName()).destroy();
 
@@ -543,6 +589,127 @@ public abstract class AbstractSnapshotSelfTest extends 
GridCommonAbstractTest {
         return ignite;
     }
 
+    /** */
+    protected void createAndCheckSnapshot(IgniteEx ig, String snpName) throws 
IgniteCheckedException {
+        createAndCheckSnapshot(ig, snpName, null);
+    }
+
+    /** */
+    protected void createAndCheckSnapshot(IgniteEx ig, String snpName, String 
snpPath) throws IgniteCheckedException {
+        createAndCheckSnapshot(ig, snpName, snpPath, 0);
+    }
+
+    /** */
+    protected void createAndCheckSnapshot(
+        IgniteEx ig,
+        String snpName,
+        String snpPath,
+        long timeout
+    ) throws IgniteCheckedException {
+        IgniteFutureImpl<Void> fut = snp(ig).createSnapshot(snpName, snpPath, 
false, onlyPrimary);
+
+        if (timeout == 0)
+            fut.get();
+        else
+            fut.get(timeout);
+
+        checkSnapshot(snpName, snpPath);
+    }
+
+    /** @param snpName Snapshot name. */
+    protected void checkSnapshot(String snpName, String snpPath) throws 
IgniteCheckedException {
+        Map<String, Map<Integer, Integer>> cachesParts = new HashMap<>();
+
+        Predicate<Ignite> filter = node -> 
!node.configuration().isClientMode() &&
+            node.cluster().currentBaselineTopology()
+                .stream()
+                .anyMatch(n -> Objects.equals(n.consistentId(), 
node.cluster().localNode().consistentId()));
+
+        int nodesCnt = 0;
+
+        for (Ignite node: G.allGrids()) {
+            if (!filter.test(node))
+                continue;
+
+            nodesCnt++;
+
+            IgniteEx node0 = (IgniteEx)node;
+
+            File nodeSnapDir = new File(
+                snp(node0).snapshotLocalDir(snpName, 
snpPath).getAbsolutePath(),
+                
databaseRelativePath(node0.context().pdsFolderResolver().resolveFolders().folderName())
+            );
+
+            if (!nodeSnapDir.exists())
+                continue;
+
+            File[] cacheDirs = nodeSnapDir.listFiles(f -> f.isDirectory() && 
!f.getName().equals(METASTORAGE_DIR_NAME));
+
+            for (File cacheDir : cacheDirs) {
+                String name = 
cacheDir.getName().startsWith(CACHE_GRP_DIR_PREFIX)
+                    ? 
cacheDir.getName().substring(CACHE_GRP_DIR_PREFIX.length())
+                    : cacheDir.getName().substring(CACHE_DIR_PREFIX.length());
+
+                Map<Integer, Integer> cacheParts = 
cachesParts.computeIfAbsent(name, k -> new HashMap<>());
+
+                File[] parts = cacheDir.listFiles(f ->
+                    f.getName().startsWith(PART_FILE_PREFIX)
+                        && f.getName().endsWith(FILE_SUFFIX));
+
+                for (File partFile : parts) {
+                    int part = Integer.parseInt(partFile.getName()
+                        .substring(PART_FILE_PREFIX.length())
+                        .replace(FILE_SUFFIX, ""));
+
+                    cacheParts.compute(part, (part0, cnt) -> (cnt == null ? 0 
: cnt) + 1);
+                }
+            }
+        }
+
+        assertTrue(nodesCnt > 0);
+
+        for (Map.Entry<String, Map<Integer, Integer>> entry : 
cachesParts.entrySet()) {
+            String cache = entry.getKey();
+
+            int parts = -1;
+            Integer expPartCopiesInSnp;
+
+            if (onlyPrimary)
+                expPartCopiesInSnp = 1;
+            else {
+                int backups = -1;
+                int affinityNodes = 0;
+
+                for (Ignite node: G.allGrids()) {
+                    if (!filter.test(node))
+                        continue;
+
+                    CacheGroupContext grpCtx = 
((IgniteEx)node).context().cache().cacheGroup(CU.cacheId(cache));
+
+                    if (grpCtx != null) {
+                        backups = grpCtx.config().getBackups();
+                        parts = grpCtx.affinity().partitions();
+
+                        affinityNodes++;
+                    }
+                }
+
+                assertTrue(backups != -1);
+                assertTrue(parts != -1);
+                assertTrue(affinityNodes > 0);
+
+                expPartCopiesInSnp = backups == Integer.MAX_VALUE
+                    ? affinityNodes
+                    : Math.min(backups + 1, affinityNodes);
+            }
+
+            Map<Integer, Integer> cacheParts = entry.getValue();
+
+            for (int i = 0; i < parts; i++)
+                assertEquals("[cache=" + cache + ", part=" + i + ']', 
expPartCopiesInSnp, cacheParts.get(i));
+        }
+    }
+
     /**
      * @param ignite Ignite instance.
      * @return Snapshot manager related to given ignite instance.
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 e7ede620a76..a66eabf45e1 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
@@ -18,7 +18,9 @@
 package org.apache.ignite.internal.processors.cache.persistence.snapshot;
 
 import java.io.File;
+import java.util.Arrays;
 import java.util.Collections;
+import java.util.List;
 import java.util.function.Function;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteDataStreamer;
@@ -53,9 +55,12 @@ public class EncryptedSnapshotTest extends 
AbstractSnapshotSelfTest {
     private static final String CACHE2 = "cache2";
 
     /** Parameters. */
-    @Parameterized.Parameters(name = "Encryption is enabled.")
-    public static Iterable<Boolean> enableEncryption() {
-        return Collections.singletonList(true);
+    @Parameterized.Parameters(name = "encryption={0}, onlyPrimay={1}")
+    public static List<Object[]> disableEncryption() {
+        return Arrays.asList(
+            new Object[]{true, false},
+            new Object[]{true, true}
+        );
     }
 
     /** {@inheritDoc} */
@@ -122,7 +127,7 @@ public class EncryptedSnapshotTest extends 
AbstractSnapshotSelfTest {
     public void testSnapshotRestoringFailsWithOtherMasterKey() throws 
Exception {
         IgniteEx ig = startGridsWithCache(2, CACHE_KEYS_RANGE, valueBuilder(), 
dfltCacheCfg);
 
-        snp(ig).createSnapshot(SNAPSHOT_NAME).get();
+        createAndCheckSnapshot(ig, SNAPSHOT_NAME);
 
         ig.destroyCache(dfltCacheCfg.getName());
 
@@ -185,7 +190,7 @@ public class EncryptedSnapshotTest extends 
AbstractSnapshotSelfTest {
     public void testValidatingSnapshotFailsWithOtherMasterKey() throws 
Exception {
         IgniteEx ig = startGridsWithCache(2, CACHE_KEYS_RANGE, valueBuilder(), 
dfltCacheCfg);
 
-        ig.snapshot().createSnapshot(SNAPSHOT_NAME).get();
+        createAndCheckSnapshot(ig, SNAPSHOT_NAME);
 
         ig.destroyCache(dfltCacheCfg.getName());
 
@@ -260,7 +265,7 @@ public class EncryptedSnapshotTest extends 
AbstractSnapshotSelfTest {
     public void testStartFromSnapshotFailedWithOtherMasterKey() throws 
Exception {
         IgniteEx ig = startGridsWithCache(2, CACHE_KEYS_RANGE, valueBuilder(), 
dfltCacheCfg);
 
-        ig.snapshot().createSnapshot(SNAPSHOT_NAME).get();
+        createAndCheckSnapshot(ig, SNAPSHOT_NAME);
 
         ig.destroyCache(dfltCacheCfg.getName());
 
@@ -313,7 +318,7 @@ public class EncryptedSnapshotTest extends 
AbstractSnapshotSelfTest {
 
         addCache(encryptedFirst);
 
-        grid(1).snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        snp(grid(1)).createSnapshot(SNAPSHOT_NAME, null, false, 
onlyPrimary).get(TIMEOUT);
 
         awaitPartitionMapExchange();
 
@@ -339,7 +344,7 @@ public class EncryptedSnapshotTest extends 
AbstractSnapshotSelfTest {
                 
grid(g).context().encryption().reencryptionFuture(CU.cacheId(dfltCacheCfg.getName())).get();
         }
 
-        ig.snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(ig, SNAPSHOT_NAME, null, TIMEOUT);
 
         ig.cache(dfltCacheCfg.getName()).destroy();
 
@@ -374,7 +379,7 @@ public class EncryptedSnapshotTest extends 
AbstractSnapshotSelfTest {
         IgniteFuture<Void> fut;
 
         if (restore) {
-            grid(1).snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+            createAndCheckSnapshot(grid(1), SNAPSHOT_NAME, null, TIMEOUT);
 
             grid(1).cache(dfltCacheCfg.getName()).destroy();
 
@@ -387,7 +392,7 @@ public class EncryptedSnapshotTest extends 
AbstractSnapshotSelfTest {
         else {
             spi0.block((msg) -> msg instanceof FullMessage && 
((FullMessage<?>)msg).error().isEmpty());
 
-            fut = grid(1).snapshot().createSnapshot(SNAPSHOT_NAME);
+            fut = snp(grid(1)).createSnapshot(SNAPSHOT_NAME, null, false, 
onlyPrimary);
         }
 
         spi0.waitBlocked(TIMEOUT);
@@ -417,7 +422,7 @@ public class EncryptedSnapshotTest extends 
AbstractSnapshotSelfTest {
 
         startGrid(G.allGrids().size());
 
-        grid(1).snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(grid(1), SNAPSHOT_NAME, null, TIMEOUT);
 
         grid(2).destroyCache(dfltCacheCfg.getName());
 
@@ -440,7 +445,7 @@ public class EncryptedSnapshotTest extends 
AbstractSnapshotSelfTest {
             expectedError);
 
         GridTestUtils.assertThrowsAnyCause(log,
-            () -> grid(2).snapshot().createSnapshot(SNAPSHOT_NAME + 
"_v2").get(TIMEOUT), IgniteCheckedException.class,
+            () -> snp(grid(2)).createSnapshot(SNAPSHOT_NAME + "_v2", null, 
false, onlyPrimary).get(TIMEOUT), IgniteCheckedException.class,
             expectedError);
 
         discoSpi.unblock();
@@ -482,7 +487,7 @@ public class EncryptedSnapshotTest extends 
AbstractSnapshotSelfTest {
 
         CacheConfiguration<?, ?> ccfg = addCache(false);
 
-        grid(1).snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(grid(1), SNAPSHOT_NAME, null, TIMEOUT);
 
         grid(1).cache(DEFAULT_CACHE_NAME).destroy();
         grid(1).cache(CACHE2).destroy();
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 398c150bf92..dec08de15fb 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
@@ -78,6 +78,7 @@ import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.internal.visor.verify.CacheFilterEnum;
 import org.apache.ignite.internal.visor.verify.VisorIdleVerifyTaskArg;
 import org.jetbrains.annotations.Nullable;
+import org.junit.Assume;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -122,7 +123,7 @@ public class IgniteClusterSnapshotCheckTest extends 
AbstractSnapshotSelfTest {
 
         startClientGrid();
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get();
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME);
 
         IdleVerifyResultV2 res = snp(ignite).checkSnapshot(SNAPSHOT_NAME, 
null).get().idleVerifyResult();
 
@@ -139,8 +140,7 @@ public class IgniteClusterSnapshotCheckTest extends 
AbstractSnapshotSelfTest {
     public void testClusterSnapshotCheckMissedPart() throws Exception {
         IgniteEx ignite = startGridsWithCache(3, dfltCacheCfg, 
CACHE_KEYS_RANGE);
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME)
-            .get();
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME);
 
         Path part0 = 
U.searchFileRecursively(snp(ignite).snapshotLocalDir(SNAPSHOT_NAME).toPath(),
             getPartitionFileName(0));
@@ -163,8 +163,7 @@ public class IgniteClusterSnapshotCheckTest extends 
AbstractSnapshotSelfTest {
     public void testClusterSnapshotCheckMissedGroup() throws Exception {
         IgniteEx ignite = startGridsWithCache(3, dfltCacheCfg, 
CACHE_KEYS_RANGE);
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME)
-            .get();
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME);
 
         Path dir = 
Files.walk(snp(ignite).snapshotLocalDir(SNAPSHOT_NAME).toPath())
             .filter(d -> 
d.toFile().getName().equals(cacheDirName(dfltCacheCfg)))
@@ -188,8 +187,7 @@ public class IgniteClusterSnapshotCheckTest extends 
AbstractSnapshotSelfTest {
     public void testClusterSnapshotCheckMissedMeta() throws Exception {
         IgniteEx ignite = startGridsWithCache(3, dfltCacheCfg, 
CACHE_KEYS_RANGE);
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME)
-            .get();
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME);
 
         File[] smfs = 
snp(ignite).snapshotLocalDir(SNAPSHOT_NAME).listFiles((dir, name) ->
             name.toLowerCase().endsWith(SNAPSHOT_METAFILE_EXT));
@@ -217,7 +215,7 @@ public class IgniteClusterSnapshotCheckTest extends 
AbstractSnapshotSelfTest {
                 .setNodeFilter(node -> 
node.consistentId().toString().endsWith("0"))).put(i, i);
         }
 
-        ig0.snapshot().createSnapshot(SNAPSHOT_NAME).get();
+        createAndCheckSnapshot(ig0, SNAPSHOT_NAME);
 
         IdleVerifyResultV2 res = snp(ig0).checkSnapshot(SNAPSHOT_NAME, 
null).get().idleVerifyResult();
 
@@ -232,11 +230,13 @@ public class IgniteClusterSnapshotCheckTest extends 
AbstractSnapshotSelfTest {
     /** @throws Exception If fails. */
     @Test
     public void testClusterSnapshotCheckPartitionCounters() throws Exception {
+        Assume.assumeFalse("One copy of partiton created in only primary 
mode", onlyPrimary);
+
         IgniteEx ignite = startGridsWithCache(3, dfltCacheCfg.
             setAffinity(new RendezvousAffinityFunction(false, 1)),
             CACHE_KEYS_RANGE);
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get();
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME);
 
         Path part0 = 
U.searchFileRecursively(snp(ignite).snapshotLocalDir(SNAPSHOT_NAME).toPath(),
             getPartitionFileName(PART_ID));
@@ -310,7 +310,8 @@ public class IgniteClusterSnapshotCheckTest extends 
AbstractSnapshotSelfTest {
                 setAffinity(new RendezvousAffinityFunction(false, 1)),
             CACHE_KEYS_RANGE);
 
-        ig0.snapshot().createSnapshot(SNAPSHOT_NAME).get();
+        createAndCheckSnapshot(ig0, SNAPSHOT_NAME);
+
         stopAllGrids();
 
         // Cleanup persistence directory except created snapshots.
@@ -361,7 +362,7 @@ public class IgniteClusterSnapshotCheckTest extends 
AbstractSnapshotSelfTest {
         IgniteEx ignite = startGridsWithCache(3, dfltCacheCfg.
                 setAffinity(new RendezvousAffinityFunction(false, 1)), 
CACHE_KEYS_RANGE);
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get();
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME);
 
         corruptPartitionFile(ignite, SNAPSHOT_NAME, dfltCacheCfg, PART_ID);
 
@@ -384,6 +385,8 @@ public class IgniteClusterSnapshotCheckTest extends 
AbstractSnapshotSelfTest {
     /** @throws Exception If fails. */
     @Test
     public void testClusterSnapshotCheckFailsOnPartitionDataDiffers() throws 
Exception {
+        Assume.assumeFalse("One copy of partiton created in only primary 
mode", onlyPrimary);
+
         CacheConfiguration<Integer, Value> ccfg = txCacheConfig(new 
CacheConfiguration<Integer, Value>(DEFAULT_CACHE_NAME))
             .setAffinity(new RendezvousAffinityFunction(false, 1));
 
@@ -467,7 +470,7 @@ public class IgniteClusterSnapshotCheckTest extends 
AbstractSnapshotSelfTest {
 
         db.waitForCheckpoint("test-checkpoint");
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get();
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME);
 
         Path part0 = 
U.searchFileRecursively(snp(ignite).snapshotLocalDir(SNAPSHOT_NAME).toPath(),
             getPartitionFileName(PART_ID));
@@ -493,7 +496,7 @@ public class IgniteClusterSnapshotCheckTest extends 
AbstractSnapshotSelfTest {
 
         IgniteEx ignite = startGridsWithCache(1, CACHE_KEYS_RANGE, k -> new 
Value(new byte[rnd.nextInt(32768)]), ccfg);
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get();
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME);
 
         IdleVerifyResultV2 idleVerifyRes = ignite.compute().execute(new 
TestVisorBackupPartitionsTask(),
             new VisorIdleVerifyTaskArg(new 
HashSet<>(singletonList(ccfg.getName())),
@@ -577,7 +580,7 @@ public class IgniteClusterSnapshotCheckTest extends 
AbstractSnapshotSelfTest {
 
         startClientGrid();
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get();
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME);
 
         int iterations = 10;
 
@@ -630,7 +633,7 @@ public class IgniteClusterSnapshotCheckTest extends 
AbstractSnapshotSelfTest {
         IgniteEx ignite = startGridsWithCache(2, CACHE_KEYS_RANGE, k -> new 
Value(new byte[rnd.nextInt(32768)]),
             ccfg1, ccfg2);
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get();
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME);
 
         corruptPartitionFile(ignite, SNAPSHOT_NAME, ccfg1, PART_ID);
 
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotDeltaTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotDeltaTest.java
index 758c90a524d..c79f8b4b6e9 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotDeltaTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotDeltaTest.java
@@ -21,8 +21,10 @@ import java.io.File;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.file.OpenOption;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.function.BiFunction;
@@ -35,7 +37,6 @@ import 
org.apache.ignite.internal.processors.cache.persistence.file.FileIODecora
 import 
org.apache.ignite.internal.processors.cache.persistence.file.FileIOFactory;
 import 
org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager;
 import 
org.apache.ignite.internal.processors.cache.persistence.partstate.GroupPartitionId;
-import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteFuture;
 import org.apache.ignite.testframework.GridTestUtils;
@@ -48,7 +49,6 @@ import static 
org.apache.ignite.internal.pagemem.PageIdAllocator.INDEX_PARTITION
 import static 
org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.CACHE_DIR_PREFIX;
 import static 
org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.DeltaSortedIterator.DELTA_SORT_BATCH_SIZE;
 import static 
org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.partDeltaIndexFile;
-import static org.apache.ignite.testframework.GridTestUtils.cartesianProduct;
 import static org.junit.Assert.assertArrayEquals;
 
 /**
@@ -57,13 +57,27 @@ import static org.junit.Assert.assertArrayEquals;
 @RunWith(Parameterized.class)
 public class IgniteClusterSnapshotDeltaTest extends AbstractSnapshotSelfTest {
     /** */
-    @Parameterized.Parameter(1)
+    @Parameterized.Parameter(2)
     public boolean sequentialWrite;
 
     /** Parameters. */
-    @Parameterized.Parameters(name = "encryption={0}, sequentialWrite={1}")
+    @Parameterized.Parameters(name = "encryption={0}, onlyPrimary={1}, 
sequentialWrite={1}")
     public static Collection<Object[]> parameters() {
-        return cartesianProduct(encryptionParams(), F.asList(false, true));
+        Collection<Object[]> baseParams = params();
+
+        List<Object[]> res = new ArrayList<>();
+
+        for (boolean seqWrite : new boolean[] {false, true}) {
+            for (Object[] baseParam : baseParams) {
+                Object[] res0 = Arrays.copyOf(baseParam, baseParam.length + 1);
+
+                res0[baseParam.length] = seqWrite;
+
+                res.add(res0);
+            }
+        }
+
+        return res;
     }
 
     /** {@inheritDoc} */
@@ -139,7 +153,7 @@ public class IgniteClusterSnapshotDeltaTest extends 
AbstractSnapshotSelfTest {
         });
 
         // 2. Start a snapshot and block copy of a partitions.
-        IgniteFuture<Void> fut = srv.snapshot().createSnapshot(SNAPSHOT_NAME);
+        IgniteFuture<Void> fut = snp(srv).createSnapshot(SNAPSHOT_NAME, null, 
false, onlyPrimary);
 
         GridTestUtils.waitForCondition(() -> mgr.currentCreateRequest() != 
null, getTestTimeout());
 
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotHandlerTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotHandlerTest.java
index 13edc33a16b..1c3ae2ef5bc 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotHandlerTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotHandlerTest.java
@@ -203,13 +203,13 @@ public class IgniteClusterSnapshotHandlerTest extends 
IgniteClusterSnapshotResto
 
         IgniteEx ignite = startGridsWithCache(2, CACHE_KEYS_RANGE, 
valueBuilder(), dfltCacheCfg);
 
-        IgniteFuture<Void> fut = 
ignite.snapshot().createSnapshot(SNAPSHOT_NAME);
+        IgniteFuture<Void> fut = snp(ignite).createSnapshot(SNAPSHOT_NAME, 
null, false, onlyPrimary);
 
         GridTestUtils.assertThrowsAnyCause(log, () -> fut.get(TIMEOUT), 
IgniteCheckedException.class, expMsg);
 
         failCreateFlag.set(false);
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME, null, TIMEOUT);
 
         ignite.cache(DEFAULT_CACHE_NAME).destroy();
 
@@ -254,7 +254,7 @@ public class IgniteClusterSnapshotHandlerTest extends 
IgniteClusterSnapshotResto
         resetBaselineTopology();
 
         // Case 1: handler is loaded on only one of the two nodes.
-        IgniteFuture<Void> fut0 = 
grid(0).snapshot().createSnapshot(SNAPSHOT_NAME);
+        IgniteFuture<Void> fut0 = snp(grid(0)).createSnapshot(SNAPSHOT_NAME, 
null, false, onlyPrimary);
 
         UUID nodeId1 = grid(1).localNode().id();
 
@@ -276,7 +276,7 @@ public class IgniteClusterSnapshotHandlerTest extends 
IgniteClusterSnapshotResto
 
         startGrid(1);
 
-        IgniteFuture<Void> fut1 = 
grid(0).snapshot().createSnapshot(SNAPSHOT_NAME);
+        IgniteFuture<Void> fut1 = snp(grid(0)).createSnapshot(SNAPSHOT_NAME, 
null, false, onlyPrimary);
 
         GridTestUtils.assertThrowsAnyCause(log, () -> fut1.get(TIMEOUT), 
IgniteCheckedException.class,
             "Snapshot handlers configuration mismatch (number of local 
snapshot handlers differs from the remote one)");
@@ -288,7 +288,7 @@ public class IgniteClusterSnapshotHandlerTest extends 
IgniteClusterSnapshotResto
 
         startGrid(1);
 
-        IgniteFuture<Void> fut2 = 
grid(0).snapshot().createSnapshot(SNAPSHOT_NAME);
+        IgniteFuture<Void> fut2 = snp(grid(0)).createSnapshot(SNAPSHOT_NAME, 
null, false, onlyPrimary);
 
         GridTestUtils.assertThrowsAnyCause(log, () -> fut2.get(TIMEOUT), 
IgniteCheckedException.class,
             "Snapshot handlers configuration mismatch (number of local 
snapshot handlers differs from the remote one)");
@@ -301,7 +301,7 @@ public class IgniteClusterSnapshotHandlerTest extends 
IgniteClusterSnapshotResto
 
         startGrid(1);
 
-        grid(1).snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(grid(1), SNAPSHOT_NAME, null, TIMEOUT);
     }
 
     /**
@@ -335,7 +335,7 @@ public class IgniteClusterSnapshotHandlerTest extends 
IgniteClusterSnapshotResto
 
         startGridsWithCache(2, CACHE_KEYS_RANGE, valueBuilder(), dfltCacheCfg);
 
-        IgniteFuture<Void> fut = 
grid(1).snapshot().createSnapshot(SNAPSHOT_NAME);
+        IgniteFuture<Void> fut = snp(grid(1)).createSnapshot(SNAPSHOT_NAME, 
null, false, onlyPrimary);
 
         latch.await();
 
@@ -347,7 +347,7 @@ public class IgniteClusterSnapshotHandlerTest extends 
IgniteClusterSnapshotResto
             "Snapshot operation interrupted, because baseline node left the 
cluster: " + crdNodeId);
 
         startGrid(0);
-        grid(0).snapshot().createSnapshot(SNAPSHOT_NAME);
+        snp(grid(0)).createSnapshot(SNAPSHOT_NAME, null, false, onlyPrimary);
     }
 
     /**
@@ -394,7 +394,7 @@ public class IgniteClusterSnapshotHandlerTest extends 
IgniteClusterSnapshotResto
 
             IgniteSnapshotManager snpMgr = 
ignite.context().cache().context().snapshotMgr();
 
-            snpMgr.createSnapshot(snpName, snpDir.getAbsolutePath(), 
false).get(TIMEOUT);
+            createAndCheckSnapshot(ignite, snpName, snpDir.getAbsolutePath(), 
TIMEOUT);
 
             ignite.destroyCache(DEFAULT_CACHE_NAME);
             awaitPartitionMapExchange();
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotRestoreSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotRestoreSelfTest.java
index 5574d01c059..41cfef6fda9 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotRestoreSelfTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotRestoreSelfTest.java
@@ -115,7 +115,8 @@ public class IgniteClusterSnapshotRestoreSelfTest extends 
IgniteClusterSnapshotR
     public void testRestoreWithEmptyPartitions() throws Exception {
         int keysCnt = dfltCacheCfg.getAffinity().partitions() / 2;
 
-        Ignite ignite = startGridsWithSnapshot(1, keysCnt, false);
+        // Skip check because some partitions will be empty - keysCnt == 
parts/2.
+        Ignite ignite = startGridsWithSnapshot(1, keysCnt, false, true);
 
         ignite.snapshot().restoreSnapshot(SNAPSHOT_NAME, null).get(TIMEOUT);
 
@@ -138,9 +139,7 @@ public class IgniteClusterSnapshotRestoreSelfTest extends 
IgniteClusterSnapshotR
             for (int i = 0; i < CACHE_KEYS_RANGE; i++)
                 ignite.cache(DEFAULT_CACHE_NAME).put(i, i);
 
-            ignite.context().cache().context().snapshotMgr()
-                .createSnapshot(SNAPSHOT_NAME, snpDir.toString(), false)
-                .get(TIMEOUT);
+            createAndCheckSnapshot(ignite, SNAPSHOT_NAME, snpDir.toString(), 
TIMEOUT);
 
             // Check snapshot.
             IdleVerifyResultV2 res = snp(ignite).checkSnapshot(SNAPSHOT_NAME, 
snpDir.getAbsolutePath()).get(TIMEOUT)
@@ -220,7 +219,7 @@ public class IgniteClusterSnapshotRestoreSelfTest extends 
IgniteClusterSnapshotR
         IgniteEx ignite = startGridsWithCache(2, CACHE_KEYS_RANGE, 
valueBuilder(),
             dfltCacheCfg.setBackups(0), cacheCfg1, cacheCfg2);
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME, null, TIMEOUT);
 
         ignite.cache(CACHE1).destroy();
         ignite.cache(CACHE2).destroy();
@@ -312,7 +311,7 @@ public class IgniteClusterSnapshotRestoreSelfTest extends 
IgniteClusterSnapshotR
 
         GridTestUtils.assertThrowsAnyCause(
             log,
-            () -> 
grid(1).snapshot().createSnapshot("NEW_SNAPSHOT").get(TIMEOUT),
+            () -> snp(grid(1)).createSnapshot("NEW_SNAPSHOT", null, false, 
onlyPrimary).get(TIMEOUT),
             IgniteException.class,
             "Cache group restore operation is currently in progress."
         );
@@ -419,7 +418,7 @@ public class IgniteClusterSnapshotRestoreSelfTest extends 
IgniteClusterSnapshotR
     public void testClusterSnapshotRestoreRejectOnInActiveCluster() throws 
Exception {
         IgniteEx ignite = startGridsWithCache(2, CACHE_KEYS_RANGE, 
valueBuilder(), dfltCacheCfg);
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME, null, TIMEOUT);
 
         ignite.cluster().state(ClusterState.INACTIVE);
 
@@ -460,7 +459,7 @@ public class IgniteClusterSnapshotRestoreSelfTest extends 
IgniteClusterSnapshotR
 
         ignite.cluster().state(ClusterState.ACTIVE);
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME, null, TIMEOUT);
 
         ignite.cache(CACHE1).destroy();
 
@@ -789,7 +788,8 @@ public class IgniteClusterSnapshotRestoreSelfTest extends 
IgniteClusterSnapshotR
 
         valBuilder = Account::new;
 
-        startGridsWithSnapshot(nodes, keysCnt);
+        // Skip check because some partitions will be empty - keysCnt < parts.
+        startGridsWithSnapshot(nodes, keysCnt, false, true);
 
         stopAllGrids();
 
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotSelfTest.java
index 44f156e7975..9aa317c3212 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotSelfTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotSelfTest.java
@@ -215,12 +215,14 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
         }, 3, "cache-put-");
 
         try {
-            IgniteFuture<Void> fut = ignite.snapshot().createSnapshot(snpName);
+            IgniteFuture<Void> fut = snp(ignite).createSnapshot(snpName, null, 
false, onlyPrimary);
 
             U.await(loadLatch, 10, TimeUnit.SECONDS);
 
             fut.get();
 
+            checkSnapshot(SNAPSHOT_NAME, null);
+
             waitForEvents(EVT_CLUSTER_SNAPSHOT_STARTED, 
EVT_CLUSTER_SNAPSHOT_FINISHED);
         }
         finally {
@@ -288,9 +290,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
         }, 5, "atomic-cache-put-");
 
         try {
-            IgniteFuture<Void> fut = 
ignite.snapshot().createSnapshot(SNAPSHOT_NAME);
-
-            fut.get();
+            createAndCheckSnapshot(ignite, SNAPSHOT_NAME);
         }
         finally {
             txLoadFut.cancel();
@@ -301,23 +301,29 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
 
         IgniteEx snpIg0 = startGridsFromSnapshot(grids, cfg -> 
resolveSnapshotWorkDirectory(cfg).getAbsolutePath(), SNAPSHOT_NAME, false);
 
-        // Block whole rebalancing.
-        for (Ignite g : G.allGrids())
-            TestRecordingCommunicationSpi.spi(g).blockMessages((node, msg) -> 
msg instanceof GridDhtPartitionDemandMessage);
+        if (!onlyPrimary) {
+            // Block whole rebalancing.
+            for (Ignite g : G.allGrids())
+                TestRecordingCommunicationSpi.spi(g)
+                    .blockMessages((node, msg) -> msg instanceof 
GridDhtPartitionDemandMessage);
 
-        snpIg0.cluster().state(ACTIVE);
+            snpIg0.cluster().state(ACTIVE);
 
-        assertFalse("Primary and backup in snapshot must have the same 
counters. Rebalance must not happen.",
-            GridTestUtils.waitForCondition(() -> {
-                boolean hasMsgs = false;
+            assertFalse("Primary and backup in snapshot must have the same 
counters. Rebalance must not happen.",
+                GridTestUtils.waitForCondition(() -> {
+                    boolean hasMsgs = false;
 
-                for (Ignite g : G.allGrids())
-                    hasMsgs |= 
TestRecordingCommunicationSpi.spi(g).hasBlockedMessages();
+                    for (Ignite g : G.allGrids())
+                        hasMsgs |= 
TestRecordingCommunicationSpi.spi(g).hasBlockedMessages();
 
-                return hasMsgs;
-            }, REBALANCE_AWAIT_TIME));
+                    return hasMsgs;
+                }, REBALANCE_AWAIT_TIME));
 
-        TestRecordingCommunicationSpi.stopBlockAll();
+            TestRecordingCommunicationSpi.stopBlockAll();
+        }
+        else {
+            snpIg0.cluster().state(ACTIVE);
+        }
 
         assertPartitionsSame(idleVerify(snpIg0, dfltCacheCfg.getName(), 
atomicCcfg.getName()));
     }
@@ -390,7 +396,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
         try {
             U.await(txStarted);
 
-            grid(0).snapshot().createSnapshot(SNAPSHOT_NAME).get();
+            snp(grid(0)).createSnapshot(SNAPSHOT_NAME, null, false, 
onlyPrimary).get();
         }
         finally {
             stop.set(true);
@@ -422,7 +428,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
         for (int i = 0; i < CACHE_KEYS_RANGE; i++)
             ig0.getOrCreateCache(ccfg).put(i, i);
 
-        ig0.snapshot().createSnapshot(SNAPSHOT_NAME).get();
+        snp(ig0).createSnapshot(SNAPSHOT_NAME, null, false, onlyPrimary).get();
 
         stopAllGrids();
 
@@ -466,7 +472,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
             return false;
         });
 
-        IgniteFuture<Void> fut = 
ignite.snapshot().createSnapshot(SNAPSHOT_NAME);
+        IgniteFuture<Void> fut = snp(ignite).createSnapshot(SNAPSHOT_NAME, 
null, false, onlyPrimary);
 
         spi.waitBlocked(TIMEOUT);
 
@@ -502,7 +508,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
         BlockingCustomMessageDiscoverySpi spi = discoSpi(ignite);
         spi.block((msg) -> msg instanceof FullMessage);
 
-        IgniteFuture<Void> fut = 
ignite.snapshot().createSnapshot(SNAPSHOT_NAME);
+        IgniteFuture<Void> fut = snp(ignite).createSnapshot(SNAPSHOT_NAME, 
null, false, onlyPrimary);
 
         spi.waitBlocked(TIMEOUT);
 
@@ -535,7 +541,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
             if (inc) {
                 
assumeFalse("https://issues.apache.org/jira/browse/IGNITE-17819";, encryption);
 
-                ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+                createAndCheckSnapshot(ignite, SNAPSHOT_NAME, null, TIMEOUT);
             }
 
             BlockingCustomMessageDiscoverySpi spi = discoSpi(ignite);
@@ -543,7 +549,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
 
             IgniteFuture<Void> fut = inc
                 ? ignite.snapshot().createIncrementalSnapshot(SNAPSHOT_NAME)
-                : ignite.snapshot().createSnapshot(SNAPSHOT_NAME);
+                : snp(ignite).createSnapshot(SNAPSHOT_NAME, null, false, 
onlyPrimary);
 
             spi.waitBlocked(TIMEOUT);
 
@@ -564,10 +570,10 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
     public void testSnapshotExistsException() throws Exception {
         IgniteEx ignite = startGridsWithCache(2, dfltCacheCfg, 
CACHE_KEYS_RANGE);
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get();
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME);
 
         assertThrowsAnyCause(log,
-            () -> ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get(),
+            () -> snp(ignite).createSnapshot(SNAPSHOT_NAME, null, false, 
onlyPrimary).get(),
             IgniteException.class,
             "Snapshot with given name already exists on local node.");
 
@@ -600,7 +606,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
         TestRecordingCommunicationSpi commSpi1 = 
TestRecordingCommunicationSpi.spi(grid(1));
         commSpi1.blockMessages((node, msg) -> msg instanceof 
SingleNodeMessage);
 
-        IgniteFuture<?> fut = ignite.snapshot().createSnapshot(SNAPSHOT_NAME);
+        IgniteFuture<?> fut = snp(ignite).createSnapshot(SNAPSHOT_NAME, null, 
false, onlyPrimary);
 
         U.await(partProcessed, TIMEOUT, TimeUnit.MILLISECONDS);
 
@@ -663,7 +669,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
         awaitPartitionMapExchange();
 
         assertThrowsAnyCause(log,
-            () -> ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get(),
+            () -> snp(ignite).createSnapshot(SNAPSHOT_NAME, null, false, 
onlyPrimary).get(),
             ClusterTopologyException.class,
             "Snapshot operation interrupted, because baseline node left the 
cluster");
 
@@ -688,12 +694,11 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
             
grid2.context().cache().context().snapshotMgr().localSnapshotNames(null).isEmpty()
         );
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME)
-            .get();
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME);
 
         stopAllGrids();
 
-        IgniteEx snp = startGridsFromSnapshot(2, SNAPSHOT_NAME);
+        IgniteEx snp = startGridsFromSnapshot(onlyPrimary ? 3 : 2, 
SNAPSHOT_NAME);
 
         assertSnapshotCacheKeys(snp.cache(dfltCacheCfg.getName()));
     }
@@ -712,7 +717,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
 
         commSpi.waitForBlocked();
 
-        IgniteFuture<Void> fut = 
ignite.snapshot().createSnapshot(SNAPSHOT_NAME);
+        IgniteFuture<Void> fut = snp(ignite).createSnapshot(SNAPSHOT_NAME, 
null, false, onlyPrimary);
 
         commSpi.stopBlock(true);
 
@@ -764,8 +769,9 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
             for (int i = 0; i < CACHE_KEYS_RANGE; i++)
                 ignite.cache(DEFAULT_CACHE_NAME).put(i, i);
 
-            ignite.context().cache().context().snapshotMgr()
-                .createSnapshot(SNAPSHOT_NAME, cfgPath ? null : 
snpDir.getAbsolutePath(), false).get();
+            String snpPath = cfgPath ? null : snpDir.getAbsolutePath();
+
+            createAndCheckSnapshot(ignite, SNAPSHOT_NAME, snpPath);
 
             stopAllGrids();
 
@@ -792,7 +798,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
 
             assertThrowsAnyCause(log,
                 () -> kctx.cache().context().snapshotMgr()
-                    .createSnapshot(SNAPSHOT_NAME, invalidPath, false)
+                    .createSnapshot(SNAPSHOT_NAME, invalidPath, false, 
onlyPrimary)
                     .get(TIMEOUT),
                 IgniteCheckedException.class,
                 invalidPath);
@@ -841,7 +847,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
 
         long cutoffStartTime = U.currentTimeMillis();
 
-        IgniteFuture<Void> fut0 = 
ignite.snapshot().createSnapshot(SNAPSHOT_NAME);
+        IgniteFuture<Void> fut0 = snp(ignite).createSnapshot(SNAPSHOT_NAME, 
null, false, onlyPrimary);
 
         U.await(deltaApply);
 
@@ -855,7 +861,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
         assertTrue("Snapshot error message must null prior to snapshot 
operation started.",
             errMsg.value().isEmpty());
 
-        IgniteFuture<Void> fut1 = 
grid(1).snapshot().createSnapshot(newSnapshotName);
+        IgniteFuture<Void> fut1 = snp(grid(1)).createSnapshot(newSnapshotName, 
null, false, onlyPrimary);
 
         assertThrowsWithCause((Callable<Object>)fut1::get, 
IgniteException.class);
 
@@ -897,7 +903,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
         IgniteEx ignite = startGridsWithCache(1, dfltCacheCfg, 
CACHE_KEYS_RANGE);
 
         assertThrowsAnyCause(log,
-            () -> ignite.snapshot().createSnapshot("--№=+.:(snapshot)").get(),
+            () -> snp(ignite).createSnapshot("--№=+.:(snapshot)", null, false, 
onlyPrimary).get(),
             IllegalArgumentException.class,
             "Snapshot name must satisfy the following name pattern: 
a-zA-Z0-9_");
     }
@@ -909,8 +915,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
 
         stopGrid(2);
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME)
-            .get();
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME);
 
         stopAllGrids();
 
@@ -934,7 +939,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
 
         IgniteEx ignite = startGridsWithCache(3, CACHE_KEYS_RANGE, 
Integer::new, ccfg1, ccfg2);
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get();
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME);
 
         waitForEvents(EVT_CLUSTER_SNAPSHOT_STARTED, 
EVT_CLUSTER_SNAPSHOT_FINISHED);
 
@@ -982,7 +987,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
                 });
         }
 
-        IgniteFuture<Void> fut = 
grid(1).snapshot().createSnapshot(SNAPSHOT_NAME);
+        IgniteFuture<Void> fut = snp(grid(1)).createSnapshot(SNAPSHOT_NAME, 
null, false, onlyPrimary);
 
         stopGrid(0);
 
@@ -1024,7 +1029,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
                 .blockMessages((node, msg) -> msg instanceof 
GridDhtPartitionSupplyMessage);
         }
 
-        Ignite ignite = startGrid(2);
+        IgniteEx ignite = startGrid(2);
 
         
ignite.cluster().setBaselineTopology(ignite.cluster().topologyVersion());
 
@@ -1066,7 +1071,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
                 });
         }
 
-        IgniteFuture<Void> fut = 
ignite.snapshot().createSnapshot(SNAPSHOT_NAME);
+        IgniteFuture<Void> fut = snp(ignite).createSnapshot(SNAPSHOT_NAME, 
null, false, onlyPrimary);
 
         stopFut.get();
 
@@ -1115,7 +1120,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
             comps.put(((IgniteEx)ig).localNode().id(), comp);
         }
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get();
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME);
 
         for (Ignite ig : G.allGrids()) {
             ((IgniteEx)ig).context().cache().context().exchange()
@@ -1147,7 +1152,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
         // Yet another non-baseline.
         startGrid(G.allGrids().size());
 
-        snp(nonBaseLineNode).createSnapshot(SNAPSHOT_NAME).get();
+        createAndCheckSnapshot(nonBaseLineNode, SNAPSHOT_NAME);
 
         stopAllGrids();
 
@@ -1164,7 +1169,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
         startGridsWithCache(2, dfltCacheCfg, CACHE_KEYS_RANGE);
         IgniteEx clnt = startClientGrid(2);
 
-        clnt.snapshot().createSnapshot(SNAPSHOT_NAME).get();
+        createAndCheckSnapshot(clnt, SNAPSHOT_NAME);
 
         waitForEvents(EVT_CLUSTER_SNAPSHOT_STARTED, 
EVT_CLUSTER_SNAPSHOT_FINISHED);
 
@@ -1191,10 +1196,10 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
         mgr.localSnapshotSenderFactory((snpName, snpPath) ->
             new DelegateSnapshotSender(log, block, old.apply(snpName, 
snpPath)));
 
-        IgniteFuture<Void> fut = grid.snapshot().createSnapshot(SNAPSHOT_NAME);
+        IgniteFuture<Void> fut = snp(grid).createSnapshot(SNAPSHOT_NAME, null, 
false, onlyPrimary);
 
         assertThrowsAnyCause(log,
-            () -> clnt.snapshot().createSnapshot(SNAPSHOT_NAME).get(),
+            () -> snp(clnt).createSnapshot(SNAPSHOT_NAME, null, false, 
onlyPrimary).get(),
             IgniteException.class,
             "Snapshot has not been created");
 
@@ -1211,7 +1216,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
         stopGrid(0);
 
         assertThrowsAnyCause(log,
-            () -> clnt.snapshot().createSnapshot(SNAPSHOT_NAME).get(),
+            () -> snp(clnt).createSnapshot(SNAPSHOT_NAME, null, false, 
onlyPrimary).get(),
             IgniteException.class,
             "Client disconnected. Snapshot result is unknown");
     }
@@ -1234,7 +1239,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
     public void testClusterSnapshotFinishedTryCancel() throws Exception {
         IgniteEx ignite = startGridsWithCache(2, dfltCacheCfg, 
CACHE_KEYS_RANGE);
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get();
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME);
         ignite.snapshot().cancelSnapshot(SNAPSHOT_NAME).get();
 
         stopAllGrids();
@@ -1249,7 +1254,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
     public void testClientHandlesSnapshotFailOnStartStage() throws Exception {
         int grids = 2;
 
-        Ignite ignite = startGridsWithCache(grids, dfltCacheCfg, 
CACHE_KEYS_RANGE);
+        IgniteEx ignite = startGridsWithCache(grids, dfltCacheCfg, 
CACHE_KEYS_RANGE);
 
         Ignite cln = 
startClientGrid(optimize(getConfiguration(getTestIgniteInstanceName(grids))
             .setCacheConfiguration(dfltCacheCfg))
@@ -1261,7 +1266,7 @@ public class IgniteClusterSnapshotSelfTest extends 
AbstractSnapshotSelfTest {
             msg instanceof SingleNodeMessage
                 && ((SingleNodeMessage<?>)msg).type() == 
DistributedProcess.DistributedProcessType.START_SNAPSHOT.ordinal());
 
-        IgniteFuture<Void> fut = 
ignite.snapshot().createSnapshot(SNAPSHOT_NAME);
+        IgniteFuture<Void> fut = snp(ignite).createSnapshot(SNAPSHOT_NAME, 
null, false, onlyPrimary);
 
         failNodeSpi.waitForBlocked(1, 10_000L);
 
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotStreamerTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotStreamerTest.java
index d159464d2b3..2bc9ce9eea5 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotStreamerTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotStreamerTest.java
@@ -43,6 +43,7 @@ import org.apache.ignite.internal.util.typedef.G;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.testframework.ListeningTestLogger;
 import org.apache.ignite.testframework.LogListener;
+import org.junit.Assume;
 import org.junit.Test;
 
 import static org.apache.ignite.cluster.ClusterState.ACTIVE;
@@ -182,6 +183,8 @@ public class IgniteClusterSnapshotStreamerTest extends 
AbstractSnapshotSelfTest
      */
     @Test
     public void testStreamerFailsLongAgoDefaultClient() throws Exception {
+        Assume.assumeFalse("Test check !onlyPrimary mode", onlyPrimary);
+
         doTestDataStreamerFailedBeforeSnapshot(client, false);
     }
 
@@ -191,6 +194,8 @@ public class IgniteClusterSnapshotStreamerTest extends 
AbstractSnapshotSelfTest
      */
     @Test
     public void testStreamerFailsLongAgoDefaultCoordinator() throws Exception {
+        Assume.assumeFalse("Test !onlyPrimary mode", onlyPrimary);
+
         doTestDataStreamerFailedBeforeSnapshot(grid(0), false);
     }
 
@@ -237,8 +242,12 @@ public class IgniteClusterSnapshotStreamerTest extends 
AbstractSnapshotSelfTest
         IgniteInternalFuture<?> loadFut = runLoad(grid(0), false, stopLoad);
 
         try {
-            assertThrows(null, () -> 
snp(client).createSnapshot(SNAPSHOT_NAME).get(), IgniteException.class,
-                DataStreamerUpdatesHandler.WRN_MSG);
+            assertThrows(
+                null,
+                () -> snp(client).createSnapshot(SNAPSHOT_NAME, null, false, 
onlyPrimary).get(),
+                IgniteException.class,
+                DataStreamerUpdatesHandler.WRN_MSG
+            );
         }
         finally {
             stopLoad.set(true);
@@ -280,7 +289,7 @@ public class IgniteClusterSnapshotStreamerTest extends 
AbstractSnapshotSelfTest
         IgniteInternalFuture<?> loadFut = runLoad(client, false, stop);
 
         try {
-            snp(client).createSnapshot(SNAPSHOT_NAME).get();
+            snp(client).createSnapshot(SNAPSHOT_NAME, null, false, 
onlyPrimary).get();
         }
         finally {
             stop.set(true);
@@ -424,11 +433,11 @@ public class IgniteClusterSnapshotStreamerTest extends 
AbstractSnapshotSelfTest
 
         if (create) {
             if (expWrn == null)
-                snp(snpHnd).createSnapshot(SNAPSHOT_NAME, null, false).get();
+                snp(snpHnd).createSnapshot(SNAPSHOT_NAME, null, false, 
onlyPrimary).get();
             else {
                 Throwable snpWrn = assertThrows(
                     null,
-                    () -> snp(snpHnd).createSnapshot(SNAPSHOT_NAME, null, 
false).get(),
+                    () -> snp(snpHnd).createSnapshot(SNAPSHOT_NAME, null, 
false, onlyPrimary).get(),
                     IgniteException.class,
                     expWrn
                 );
@@ -441,7 +450,9 @@ public class IgniteClusterSnapshotStreamerTest extends 
AbstractSnapshotSelfTest
         SnapshotPartitionsVerifyTaskResult checkRes = 
snp(snpHnd).checkSnapshot(SNAPSHOT_NAME, null).get();
 
         assertTrue(checkRes.exceptions().isEmpty());
-        assertTrue((expWrn != null) == 
checkRes.idleVerifyResult().hasConflicts());
+
+        if (!onlyPrimary)
+            assertTrue((expWrn != null) == 
checkRes.idleVerifyResult().hasConflicts());
 
         if (expWrn != null) {
             ListeningTestLogger testLog = new ListeningTestLogger();
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotWalRecordTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotWalRecordTest.java
index 6db4f0ad006..7b7145df3cf 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotWalRecordTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotWalRecordTest.java
@@ -80,7 +80,7 @@ public class IgniteClusterSnapshotWalRecordTest extends 
AbstractSnapshotSelfTest
                 }
             }, 5, "cache-loader-");
 
-            snp(ign).createSnapshot(SNAPSHOT_NAME).get();
+            snp(ign).createSnapshot(SNAPSHOT_NAME, null, false, 
onlyPrimary).get();
 
             loadStopLatch.countDown();
 
@@ -122,7 +122,7 @@ public class IgniteClusterSnapshotWalRecordTest extends 
AbstractSnapshotSelfTest
 
         for (int i = 0; i < snapshots; i++) {
             // Start changing data concurrently with performing the 
ClusterSnapshot operation.
-            snp(grid(0)).createSnapshot(SNAPSHOT_NAME + i).get();
+            snp(grid(0)).createSnapshot(SNAPSHOT_NAME + i, null, false, 
onlyPrimary).get();
         }
 
         for (int i = 0; i < nodes; i++) {
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotConsistencyTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotConsistencyTest.java
index 3c1dedb3b54..53b4fcb4d09 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotConsistencyTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotConsistencyTest.java
@@ -64,6 +64,7 @@ import static 
org.apache.ignite.internal.GridTopic.TOPIC_CACHE;
 import static org.apache.ignite.internal.TestRecordingCommunicationSpi.spi;
 import static 
org.apache.ignite.internal.processors.cache.distributed.GridCacheModuloAffinityFunction.IDX_ATTR;
 import static 
org.apache.ignite.internal.processors.cache.persistence.snapshot.AbstractSnapshotSelfTest.SNAPSHOT_NAME;
+import static 
org.apache.ignite.internal.processors.cache.persistence.snapshot.AbstractSnapshotSelfTest.snp;
 import static 
org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ;
 
 /** Tests the consistency of taken snapshots across multiple nodes. */
@@ -92,16 +93,22 @@ public class IgniteSnapshotConsistencyTest extends 
GridCommonAbstractTest {
     public TransactionConcurrency txConcurrency;
 
     /** */
-    @Parameterized.Parameters(name = "isClient={0}, atomicity={1}, 
backups={2}, txConcurrency={3}")
+    @Parameterized.Parameter(4)
+    public boolean onlyPrimary;
+
+    /** */
+    @Parameterized.Parameters(name = "isClient={0}, atomicity={1}, 
backups={2}, txConcurrency={3}, onlyPrimayr={4}")
     public static Iterable<Object[]> data() {
         List<Object[]> res = new ArrayList<>();
 
         for (boolean isClient : Arrays.asList(true, false)) {
             for (int backups = 1; backups <= 2; ++backups) {
-                res.add(new Object[] {isClient, ATOMIC, backups, null});
+                for (boolean onlyPrimary : Arrays.asList(true, false)) {
+                    res.add(new Object[]{isClient, ATOMIC, backups, null, 
onlyPrimary});
 
-                for (TransactionConcurrency txConcurrency : 
TransactionConcurrency.values())
-                    res.add(new Object[] {isClient, TRANSACTIONAL, backups, 
txConcurrency});
+                    for (TransactionConcurrency txConcurrency : 
TransactionConcurrency.values())
+                        res.add(new Object[]{isClient, TRANSACTIONAL, backups, 
txConcurrency, onlyPrimary});
+                }
             }
         }
 
@@ -186,7 +193,7 @@ public class IgniteSnapshotConsistencyTest extends 
GridCommonAbstractTest {
             .topologyVersion()
             .nextMinorVersion();
 
-        IgniteFuture<Void> snpFut = 
crd.snapshot().createSnapshot(SNAPSHOT_NAME);
+        IgniteFuture<Void> snpFut = snp(crd).createSnapshot(SNAPSHOT_NAME, 
null, false, onlyPrimary);
 
         
waitForReadyTopology(grid(primaryIdx).cachex(DEFAULT_CACHE_NAME).context().topology(),
 snpTopVer);
 
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotMXBeanTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotMXBeanTest.java
index 74c9d4e9293..375ec60ccd2 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotMXBeanTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotMXBeanTest.java
@@ -134,7 +134,7 @@ public class IgniteSnapshotMXBeanTest extends 
AbstractSnapshotSelfTest {
 
         IgniteEx ignite = startGridsWithCache(2, CACHE_KEYS_RANGE, 
valueBuilder(), dfltCacheCfg);
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME, null, TIMEOUT);
 
         try (IgniteDataStreamer<Integer, Object> ds = 
ignite.dataStreamer(dfltCacheCfg.getName())) {
             for (int i = CACHE_KEYS_RANGE; i < 2 * CACHE_KEYS_RANGE; i++)
@@ -225,7 +225,7 @@ public class IgniteSnapshotMXBeanTest extends 
AbstractSnapshotSelfTest {
 
         spi.blockMessages((node, msg) -> msg instanceof SingleNodeMessage);
 
-        IgniteFuture<Void> fut = srv.snapshot().createSnapshot(SNAPSHOT_NAME);
+        IgniteFuture<Void> fut = snp(srv).createSnapshot(SNAPSHOT_NAME, null, 
false, onlyPrimary);
 
         spi.waitForBlocked();
 
@@ -235,6 +235,8 @@ public class IgniteSnapshotMXBeanTest extends 
AbstractSnapshotSelfTest {
 
         fut.get(getTestTimeout());
 
+        checkSnapshot(SNAPSHOT_NAME, null);
+
         checkSnapshotStatus(false, false, false, null);
 
         // Create incremental snapshot.
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotManagerSelfTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotManagerSelfTest.java
index 59923bebe08..79b3699b6b0 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotManagerSelfTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotManagerSelfTest.java
@@ -381,7 +381,7 @@ public class IgniteSnapshotManagerSelfTest extends 
AbstractSnapshotSelfTest {
 
         fut.get();
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get();
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME);
 
         Map<Integer, Value> iterated = new HashMap<>();
 
@@ -425,7 +425,9 @@ public class IgniteSnapshotManagerSelfTest extends 
AbstractSnapshotSelfTest {
         IgniteEx ignite = startGridsWithCache(2,
             dfltCacheCfg.setAffinity(new RendezvousAffinityFunction(false, 
1)), keys);
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get();
+        ignite = 
grid(ignite.affinity(dfltCacheCfg.getName()).mapPartitionToNode(0));
+
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME);
 
         int rows = 0;
 
@@ -466,16 +468,20 @@ public class IgniteSnapshotManagerSelfTest extends 
AbstractSnapshotSelfTest {
         for (int i = 0; i < keys; i++)
             ignite.getOrCreateCache(ccfg).put(i, new Value(new 
byte[SIZE_FOR_FIT_3_PAGES]));
 
+        int part = 0;
+
+        ignite = 
grid(ignite.affinity(ccfg.getName()).mapPartitionToNode(part));
+
         forceCheckpoint();
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get();
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME);
 
         int rows = 0;
 
         try (GridCloseableIterator<CacheDataRow> iter = 
snp(ignite).partitionRowIterator(SNAPSHOT_NAME,
             ignite.context().pdsFolderResolver().resolveFolders().folderName(),
             dfltCacheCfg.getName(),
-            0,
+            part,
             ignite.context().encryption())
         ) {
             CacheObjectContext coctx = 
ignite.cachex(dfltCacheCfg.getName()).context().cacheObjectContext();
@@ -540,7 +546,7 @@ public class IgniteSnapshotManagerSelfTest extends 
AbstractSnapshotSelfTest {
 
         beforeCpEnter.await(testTimeout, TimeUnit.MILLISECONDS);
 
-        IgniteFuture<Void> snpFut = 
ignite.snapshot().createSnapshot(SNAPSHOT_NAME);
+        IgniteFuture<Void> snpFut = snp(ignite).createSnapshot(SNAPSHOT_NAME, 
null, false, onlyPrimary);
 
         // Wait until the snapshot task checkpoint listener is registered.
         assertTrue(GridTestUtils.waitForCondition(lsnr::check, testTimeout));
@@ -550,6 +556,8 @@ public class IgniteSnapshotManagerSelfTest extends 
AbstractSnapshotSelfTest {
 
         // Make sure the snapshot has been taken.
         snpFut.get(testTimeout);
+
+        checkSnapshot(SNAPSHOT_NAME, null);
     }
 
     /** @throws Exception If fails. */
@@ -559,7 +567,7 @@ public class IgniteSnapshotManagerSelfTest extends 
AbstractSnapshotSelfTest {
 
         IgniteEx ig = startGridWithCache(dfltCacheCfg, CACHE_KEYS_RANGE);
 
-        ig.snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(ig, SNAPSHOT_NAME, null, TIMEOUT);
 
         ThreadMXBean tMb = ManagementFactory.getThreadMXBean();
 
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotRemoteRequestTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotRemoteRequestTest.java
index d8ba7f108cd..d452ebb4d5d 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotRemoteRequestTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotRemoteRequestTest.java
@@ -81,7 +81,7 @@ public class IgniteSnapshotRemoteRequestTest extends 
IgniteClusterSnapshotRestor
 
         IgniteEx ignite = startGridsWithCache(2, CACHE_KEYS_RANGE, 
valueBuilder(), dfltCacheCfg);
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME, null, TIMEOUT);
 
         Map<Integer, Set<Integer>> parts = owningParts(ignite, 
CU.cacheId(DEFAULT_CACHE_NAME), grid(1).localNode().id());
 
@@ -125,7 +125,7 @@ public class IgniteSnapshotRemoteRequestTest extends 
IgniteClusterSnapshotRestor
     public void testSnapshotRemoteRequestEachOther() throws Exception {
         IgniteEx ignite = startGridsWithCache(2, CACHE_KEYS_RANGE, 
valueBuilder(), dfltCacheCfg);
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME, null, TIMEOUT);
 
         IgniteSnapshotManager mgr0 = snp(ignite);
         IgniteSnapshotManager mgr1 = snp(grid(1));
@@ -161,7 +161,7 @@ public class IgniteSnapshotRemoteRequestTest extends 
IgniteClusterSnapshotRestor
     public void testRemoteRequestedInitiatorNodeLeft() throws Exception {
         IgniteEx ignite = startGridsWithCache(2, CACHE_KEYS_RANGE, 
valueBuilder(), dfltCacheCfg);
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME, null, TIMEOUT);
 
         awaitPartitionMapExchange();
 
@@ -228,7 +228,7 @@ public class IgniteSnapshotRemoteRequestTest extends 
IgniteClusterSnapshotRestor
     public void testSnapshotRequestRemoteSourceNodeLeft() throws Exception {
         IgniteEx ignite = startGridsWithCache(2, CACHE_KEYS_RANGE, 
valueBuilder(), dfltCacheCfg);
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME, null, TIMEOUT);
 
         Map<Integer, Set<Integer>> parts = owningParts(ignite, 
CU.cacheId(DEFAULT_CACHE_NAME),
             grid(1).localNode().id());
@@ -275,7 +275,7 @@ public class IgniteSnapshotRemoteRequestTest extends 
IgniteClusterSnapshotRestor
     public void testSnapshotRequestRemoteCancel() throws Exception {
         IgniteEx ignite = startGridsWithCache(2, CACHE_KEYS_RANGE, 
valueBuilder(), dfltCacheCfg);
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME, null, TIMEOUT);
 
         Map<Integer, Set<Integer>> parts = owningParts(ignite, 
CU.cacheId(DEFAULT_CACHE_NAME),
             grid(1).localNode().id());
@@ -331,7 +331,7 @@ public class IgniteSnapshotRemoteRequestTest extends 
IgniteClusterSnapshotRestor
 
         UUID sndNode = sndr.localNode().id();
 
-        sndr.snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(sndr, SNAPSHOT_NAME, null, TIMEOUT);
 
         IgniteSnapshotManager mgr0 = snp(grid(0));
 
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 783b17055b4..822efe4a67f 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
@@ -144,7 +144,7 @@ public class IgniteSnapshotRestoreFromRemoteTest extends 
IgniteClusterSnapshotRe
             IgniteEx ignite = 
startDedicatedGridsWithCache(FIRST_CLUSTER_PREFIX, GRIDS, CACHE_KEYS_RANGE, 
valBuilder,
                 dfltCacheCfg.setBackups(0), cacheCfg1, cacheCfg2, cacheCfg3);
 
-            ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+            createAndCheckSnapshot(ignite, SNAPSHOT_NAME, null, TIMEOUT);
 
             awaitPartitionMapExchange();
             stopAllGrids();
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotWithMetastorageTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotWithMetastorageTest.java
index 6781c2e31d2..61dc076124f 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotWithMetastorageTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotWithMetastorageTest.java
@@ -66,7 +66,7 @@ public class IgniteSnapshotWithMetastorageTest extends 
AbstractSnapshotSelfTest
 
         ignite.context().distributedMetastorage().write("key", "value");
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get();
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME);
 
         stopAllGrids();
 
@@ -118,7 +118,7 @@ public class IgniteSnapshotWithMetastorageTest extends 
AbstractSnapshotSelfTest
                 }
             });
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get();
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME);
 
         stop.set(true);
         updFut.get();
@@ -183,7 +183,7 @@ public class IgniteSnapshotWithMetastorageTest extends 
AbstractSnapshotSelfTest
                 }
             });
 
-        IgniteFuture<?> fut = ignite.snapshot().createSnapshot(SNAPSHOT_NAME);
+        IgniteFuture<?> fut = snp(ignite).createSnapshot(SNAPSHOT_NAME, null, 
false, onlyPrimary);
 
         GridTestUtils.assertThrowsAnyCause(log, fut::get, 
IgniteCheckedException.class, "Test exception");
 
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IncrementalSnapshotTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IncrementalSnapshotTest.java
index fcb04783e68..cd3d7df1239 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IncrementalSnapshotTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IncrementalSnapshotTest.java
@@ -109,10 +109,11 @@ public class IncrementalSnapshotTest extends 
AbstractSnapshotSelfTest {
 
                 String snpName = SNAPSHOT_NAME + "_" + client + "_" + (snpPath 
== null ? "" : snpPath.getName());
 
-                if (snpPath == null)
-                    snpCreate.createSnapshot(snpName).get(TIMEOUT);
-                else
-                    snpCreate.createSnapshot(snpName, 
snpPath.getAbsolutePath(), false).get(TIMEOUT);
+                snpCreate
+                    .createSnapshot(snpName, snpPath == null ? null : 
snpPath.getAbsolutePath(), false, onlyPrimary)
+                    .get(TIMEOUT);
+
+                checkSnapshot(snpName, snpPath == null ? null : 
snpPath.getAbsolutePath());
 
                 for (int incIdx = 1; incIdx < 3; incIdx++) {
                     addData(cli);
@@ -120,7 +121,7 @@ public class IncrementalSnapshotTest extends 
AbstractSnapshotSelfTest {
                     if (snpPath == null)
                         
snpCreate.createIncrementalSnapshot(snpName).get(TIMEOUT);
                     else
-                        snpCreate.createSnapshot(snpName, 
snpPath.getAbsolutePath(), true).get(TIMEOUT);
+                        snpCreate.createSnapshot(snpName, 
snpPath.getAbsolutePath(), true, false).get(TIMEOUT);
 
                     for (int gridIdx = 0; gridIdx < GRID_CNT; gridIdx++) {
                         assertTrue("Incremental snapshot must exists on node " 
+ gridIdx, checkIncremental(
@@ -161,7 +162,7 @@ public class IncrementalSnapshotTest extends 
AbstractSnapshotSelfTest {
             IgniteException.class
         );
 
-        snp(ign).createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(ign, SNAPSHOT_NAME, null, TIMEOUT);
 
         assertThrowsWithCause(
             () -> snp(ign).createIncrementalSnapshot("unknown").get(TIMEOUT),
@@ -187,7 +188,7 @@ public class IncrementalSnapshotTest extends 
AbstractSnapshotSelfTest {
                 cfg -> cfg.setCacheConfiguration(new 
CacheConfiguration<>(DEFAULT_CACHE_NAME))
         );
 
-        cli.snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(cli, SNAPSHOT_NAME, null, TIMEOUT);
 
         cli.snapshot().createIncrementalSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
         cli.snapshot().createIncrementalSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
@@ -218,7 +219,7 @@ public class IncrementalSnapshotTest extends 
AbstractSnapshotSelfTest {
             new CacheConfiguration<>(DEFAULT_CACHE_NAME)
         );
 
-        srv.snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(srv, SNAPSHOT_NAME, null, TIMEOUT);
 
         addData(srv);
 
@@ -250,7 +251,7 @@ public class IncrementalSnapshotTest extends 
AbstractSnapshotSelfTest {
 
         IgniteSnapshotManager snpCreate = snp(srv);
 
-        snpCreate.createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(srv, SNAPSHOT_NAME, null, TIMEOUT);
 
         String consId = 
grid(1).context().discovery().localNode().consistentId().toString();
 
@@ -293,7 +294,7 @@ public class IncrementalSnapshotTest extends 
AbstractSnapshotSelfTest {
 
         IgniteEx srv = startGridsWithCache(1, CACHE_KEYS_RANGE, key -> new 
Account(key, key), ccfg);
 
-        snp(srv).createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(srv, SNAPSHOT_NAME, null, TIMEOUT);
 
         GridLocalConfigManager locCfgMgr = 
srv.context().cache().configManager();
 
@@ -327,7 +328,7 @@ public class IncrementalSnapshotTest extends 
AbstractSnapshotSelfTest {
             new CacheConfiguration<>(DEFAULT_CACHE_NAME)
         );
 
-        snp(srv).createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(srv, SNAPSHOT_NAME, null, TIMEOUT);
 
         assertTrue(snp(srv).incrementalSnapshotsLocalRootDir(SNAPSHOT_NAME, 
null).mkdirs());
         assertTrue(snp(srv).incrementalSnapshotLocalDir(SNAPSHOT_NAME, null, 
1).createNewFile());
@@ -358,7 +359,7 @@ public class IncrementalSnapshotTest extends 
AbstractSnapshotSelfTest {
                 new CacheConfiguration<>(DEFAULT_CACHE_NAME)
             );
 
-            srv.snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+            createAndCheckSnapshot(srv, SNAPSHOT_NAME, null, TIMEOUT);
 
             assertThrows(
                 null,
@@ -387,7 +388,7 @@ public class IncrementalSnapshotTest extends 
AbstractSnapshotSelfTest {
 
         IgniteSnapshotManager snpCreate = snp(srv);
 
-        snpCreate.createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(srv, SNAPSHOT_NAME, null, TIMEOUT);
 
         snpCreate.createIncrementalSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
 
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/PlainSnapshotTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/PlainSnapshotTest.java
index c916610a758..0d18214bb2a 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/PlainSnapshotTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/PlainSnapshotTest.java
@@ -18,7 +18,8 @@
 package org.apache.ignite.internal.processors.cache.persistence.snapshot;
 
 import java.io.File;
-import java.util.Collections;
+import java.util.Arrays;
+import java.util.List;
 import java.util.Map;
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.configuration.CacheConfiguration;
@@ -47,9 +48,12 @@ import static 
org.apache.ignite.testframework.GridTestUtils.assertThrowsAnyCause
  */
 public class PlainSnapshotTest extends AbstractSnapshotSelfTest {
     /** Parameters. */
-    @Parameterized.Parameters(name = "Encryption is disabled.")
-    public static Iterable<Boolean> disableEncryption() {
-        return Collections.singletonList(false);
+    @Parameterized.Parameters(name = "encryption={0}, onlyPrimay={1}")
+    public static List<Object[]> disableEncryption() {
+        return Arrays.asList(
+            new Object[]{false, false},
+            new Object[]{false, true}
+        );
     }
 
     /** {@link AbstractSnapshotSelfTest.Account} with custom toString method. 
*/
@@ -151,7 +155,7 @@ public class PlainSnapshotTest extends 
AbstractSnapshotSelfTest {
 
         IgniteEx clnt = startClientGrid(1);
 
-        IgniteFuture<?> fut = clnt.snapshot().createSnapshot(SNAPSHOT_NAME);
+        IgniteFuture<?> fut = snp(clnt).createSnapshot(SNAPSHOT_NAME, null, 
false, onlyPrimary);
 
         assertThrowsAnyCause(log,
             fut::get,
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 bc35aed2012..1ebae1956e9 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
@@ -316,8 +316,8 @@ public class IncrementalSnapshotCheckBeforeRestoreTest 
extends AbstractSnapshotS
     }
 
     /** */
-    private void createFullSnapshot() {
-        snp(grid(0)).createSnapshot(SNP).get(TIMEOUT);
+    private void createFullSnapshot() throws IgniteCheckedException {
+        createAndCheckSnapshot(grid(0), SNP);
     }
 
     /** */
diff --git 
a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
 
b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
index 85ecc10ea59..d7a8f235e53 100755
--- 
a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
@@ -1785,16 +1785,16 @@ public abstract class GridAbstractTest extends 
JUnitAssertAware {
      * @param node Node.
      * @return Ignite instance with given local node.
      */
-    protected final Ignite grid(ClusterNode node) {
+    protected final IgniteEx grid(ClusterNode node) {
         if (!isMultiJvm())
-            return G.ignite(node.id());
+            return (IgniteEx)G.ignite(node.id());
         else {
             try {
-                return IgniteProcessProxy.ignite(node.id());
+                return (IgniteEx)IgniteProcessProxy.ignite(node.id());
             }
             catch (Exception ignore) {
                 // A hack if it is local grid.
-                return G.ignite(node.id());
+                return (IgniteEx)G.ignite(node.id());
             }
         }
     }
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotCheckWithIndexesTest.java
 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotCheckWithIndexesTest.java
index 81aee9f691a..6f6c160884d 100644
--- 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotCheckWithIndexesTest.java
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotCheckWithIndexesTest.java
@@ -42,7 +42,7 @@ public class IgniteClusterSnapshotCheckWithIndexesTest 
extends AbstractSnapshotS
         IgniteEx ignite = startGridsWithCache(3, 0, key -> new Account(key, 
key),
             txFilteredCache("indexed"));
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        snp(ignite).createSnapshot(SNAPSHOT_NAME, null, false, 
onlyPrimary).get(TIMEOUT);
 
         IdleVerifyResultV2 res = 
ignite.context().cache().context().snapshotMgr()
             .checkSnapshot(SNAPSHOT_NAME, null).get().idleVerifyResult();
@@ -60,7 +60,7 @@ public class IgniteClusterSnapshotCheckWithIndexesTest 
extends AbstractSnapshotS
         IgniteEx ignite = startGridsWithCache(3, CACHE_KEYS_RANGE, key -> new 
Account(key, key),
             txFilteredCache("indexed"));
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(ignite, SNAPSHOT_NAME, null, TIMEOUT);
 
         IdleVerifyResultV2 res = 
ignite.context().cache().context().snapshotMgr()
             .checkSnapshot(SNAPSHOT_NAME, null).get().idleVerifyResult();
@@ -87,7 +87,7 @@ public class IgniteClusterSnapshotCheckWithIndexesTest 
extends AbstractSnapshotS
             cache2.put(i, new Account(i, i));
         }
 
-        grid(0).snapshot().createSnapshot(SNAPSHOT_NAME).get(TIMEOUT);
+        createAndCheckSnapshot(grid(0), SNAPSHOT_NAME, null, TIMEOUT);
 
         IdleVerifyResultV2 res = 
grid(0).context().cache().context().snapshotMgr()
             .checkSnapshot(SNAPSHOT_NAME, null).get().idleVerifyResult();
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotMetricsTest.java
 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotMetricsTest.java
index 20fee765358..4ba805c6fd0 100644
--- 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotMetricsTest.java
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotMetricsTest.java
@@ -28,6 +28,7 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicBoolean;
 import javax.management.AttributeNotFoundException;
 import javax.management.DynamicMBean;
 import javax.management.MBeanException;
@@ -186,16 +187,21 @@ public class IgniteClusterSnapshotMetricsTest extends 
IgniteClusterSnapshotResto
         IgniteEx ignite = startGridsWithSnapshot(2, CACHE_KEYS_RANGE);
 
         String failingFilePath = 
Paths.get(FilePageStoreManager.cacheDirName(dfltCacheCfg),
-            PART_FILE_PREFIX + (dfltCacheCfg.getAffinity().partitions() / 2) + 
FILE_SUFFIX).toString();
+            PART_FILE_PREFIX + primaries[0] + FILE_SUFFIX).toString();
 
         FileIOFactory ioFactory = new RandomAccessFileIOFactory();
         String testErrMsg = "Test exception";
 
+        AtomicBoolean failFlag = new AtomicBoolean();
+
         ignite.context().cache().context().snapshotMgr().ioFactory((file, 
modes) -> {
             FileIO delegate = ioFactory.create(file, modes);
 
-            if (file.getPath().endsWith(failingFilePath))
+            if (file.getPath().endsWith(failingFilePath)) {
+                failFlag.set(true);
+
                 throw new RuntimeException(testErrMsg);
+            }
 
             return delegate;
         });
@@ -222,6 +228,8 @@ public class IgniteClusterSnapshotMetricsTest extends 
IgniteClusterSnapshotResto
             assertTrue(nodeNameMsg, endTime >= startTime);
             assertTrue(nodeNameMsg, 
((String)mReg.getAttribute("error")).contains(testErrMsg));
         }
+
+        assertTrue(failFlag.get());
     }
 
     /** @throws Exception If fails. */
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotRestoreWithIndexingTest.java
 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotRestoreWithIndexingTest.java
index e1bc45dbef6..b8ebe10a7d2 100644
--- 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotRestoreWithIndexingTest.java
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotRestoreWithIndexingTest.java
@@ -76,8 +76,13 @@ public class IgniteClusterSnapshotRestoreWithIndexingTest 
extends IgniteClusterS
 
         grid(0).snapshot().restoreSnapshot(SNAPSHOT_NAME, 
Collections.singleton(DEFAULT_CACHE_NAME)).get(TIMEOUT);
 
+        // Only primary mode leads to index rebuild on restore.
+        // Must wait until index rebuild finish so subsequent checks will pass.
+        if (onlyPrimary)
+            awaitPartitionMapExchange();
+
         assertCacheKeys(client.cache(DEFAULT_CACHE_NAME), CACHE_KEYS_RANGE);
-        assertRebuildIndexes(client.cache(DEFAULT_CACHE_NAME), false);
+        assertRebuildIndexes(client.cache(DEFAULT_CACHE_NAME), onlyPrimary);
 
         waitForEvents(EVT_CLUSTER_SNAPSHOT_RESTORE_STARTED, 
EVT_CLUSTER_SNAPSHOT_RESTORE_FINISHED);
     }
@@ -98,8 +103,13 @@ public class IgniteClusterSnapshotRestoreWithIndexingTest 
extends IgniteClusterS
 
         ignite.snapshot().restoreSnapshot(SNAPSHOT_NAME, 
Collections.singleton(DEFAULT_CACHE_NAME)).get(TIMEOUT);
 
+        // Only primary mode leads to index rebuild on restore.
+        // Must wait until index rebuild finish so subsequent checks will pass.
+        if (onlyPrimary)
+            awaitPartitionMapExchange();
+
         assertCacheKeys(ignite.cache(DEFAULT_CACHE_NAME).withKeepBinary(), 
CACHE_KEYS_RANGE);
-        
assertRebuildIndexes(ignite.cache(DEFAULT_CACHE_NAME).withKeepBinary(), false);
+        
assertRebuildIndexes(ignite.cache(DEFAULT_CACHE_NAME).withKeepBinary(), 
onlyPrimary);
 
         for (Ignite grid : G.allGrids())
             
assertNotNull(((IgniteEx)grid).context().cacheObjects().metadata(typeId));
@@ -197,6 +207,9 @@ public class IgniteClusterSnapshotRestoreWithIndexingTest 
extends IgniteClusterS
 
             assertTrue("nodeId=" + ctx.localNodeId(), 
grid.cache(cache.getName()).indexReadyFuture().isDone());
 
+            if (grid.configuration().isClientMode())
+                continue;
+
             // Make sure no index rebuild happened.
             assertEquals("nodeId=" + ctx.localNodeId(),
                 rebuild, 
ctx.cache().cache(cache.getName()).context().cache().metrics0()
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotWithIndexesTest.java
 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotWithIndexesTest.java
index 3c7e1444b21..838887be5ec 100644
--- 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotWithIndexesTest.java
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteClusterSnapshotWithIndexesTest.java
@@ -81,13 +81,18 @@ public class IgniteClusterSnapshotWithIndexesTest extends 
AbstractSnapshotSelfTe
         assertEquals(CACHE_KEYS_RANGE, 
rowsCount(executeSql(ignite.context().cache().jcache(indexedCcfg.getName()),
             selectStartSQLStatement(Account.class.getSimpleName()))));
 
-        ignite.snapshot().createSnapshot(SNAPSHOT_NAME)
+        snp(ignite).createSnapshot(SNAPSHOT_NAME, null, false, onlyPrimary)
             .get();
 
         stopAllGrids();
 
         IgniteEx snp = startGridsFromSnapshot(3, SNAPSHOT_NAME);
 
+        // Only primary mode leads to index rebuild on restore.
+        // Must wait until index rebuild finish so subsequent checks will pass.
+        if (onlyPrimary)
+            awaitPartitionMapExchange();
+
         
assertTrue(snp.cache(indexedCcfg.getName()).indexReadyFuture().isDone());
         assertTrue(snp.cache(tblName).indexReadyFuture().isDone());
 
@@ -141,7 +146,7 @@ public class IgniteClusterSnapshotWithIndexesTest extends 
AbstractSnapshotSelfTe
         // Blocking configuration local snapshot sender.
         List<BlockingExecutor> execs = 
setBlockingSnapshotExecutor(G.allGrids());
 
-        IgniteFuture<Void> fut = 
ignite.snapshot().createSnapshot(SNAPSHOT_NAME);
+        IgniteFuture<Void> fut = snp(ignite).createSnapshot(SNAPSHOT_NAME, 
null, false, onlyPrimary);
 
         List<String> idxNames = Arrays.asList("SNP_IDX_1", "SNP_IDX_2");
 

Reply via email to