Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
fa2412e
raw
Vladsz83 Aug 31, 2026
8d2c035
Merge branch 'master' into IGNITE-19034-snp-check-status
Vladsz83 Aug 31, 2026
19dde26
in-progress
Vladsz83 Aug 31, 2026
77fa5ed
Merge branch 'master' into IGNITE-19034-snp-check-status
Vladsz83 Sep 1, 2026
f18d2fc
raw
Vladsz83 Sep 1, 2026
dfe63ee
raw
Vladsz83 Sep 1, 2026
befe265
Merge remote-tracking branch 'my/IGNITE-19034-snp-check-status' into …
Vladsz83 Sep 1, 2026
4007c15
test fixes
Vladsz83 Sep 1, 2026
e8d79ea
test fixes
Vladsz83 Sep 1, 2026
a57d800
test fixes
Vladsz83 Sep 1, 2026
0f2302b
Merge remote-tracking branch 'my/IGNITE-19034-snp-check-status' into …
Vladsz83 Sep 1, 2026
375edb4
test fixes
Vladsz83 Sep 2, 2026
4f18f1b
tets fixes
Vladsz83 Sep 2, 2026
89e50c8
test fixes
Vladsz83 Sep 2, 2026
5e91a93
extended tests
Vladsz83 Sep 2, 2026
ab62f2d
minority
Vladsz83 Sep 2, 2026
c223b8f
fix
Vladsz83 Sep 2, 2026
f6210c2
Merge branch 'master' into IGNITE-19034-snp-check-status
Vladsz83 Sep 2, 2026
77dbb35
+ taskV2 for thin client
Vladsz83 Sep 2, 2026
65addb2
minor
Vladsz83 Sep 2, 2026
0b534fe
fixes, + check status test
Vladsz83 Sep 3, 2026
215c7dd
+ incremental snp test
Vladsz83 Sep 3, 2026
bd8a9fd
Merge branch 'master' into IGNITE-19034-VisorSnapshotStatusTask-retur…
Vladsz83 Sep 4, 2026
93a442e
review fixes
Vladsz83 Sep 4, 2026
1bc87c3
review fixes
Vladsz83 Sep 4, 2026
e385404
Merge remote-tracking branch 'my/IGNITE-19034-snp-check-status' into …
Vladsz83 Sep 4, 2026
c13083a
minor doc fix
Vladsz83 Sep 4, 2026
212ee80
Merge branch 'master' into IGNITE-19034-snp-check-status
Vladsz83 Oct 14, 2026
9bfe62a
+ master, fix
Vladsz83 Oct 14, 2026
4f93605
+ master, fix
Vladsz83 Oct 14, 2026
e9ba27a
reimpls iof teh result
Vladsz83 Oct 15, 2026
79fb992
reimppl iof teh result in progress
Vladsz83 Oct 15, 2026
3f4fd75
Merge remote-tracking branch 'my/IGNITE-19034-snp-check-status' into …
Vladsz83 Oct 15, 2026
84ace45
compiled + checkstyle
Vladsz83 Oct 15, 2026
651581e
checkstyle
Vladsz83 Oct 15, 2026
afc0fd6
Merge branch 'master' into IGNITE-19034-snp-check-status-dedicatedRes…
Vladsz83 Oct 16, 2026
ff3fa14
Merge branch 'master' into IGNITE-19034-snp-check-status
Vladsz83 Oct 19, 2026
075c217
+ master
Vladsz83 Oct 19, 2026
0a2f1a1
Merge branch 'master' into IGNITE-19034-snp-check-status-dedicatedRes…
Vladsz83 Oct 19, 2026
1606fea
in progress
Vladsz83 Oct 19, 2026
086a468
reimpl result
Vladsz83 Oct 19, 2026
1dc3b87
Merge branch 'IGNITE-19034-snp-check-status-dedicatedResults' into IG…
Vladsz83 Oct 19, 2026
50467cb
fixes
Vladsz83 Oct 20, 2026
f910f8a
Merge branch 'master' into IGNITE-19034-snp-check-status
Vladsz83 Oct 21, 2026
e66a50d
Merge branch 'master' into IGNITE-19034-snp-check-status
Vladsz83 Oct 27, 2026
0107acb
Merge remote-tracking branch 'my/IGNITE-19034-snp-check-status' into …
Vladsz83 Oct 27, 2026
8439695
Merge remote-tracking branch 'my/IGNITE-19034-snp-check-status' into …
Vladsz83 Oct 27, 2026
9fef05b
Merge branch 'master' into IGNITE-19034-snp-check-status
Vladsz83 Oct 28, 2026
c01455d
to idtos
Vladsz83 Oct 28, 2026
d466ca3
mxbean test fix
Vladsz83 Oct 29, 2026
3c73806
fixing
Vladsz83 Oct 29, 2026
bca841c
in progress
Vladsz83 Oct 29, 2026
60e2efe
fixing
Vladsz83 Oct 29, 2026
1cadd2a
fixing
Vladsz83 Oct 29, 2026
22c5586
Merge branch 'master' into IGNITE-19034-VisorSnapshotStatusTask-retur…
Vladsz83 Oct 29, 2026
9ee9bd9
Merge remote-tracking branch 'my/IGNITE-19034-VisorSnapshotStatusTask…
Vladsz83 Oct 29, 2026
1cbfe21
LLM review fixes
Vladsz83 Oct 29, 2026
153ef53
merge dev branch
Vladsz83 Oct 29, 2026
ed55241
Merge branch 'master' into IGNITE-19034-VisorSnapshotStatusTask-retur…
Vladsz83 Oct 29, 2026
f35bd49
Merge branch 'IGNITE-19034-VisorSnapshotStatusTask-returns-empty-resu…
Vladsz83 Oct 29, 2026
6178845
better test
Vladsz83 Oct 29, 2026
2d14d0e
manual review fixes
Vladsz83 Oct 30, 2026
7c25ead
manual review fixes
Vladsz83 Oct 30, 2026
977708b
Merge remote-tracking branch 'my/IGNITE-19034-snp-check-status' into …
Vladsz83 Oct 30, 2026
3e270e0
renaming
Vladsz83 Oct 30, 2026
e3d7c2f
fixes
Vladsz83 Oct 31, 2026
6610d8b
fixes, same rqId
Vladsz83 Oct 31, 2026
4504ec0
fixes in progress
Vladsz83 Oct 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/_docs/monitoring-metrics/new-metrics.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -684,13 +684,13 @@ Register name: `snapshot-restore`
[cols="2,1,3",opts="header"]
|===
|Name | Type | Description
|requestId | string | The request ID of the last running cluster snapshot restore operation on this node.
|endTime | long | The system time when the restore operation of a cluster snapshot on this node ended.
|error | string | Error message of the last running cluster snapshot restore operation on this node.
|incrementIndex | integer | The index of incremental snapshot of the last snapshot restore operation on this node.
|processedPartitions | integer | The number of processed partitions on this node.
|processedWalEntries | long | The number of processed entries from incremental snapshot on this node.
|processedWalSegments | integer | The number of processed WAL segments in the incremental snapshot on this node.
|requestId | string | The request ID of the last running cluster snapshot restore operation on this node.
|snapshotName | string | The snapshot name of the last running cluster snapshot restore operation on this node.
|startTime | long | The system time of the start of the cluster snapshot restore operation on this node.
|totalPartitions | integer | The total number of partitions to be restored on this node.
Expand All @@ -706,6 +706,8 @@ Register name: `snapshot-check.{snapshot_name}`
[cols="2,1,3",opts="header"]
|===
|Name | Type | Description
|requestId | string | The request ID of the last running cluster snapshot check operation on this node.
If snapshot is checked as part of the restoration operation, it has the same request ID.
|checkPartitions | boolean | Shows whether full validation of snapshot partitions is enabled.
|incrementIndex | integer | The index of incremental snapshot of the snapshot check operation.
|processedPartitions | integer | The number of checked partitions on current node.
Expand Down
24 changes: 11 additions & 13 deletions docs/_docs/snapshots/snapshots.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -371,35 +371,33 @@ If the metadata isn't found or cannot be read, snapshot isn't deleted.

== Getting Snapshot Operation Status

The status of the create/restore snapshot operations in the cluster can be obtained using the `control.sh|bat` script or JMX interface:
The status of the create/restore snapshot operations in the cluster can be obtained using the `control.sh|bat` script.

[tabs]
--
tab:Unix[]
[source,shell]
----
# Get the status of the snapshot operation.
# Get the status of snapshot operation.
control.sh --snapshot status
----

tab:Windows[]
[source,shell]
----
# Get the status of the snapshot operation.
# Get the status of snapshot operation.
control.bat --snapshot status
----

tab:JMX[]
You can also get the current snapshot status via the `SnapshotMXBean` interface:
[source,java]
----
SnapshotMXBean mxBean = ...;

// The status of a current snapshot operation in the cluster.
String status = mxBean.status();
----
--

[NOTE]
====
Multiple snapshot check operations can run concurrently with any other snapshot operation of another snapshot.
Only one check can be running for the same snapshot at a time. Create and restore operations cannot run in parallel —
only one of them can be active at a time. The status is printed for each running snapshot operation (if multiple) separately,
one after another.
====

== Cancelling Snapshot Operation

To abort create/restore snapshot operation you need to obtain an `operation request ID`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
import org.apache.ignite.internal.management.cache.FindAndDeleteGarbageInPersistenceTaskResult;
import org.apache.ignite.internal.management.cache.IdleVerifyDumpTask;
import org.apache.ignite.internal.management.cache.VerifyBackupPartitionsTask;
import org.apache.ignite.internal.management.snapshot.SnapshotStatusCommand;
import org.apache.ignite.internal.management.tx.TxInfo;
import org.apache.ignite.internal.management.tx.TxTaskResult;
import org.apache.ignite.internal.managers.communication.GridIoMessage;
Expand Down Expand Up @@ -121,6 +122,7 @@
import org.apache.ignite.internal.util.distributed.DistributedProcess;
import org.apache.ignite.internal.util.distributed.SingleNodeMessage;
import org.apache.ignite.internal.util.future.IgniteFinishedFutureImpl;
import org.apache.ignite.internal.util.future.IgniteFutureImpl;
import org.apache.ignite.internal.util.lang.GridAbsPredicate;
import org.apache.ignite.internal.util.lang.GridFunc;
import org.apache.ignite.internal.util.typedef.F;
Expand Down Expand Up @@ -182,6 +184,8 @@
import static org.apache.ignite.internal.processors.diagnostic.DiagnosticProcessor.DEFAULT_TARGET_FOLDER;
import static org.apache.ignite.internal.processors.job.GridJobProcessor.JOBS_VIEW;
import static org.apache.ignite.internal.processors.task.GridTaskProcessor.TASKS_VIEW;
import static org.apache.ignite.internal.util.distributed.DistributedProcess.DistributedProcessType.CHECK_SNAPSHOT_PARTS;
import static org.apache.ignite.internal.util.distributed.DistributedProcess.DistributedProcessType.END_SNAPSHOT;
import static org.apache.ignite.internal.util.distributed.DistributedProcess.DistributedProcessType.RESTORE_CACHE_GROUP_SNAPSHOT_PREPARE;
import static org.apache.ignite.testframework.GridTestUtils.assertContains;
import static org.apache.ignite.testframework.GridTestUtils.assertNotContains;
Expand Down Expand Up @@ -3653,11 +3657,257 @@ public void testSnapshotRestoreCancelAndStatus() throws Exception {
assertTrue(ctxDisposed);

assertEquals(EXIT_CODE_OK, execute("--snapshot", "status"));
assertContains(log, testOut.toString(), "There is no create or restore snapshot operation in progress.");
assertContains(log, testOut.toString(), SnapshotStatusCommand.NO_SNP_OP_IN_PROGRESS_MSG);

assertNull(ig.cache(DEFAULT_CACHE_NAME));
}

/** Tests that snapshot status isn't empty when being restored snapshot waits for the check process. */
@Test
public void testRestoreSnapshotStatusAtStart() throws Exception {
startGrids(3).cluster().state(ClusterState.ACTIVE);

createCacheAndPreload(grid(1), 100);

IgniteSnapshotManager snpMgr = (IgniteSnapshotManager)grid(0).snapshot();

snpMgr.createSnapshot("test_snapshot").get(getTestTimeout());

grid(0).destroyCache(DEFAULT_CACHE_NAME);

awaitPartitionMapExchange();

TestRecordingCommunicationSpi cm = ((TestRecordingCommunicationSpi)grid(1).configuration().getCommunicationSpi());

cm.blockMessages((node, msg) -> msg instanceof SingleNodeMessage<?> sm
&& (sm.type() == CHECK_SNAPSHOT_PARTS.ordinal()));

IgniteFutureImpl<Void> restoreFut = snpMgr.restoreSnapshot("test_snapshot", null, null, 0, true);

assertTrue(waitForCondition(cm::hasBlockedMessages, getTestTimeout()));

injectTestSystemOut();

int code = execute("--snapshot", "status");

assertEquals("Unexpected exit code", EXIT_CODE_OK, code);

String out = testOut.toString();

assertContains(log, out, "Check snapshot operation is in progress");
assertContains(log, out, "Snapshot name: test_snapshot");

assertFalse("Snapshot future has finished", restoreFut.isDone());

cm.stopBlock();

restoreFut.get(getTestTimeout());
}

/** */
@Test
public void testOneSnapshotCheckStatus() throws Exception {
doTestSnapshotsChecksStatus(false, false);
}

/** */
@Test
public void testOneIncrementalSnapshotCheckStatus() throws Exception {
doTestSnapshotsChecksStatus(false, true);
}

/** */
@Test
public void testTwoSnapshotsChecksStatus() throws Exception {
doTestSnapshotsChecksStatus(true, false);
}

/** */
@Test
public void testTwoIncrementalsSnapshotsChecksStatus() throws Exception {
doTestSnapshotsChecksStatus(true, true);
}

/** */
private void doTestSnapshotsChecksStatus(boolean twoSnapshots, boolean incremental) throws Exception {
walCompactionEnabled(incremental);

startGrids(3).cluster().state(ClusterState.ACTIVE);

IgniteSnapshotManager snpMgr = (IgniteSnapshotManager)grid(0).snapshot();

createCacheAndPreload(grid(1), DEFAULT_CACHE_NAME, 100, 32, null);
snpMgr.createSnapshot("testSnapshot0").get(getTestTimeout());

if (incremental) {
try (IgniteDataStreamer<Object, Object> streamer = grid(0).dataStreamer(DEFAULT_CACHE_NAME)) {
for (int i = 100; i < 110; i++)
streamer.addData(i, i);
}

snpMgr.createIncrementalSnapshot("testSnapshot0").get(getTestTimeout());
}

if (twoSnapshots) {
snpMgr.createSnapshot("testSnapshot1").get(getTestTimeout());

if (incremental) {
try (IgniteDataStreamer<Object, Object> streamer = grid(0).dataStreamer(DEFAULT_CACHE_NAME)) {
for (int i = 110; i < 120; i++)
streamer.addData(i, i);
}

snpMgr.createIncrementalSnapshot("testSnapshot1").get(getTestTimeout());
}
}

TestRecordingCommunicationSpi cm = ((TestRecordingCommunicationSpi)grid(1).configuration().getCommunicationSpi());

cm.blockMessages((node, msg) -> msg instanceof SingleNodeMessage<?> sm &&
(sm.type() == CHECK_SNAPSHOT_PARTS.ordinal()));

IgniteInternalFuture<?> checkFut0 = runAsync(() -> incremental
? execute("--snapshot", "check", "testSnapshot0", "--increment", "1")
: execute("--snapshot", "check", "testSnapshot0"));

IgniteInternalFuture<?> checkFut1 = twoSnapshots
? runAsync(() -> incremental
? execute("--snapshot", "check", "testSnapshot1", "--increment", "1")
: execute("--snapshot", "check", "testSnapshot1"))
: null;

assertTrue(waitForCondition(() -> cm.blockedMessages().stream().filter(m ->
m.ioMessage().message() instanceof SingleNodeMessage<?> sm
&& sm.type() == CHECK_SNAPSHOT_PARTS.ordinal()).count() == (twoSnapshots ? 2 : 1),
getTestTimeout()
));

injectTestSystemOut();

assertEquals("Unexpected exit code", EXIT_CODE_OK, execute("--snapshot", "status"));

String out = testOut.toString();

if (log.isInfoEnabled())
log.info("Test out:" + U.nl() + out);

String checkSnpErr = "Check snapshot operation is in progress";

int errSum = Arrays.stream(out.split(U.nl()))
.mapToInt(l -> (l.length() - l.replace(checkSnpErr, "").length()) / checkSnpErr.length())
.sum();

assertEquals(twoSnapshots ? 2 : 1, errSum);

assertTrue(out.contains("Snapshot name: testSnapshot0"));

if (incremental)
assertTrue(out.contains("Increment index: 1"));

if (twoSnapshots) {
assertTrue(out.contains("Snapshot name: testSnapshot1"));

if (incremental) {
// Number of 'Increment index: 1' entries.
var sum = Arrays.stream(out.split(U.nl()))
.mapToInt(l -> (l.length() - l.replace("Increment index: 1", "").length()) / "Increment index: 1".length())
.sum();

assertEquals(2, sum);
}
}

cm.stopBlock();

checkFut0.get();

if (twoSnapshots)
checkFut1.get();
}

/** */
@Test
public void testSnapshotCheckStatusWithParallelCreate() throws Exception {
doTestSnapshotsChecksStatusWithParallelCreate(false);
}

/** */
@Test
public void testTwoSnapshotsChecksStatusWithParallelCreate() throws Exception {
doTestSnapshotsChecksStatusWithParallelCreate(true);
}

/** */
private void doTestSnapshotsChecksStatusWithParallelCreate(boolean twoChecks) throws Exception {
startGrids(3).cluster().state(ClusterState.ACTIVE);

IgniteSnapshotManager snpMgr = (IgniteSnapshotManager)grid(0).snapshot();

createCacheAndPreload(grid(1), DEFAULT_CACHE_NAME, 100, 32, null);
snpMgr.createSnapshot("testSnapshot0").get(getTestTimeout());

if (twoChecks) {
createCacheAndPreload(grid(1), "cache2", 100, 32, null);
snpMgr.createSnapshot("testSnapshot1").get(getTestTimeout());
}

createCacheAndPreload(grid(1), "cache3", 100, 32, null);

TestRecordingCommunicationSpi cm = ((TestRecordingCommunicationSpi)grid(1).configuration().getCommunicationSpi());

cm.blockMessages((node, msg) ->
msg instanceof SingleNodeMessage<?> sm && (sm.type() == CHECK_SNAPSHOT_PARTS.ordinal()
|| sm.type() == END_SNAPSHOT.ordinal()));

IgniteFuture<?> createFut = snpMgr.createSnapshot("testSnapshot2");

IgniteInternalFuture<?> checkFut0 = runAsync(() -> execute("--snapshot", "check", "testSnapshot0"));
IgniteInternalFuture<?> checkFut1 = twoChecks ? runAsync(() -> execute("--snapshot", "check", "testSnapshot1")) : null;

// Wait for the creation gets blocked.
assertTrue(waitForCondition(() -> cm.blockedMessages().stream().anyMatch(m ->
m.ioMessage().message() instanceof SingleNodeMessage<?> sm && sm.type() == END_SNAPSHOT.ordinal()),
getTestTimeout()
));

// Wait for the checks get blocked.
assertTrue(waitForCondition(() -> cm.blockedMessages().stream().filter(m ->
m.ioMessage().message() instanceof SingleNodeMessage<?> sm
&& sm.type() == CHECK_SNAPSHOT_PARTS.ordinal()).count() == (twoChecks ? 2 : 1),
getTestTimeout()
));

injectTestSystemOut();

assertEquals("Unexpected exit code", EXIT_CODE_OK, execute("--snapshot", "status"));

String out = testOut.toString();

assertTrue(out.contains("Create snapshot operation is in progress"));
assertTrue(out.contains("Snapshot name: testSnapshot2"));

String checkSnpLogErr = "Check snapshot operation is in progress";

int entrySum = Arrays.stream(out.split(U.nl()))
.mapToInt(l -> (l.length() - l.replace(checkSnpLogErr, "").length()) / checkSnpLogErr.length())
.sum();

assertEquals(twoChecks ? 2 : 1, entrySum);

assertTrue(out.contains("Snapshot name: testSnapshot0"));

if (twoChecks)
assertTrue(out.contains("Snapshot name: testSnapshot1"));

cm.stopBlock();

createFut.get();
checkFut0.get();

if (twoChecks)
checkFut1.get();
}

/** @throws Exception If fails. */
@Test
public void testSnapshotStatusInMemory() throws Exception {
Expand Down Expand Up @@ -3785,7 +4035,7 @@ private void checkSnapshotStatus(boolean isCreating, boolean isRestoring, boolea
assertEquals(out, EXIT_CODE_OK, status);

if (!isCreating && !isRestoring) {
assertContains(log, out, "There is no create or restore snapshot operation in progress.");
assertContains(log, out, SnapshotStatusCommand.NO_SNP_OP_IN_PROGRESS_MSG);

return;
}
Expand Down
Loading
Loading