You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by na...@apache.org on 2022/08/18 14:42:19 UTC
[ignite] branch master updated: IGNITE-13510 Added snapshot status command to control.sh and JMX. (#10202)
This is an automated email from the ASF dual-hosted git repository.
namelchev 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 2361ff3d818 IGNITE-13510 Added snapshot status command to control.sh and JMX. (#10202)
2361ff3d818 is described below
commit 2361ff3d8189ead8f7274ad4bf318df993b5404f
Author: Nikita Amelchev <ns...@gmail.com>
AuthorDate: Thu Aug 18 17:42:09 2022 +0300
IGNITE-13510 Added snapshot status command to control.sh and JMX. (#10202)
---
docs/_docs/snapshots/snapshots.adoc | 36 +++-
.../snapshot/SnapshotRestoreCommand.java | 7 +-
.../snapshot/SnapshotStatusCommand.java | 113 +++++++++++
.../commandline/snapshot/SnapshotSubcommands.java | 5 +-
.../util/GridCommandHandlerAbstractTest.java | 9 +-
.../apache/ignite/util/GridCommandHandlerTest.java | 86 +++++++-
.../snapshot/IgniteSnapshotManager.java | 5 +
.../persistence/snapshot/SnapshotMXBeanImpl.java | 29 +++
.../snapshot/SnapshotOperationRequest.java | 10 +
.../visor/snapshot/VisorSnapshotRestoreTask.java | 5 +-
.../snapshot/VisorSnapshotRestoreTaskAction.java | 7 +-
.../visor/snapshot/VisorSnapshotStatusTask.java | 219 +++++++++++++++++++++
.../org/apache/ignite/mxbean/SnapshotMXBean.java | 8 +
.../IgniteClusterSnapshotRestoreSelfTest.java | 8 +-
.../snapshot/IgniteSnapshotMXBeanTest.java | 91 ++++++++-
...ridCommandHandlerClusterByClassTest_help.output | 5 +-
...andHandlerClusterByClassWithSSLTest_help.output | 5 +-
17 files changed, 625 insertions(+), 23 deletions(-)
diff --git a/docs/_docs/snapshots/snapshots.adoc b/docs/_docs/snapshots/snapshots.adoc
index b3f03cdc766..ed26326f7ef 100644
--- a/docs/_docs/snapshots/snapshots.adoc
+++ b/docs/_docs/snapshots/snapshots.adoc
@@ -218,7 +218,7 @@ control.(sh|bat) --snapshot restore snapshot_02092020 --start --groups snapshot-
--
==== Using CLI to control restore operation
-The `control.sh|bat` script provides the ability to start, stop, and get the status of the restore operation.
+The `control.sh|bat` script provides the ability to start and stop the restore operation.
[source,shell]
----
@@ -234,13 +234,41 @@ control.(sh|bat) --snapshot restore snapshot_09062021 --src /tmp/ignite/snapshot
# Start restoring only "cache-group1" and "cache-group2" from the snapshot "snapshot_09062021" in the background.
control.(sh|bat) --snapshot restore snapshot_09062021 --start --groups cache-group1,cache-group2
-# Get the status of the restore operation for "snapshot_09062021".
-control.(sh|bat) --snapshot restore snapshot_09062021 --status
-
# Cancel the restore operation for "snapshot_09062021".
control.(sh|bat) --snapshot restore snapshot_09062021 --cancel
----
+== Getting Snapshot Operation Status
+
+The status of the current snapshot operation in the cluster can be obtained using the `control.sh|bat` script or JMX interface:
+
+[tabs]
+--
+tab:Unix[]
+[source,shell]
+----
+# Get the status of the snapshot operation.
+control.sh --snapshot status
+----
+
+tab:Windows[]
+[source,shell]
+----
+# Get the status of the 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();
+----
+--
+
== Consistency Guarantees
All snapshots are fully consistent in terms of concurrent cluster-wide operations as well as ongoing changes with Ignite.
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/snapshot/SnapshotRestoreCommand.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/snapshot/SnapshotRestoreCommand.java
index 0fa21259a54..ae90116f561 100644
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/snapshot/SnapshotRestoreCommand.java
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/snapshot/SnapshotRestoreCommand.java
@@ -37,6 +37,7 @@ import static org.apache.ignite.internal.commandline.snapshot.SnapshotRestoreCom
import static org.apache.ignite.internal.commandline.snapshot.SnapshotRestoreCommandOption.SYNC;
import static org.apache.ignite.internal.commandline.snapshot.SnapshotSubcommands.RESTORE;
import static org.apache.ignite.internal.visor.snapshot.VisorSnapshotRestoreTaskAction.START;
+import static org.apache.ignite.internal.visor.snapshot.VisorSnapshotRestoreTaskAction.STATUS;
/**
* Sub-command to restore snapshot.
@@ -49,6 +50,9 @@ public class SnapshotRestoreCommand extends SnapshotSubcommand {
/** {@inheritDoc} */
@Override public Object execute(GridClientConfiguration clientCfg, Logger log) throws Exception {
+ if (cmdArg instanceof VisorSnapshotRestoreTaskArg && ((VisorSnapshotRestoreTaskArg)cmdArg).jobAction() == STATUS)
+ log.warning("Command deprecated. Use '" + SNAPSHOT + ' ' + SnapshotSubcommands.STATUS + "' instead.");
+
Object res = super.execute(clientCfg, log);
log.info(String.valueOf(res));
@@ -122,7 +126,8 @@ public class SnapshotRestoreCommand extends SnapshotSubcommand {
usage(log, "Restore snapshot:", SNAPSHOT, startParams, RESTORE.toString(), SNAPSHOT_NAME_ARG, "--start",
optional(GROUPS.argName(), GROUPS.arg()), optional(SOURCE.argName(), SOURCE.arg()), optional(SYNC.argName()));
- usage(log, "Snapshot restore operation status:", SNAPSHOT, params, RESTORE.toString(), SNAPSHOT_NAME_ARG, "--status");
+ usage(log, "Snapshot restore operation status (Command deprecated. Use '" + SNAPSHOT + ' '
+ + SnapshotSubcommands.STATUS + "' instead.):", SNAPSHOT, params, RESTORE.toString(), SNAPSHOT_NAME_ARG, "--status");
usage(log, "Cancel snapshot restore operation:", SNAPSHOT, params, RESTORE.toString(), SNAPSHOT_NAME_ARG, "--cancel");
}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/snapshot/SnapshotStatusCommand.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/snapshot/SnapshotStatusCommand.java
new file mode 100644
index 00000000000..c0f2f2157e4
--- /dev/null
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/snapshot/SnapshotStatusCommand.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.commandline.snapshot;
+
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+import org.apache.ignite.internal.commandline.CommandArgIterator;
+import org.apache.ignite.internal.commandline.systemview.SystemViewCommand;
+import org.apache.ignite.internal.util.GridStringBuilder;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.X;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.internal.visor.snapshot.VisorSnapshotStatusTask;
+import org.apache.ignite.internal.visor.snapshot.VisorSnapshotStatusTask.SnapshotStatus;
+
+import static org.apache.ignite.internal.commandline.CommandList.SNAPSHOT;
+import static org.apache.ignite.internal.commandline.snapshot.SnapshotSubcommands.STATUS;
+import static org.apache.ignite.internal.visor.systemview.VisorSystemViewTask.SimpleType.NUMBER;
+import static org.apache.ignite.internal.visor.systemview.VisorSystemViewTask.SimpleType.STRING;
+
+/**
+ * Command to get the status of the current snapshot operation in the cluster.
+ */
+public class SnapshotStatusCommand extends SnapshotSubcommand {
+ /** */
+ protected SnapshotStatusCommand() {
+ super("status", VisorSnapshotStatusTask.class);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void printResult(Object res, Logger log) {
+ if (res == null) {
+ log.info("There is no create or restore snapshot operation in progress.");
+
+ return;
+ }
+
+ SnapshotStatus status = (SnapshotStatus)res;
+
+ boolean isCreating = status.operation() == VisorSnapshotStatusTask.SnapshotOperation.CREATE;
+
+ GridStringBuilder s = new GridStringBuilder();
+
+ if (isCreating)
+ s.a("Create snapshot operation is in progress.").nl();
+ else
+ s.a("Restore snapshot operation is in progress.").nl();
+
+ s.a("Snapshot name: ").a(status.name()).nl();
+ s.a("Operation ID: ").a(status.requestId()).nl();
+ s.a("Started at: ").a(DateFormat.getDateTimeInstance().format(new Date(status.startTime()))).nl();
+ s.a("Duration: ").a(X.timeSpan2DHMSM(System.currentTimeMillis() - status.startTime())).nl()
+ .nl();
+ s.a("Estimated operation progress:").nl();
+
+ log.info(s.toString());
+
+ List<String> titles = isCreating ? F.asList("Node ID", "Processed, bytes", "Total, bytes", "Percent") :
+ F.asList("Node ID", "Processed, partitions", "Total, partitions", "Percent");
+
+ List<List<?>> rows = status.progress().entrySet().stream().sorted(Map.Entry.comparingByKey()).map(e -> {
+ UUID nodeId = e.getKey();
+ long processed = e.getValue().get1();
+ long total = e.getValue().get2();
+
+ if (total <= 0)
+ return F.asList(nodeId, "unknown", "unknown", "unknown");
+
+ String percent = (int)(processed * 100 / total) + "%";
+
+ if (isCreating)
+ return F.asList(nodeId, U.humanReadableByteCount(processed), U.humanReadableByteCount(total), percent);
+ else
+ return F.asList(nodeId, processed, total, percent);
+ }).collect(Collectors.toList());
+
+ SystemViewCommand.printTable(titles, F.asList(STRING, NUMBER, NUMBER, NUMBER),
+ rows, log);
+
+ log.info(U.nl());
+ }
+
+ /** {@inheritDoc} */
+ @Override public void parseArguments(CommandArgIterator argIter) {
+ if (argIter.hasNextSubArg())
+ throw new IllegalArgumentException("Unexpected argument: " + argIter.peekNextArg() + '.');
+ }
+
+ /** {@inheritDoc} */
+ @Override public void printUsage(Logger log) {
+ usage(log, "Get the status of the current snapshot operation:", SNAPSHOT, STATUS.toString());
+ }
+}
diff --git a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/snapshot/SnapshotSubcommands.java b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/snapshot/SnapshotSubcommands.java
index c26b5ade4b4..abe16c9d69f 100644
--- a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/snapshot/SnapshotSubcommands.java
+++ b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/snapshot/SnapshotSubcommands.java
@@ -36,7 +36,10 @@ public enum SnapshotSubcommands {
CHECK(new SnapshotCheckCommand()),
/** Sub-command to restore snapshot. */
- RESTORE(new SnapshotRestoreCommand());
+ RESTORE(new SnapshotRestoreCommand()),
+
+ /** Sub-command to get the status of the current snapshot operation. */
+ STATUS(new SnapshotStatusCommand());
/** Sub-command. */
private final SnapshotSubcommand cmd;
diff --git a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerAbstractTest.java b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerAbstractTest.java
index 67552e27b0b..340fe958b36 100644
--- a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerAbstractTest.java
+++ b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerAbstractTest.java
@@ -33,7 +33,7 @@ import java.util.logging.Handler;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import org.apache.ignite.Ignite;
-import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteDataStreamer;
import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.configuration.AtomicConfiguration;
@@ -455,9 +455,10 @@ public abstract class GridCommandHandlerAbstractTest extends GridCommonAbstractT
ignite.createCache(ccfg);
- IgniteCache<Object, Object> cache = ignite.cache(cacheName);
- for (int i = 0; i < countEntries; i++)
- cache.put(i, i);
+ try (IgniteDataStreamer<Object, Object> streamer = ignite.dataStreamer(cacheName)) {
+ for (int i = 0; i < countEntries; i++)
+ streamer.addData(i, i);
+ }
}
/**
diff --git a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java
index 1669e2251e6..90ce6cccf2e 100644
--- a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java
+++ b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java
@@ -106,6 +106,7 @@ import org.apache.ignite.internal.processors.cache.warmup.WarmUpTestPluginProvid
import org.apache.ignite.internal.processors.cluster.ChangeGlobalStateFinishMessage;
import org.apache.ignite.internal.processors.cluster.GridClusterStateProcessor;
import org.apache.ignite.internal.util.BasicRateLimiter;
+import org.apache.ignite.internal.util.distributed.SingleNodeMessage;
import org.apache.ignite.internal.util.future.IgniteFinishedFutureImpl;
import org.apache.ignite.internal.util.lang.GridAbsPredicate;
import org.apache.ignite.internal.util.lang.GridFunc;
@@ -3474,9 +3475,92 @@ public class GridCommandHandlerTest extends GridCommandHandlerClusterPerMethodAb
assertNull(ig.cache(DEFAULT_CACHE_NAME));
}
+ /** @throws Exception If fails. */
+ @Test
+ public void testSnapshotStatus() throws Exception {
+ String snapshotName = "snapshot1";
+ int keysCnt = 10_000;
+
+ IgniteEx srv = startGrids(3);
+
+ srv.cluster().state(ACTIVE);
+
+ createCacheAndPreload(srv, keysCnt);
+
+ checkSnapshotStatus(false, false, null);
+
+ TestRecordingCommunicationSpi spi = TestRecordingCommunicationSpi.spi(grid(1));
+
+ spi.blockMessages((node, msg) -> msg instanceof SingleNodeMessage);
+
+ IgniteFuture<Void> fut = srv.snapshot().createSnapshot(snapshotName);
+
+ spi.waitForBlocked();
+
+ checkSnapshotStatus(true, false, snapshotName);
+
+ spi.stopBlock();
+
+ fut.get(getTestTimeout());
+
+ checkSnapshotStatus(false, false, null);
+
+ srv.destroyCache(DEFAULT_CACHE_NAME);
+
+ spi.blockMessages((node, msg) -> msg instanceof SingleNodeMessage);
+
+ fut = srv.snapshot().restoreSnapshot(snapshotName, F.asList(DEFAULT_CACHE_NAME));
+
+ spi.waitForBlocked();
+
+ checkSnapshotStatus(false, true, snapshotName);
+
+ spi.stopBlock();
+
+ fut.get(getTestTimeout());
+
+ checkSnapshotStatus(false, false, null);
+ }
+
/**
- * @throws Exception If failed.
+ * @param isCreating {@code True} if create snapshot operation is in progress.
+ * @param isRestoring {@code True} if restore snapshot operation is in progress.
+ * @param expName Expected snapshot name.
*/
+ private void checkSnapshotStatus(boolean isCreating, boolean isRestoring, String expName) throws Exception {
+ assertTrue(waitForCondition(() -> G.allGrids().stream().allMatch(
+ ignite -> {
+ IgniteSnapshotManager mgr = ((IgniteEx)ignite).context().cache().context().snapshotMgr();
+
+ return isCreating == mgr.isSnapshotCreating() && isRestoring == mgr.isRestoring();
+ }),
+ getTestTimeout()));
+
+ injectTestSystemOut();
+
+ int status = execute("--snapshot", "status");
+
+ String out = testOut.toString();
+
+ assertEquals(out, EXIT_CODE_OK, status);
+
+ if (!isCreating && !isRestoring) {
+ assertContains(log, out, "There is no create or restore snapshot operation in progress.");
+
+ return;
+ }
+
+ if (isCreating)
+ assertContains(log, out, "Create snapshot operation is in progress.");
+ else
+ assertContains(log, out, "Restore snapshot operation is in progress.");
+
+ assertContains(log, out, "Snapshot name: " + expName);
+
+ G.allGrids().forEach(srv -> assertContains(log, out, srv.cluster().localNode().id().toString()));
+ }
+
+ /** @throws Exception If failed. */
@Test
@WithSystemProperty(key = IGNITE_PDS_SKIP_CHECKPOINT_ON_NODE_STOP, value = "true")
public void testCleaningGarbageAfterCacheDestroyedAndNodeStop_ControlConsoleUtil() throws Exception {
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 2d1981aa70f..322293573db 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
@@ -1037,6 +1037,11 @@ public class IgniteSnapshotManager extends GridCacheSharedManagerAdapter
}
}
+ /** @return Current create snapshot request. {@code Null} if there is no create snapshot operation in progress. */
+ @Nullable public SnapshotOperationRequest currentCreateRequest() {
+ return clusterSnpReq;
+ }
+
/**
* Check if snapshot restore process is currently running.
*
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 33389881a26..ea0a1debd1f 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
@@ -21,10 +21,14 @@ import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.processors.metric.GridMetricManager;
+import org.apache.ignite.internal.processors.metric.MetricRegistry;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.lang.IgniteFuture;
import org.apache.ignite.mxbean.SnapshotMXBean;
+import static org.apache.ignite.internal.processors.cache.persistence.snapshot.SnapshotRestoreProcess.SNAPSHOT_RESTORE_METRICS;
+
/**
* Snapshot MBean features.
*/
@@ -32,11 +36,15 @@ public class SnapshotMXBeanImpl implements SnapshotMXBean {
/** Instance of snapshot cache shared manager. */
private final IgniteSnapshotManager mgr;
+ /** Instance of metric manager. */
+ private final GridMetricManager metricMgr;
+
/**
* @param ctx Kernal context.
*/
public SnapshotMXBeanImpl(GridKernalContext ctx) {
mgr = ctx.cache().context().snapshotMgr();
+ metricMgr = ctx.metric();
}
/** {@inheritDoc} */
@@ -67,4 +75,25 @@ public class SnapshotMXBeanImpl implements SnapshotMXBean {
@Override public void cancelSnapshotRestore(String name) {
mgr.cancelSnapshotRestore(name).get();
}
+
+ /** {@inheritDoc} */
+ @Override public String status() {
+ SnapshotOperationRequest req = mgr.currentCreateRequest();
+
+ if (req != null) {
+ return "Create snapshot operation is in progress [name=" + req.snapshotName() +
+ ", id=" + req.requestId() + ']';
+ }
+
+ if (mgr.isRestoring()) {
+ MetricRegistry mreg = metricMgr.registry(SNAPSHOT_RESTORE_METRICS);
+
+ String name = mreg.findMetric("snapshotName").getAsString();
+ String id = mreg.findMetric("requestId").getAsString();
+
+ return "Restore snapshot operation is in progress [name=" + name + ", id=" + id + ']';
+ }
+
+ return "There is no create or restore snapshot operation in progress.";
+ }
}
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 6c20c6d2910..14c72f661ea 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
@@ -25,6 +25,7 @@ import org.apache.ignite.internal.util.distributed.DistributedProcess;
import org.apache.ignite.internal.util.distributed.DistributedProcess.DistributedProcessType;
import org.apache.ignite.internal.util.tostring.GridToStringInclude;
import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
import org.jetbrains.annotations.Nullable;
/**
@@ -60,6 +61,9 @@ public class SnapshotOperationRequest implements Serializable {
/** Flag indicating that the {@link DistributedProcessType#START_SNAPSHOT} phase has completed. */
private transient volatile boolean startStageEnded;
+ /** Operation start time. */
+ private final long startTime;
+
/**
* @param reqId Request ID.
* @param opNodeId Operational node ID.
@@ -82,6 +86,7 @@ public class SnapshotOperationRequest implements Serializable {
this.grps = grps;
this.nodes = nodes;
this.snpPath = snpPath;
+ startTime = U.currentTimeMillis();
}
/**
@@ -140,6 +145,11 @@ public class SnapshotOperationRequest implements Serializable {
this.err = err;
}
+ /** @return Start time. */
+ public long startTime() {
+ return startTime;
+ }
+
/**
* @return Flag indicating that the {@link DistributedProcessType#START_SNAPSHOT} phase has completed.
*/
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotRestoreTask.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotRestoreTask.java
index 49e5e62d166..1892af84bb3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotRestoreTask.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotRestoreTask.java
@@ -98,7 +98,10 @@ public class VisorSnapshotRestoreTask extends VisorSnapshotOneNodeTask<VisorSnap
}
}
- /** */
+ /**
+ * @deprecated Use {@link VisorSnapshotStatusTask} instead.
+ */
+ @Deprecated
private static class VisorSnapshotRestoreStatusJob extends VisorJob<VisorSnapshotRestoreTaskArg, String> {
/** Serial version uid. */
private static final long serialVersionUID = 0L;
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotRestoreTaskAction.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotRestoreTaskAction.java
index ad101556045..04c2c740b76 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotRestoreTaskAction.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotRestoreTaskAction.java
@@ -25,6 +25,11 @@ public enum VisorSnapshotRestoreTaskAction {
/** Cancel snapshot restore operation. */
CANCEL,
- /** Status of the snapshot restore operation. */
+ /**
+ * Status of the snapshot restore operation.
+ *
+ * @deprecated Use {@link VisorSnapshotStatusTask} instead.
+ */
+ @Deprecated
STATUS;
}
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotStatusTask.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotStatusTask.java
new file mode 100644
index 00000000000..0cb165c0299
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/snapshot/VisorSnapshotStatusTask.java
@@ -0,0 +1,219 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.visor.snapshot;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.compute.ComputeJobResult;
+import org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager;
+import org.apache.ignite.internal.processors.cache.persistence.snapshot.SnapshotOperationRequest;
+import org.apache.ignite.internal.processors.metric.MetricRegistry;
+import org.apache.ignite.internal.processors.task.GridInternal;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.T2;
+import org.apache.ignite.internal.visor.VisorJob;
+import org.apache.ignite.internal.visor.VisorMultiNodeTask;
+import org.apache.ignite.internal.visor.VisorTaskArgument;
+import org.apache.ignite.spi.metric.IntMetric;
+import org.apache.ignite.spi.metric.LongMetric;
+import org.jetbrains.annotations.Nullable;
+
+import static org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.SNAPSHOT_METRICS;
+import static org.apache.ignite.internal.processors.cache.persistence.snapshot.SnapshotRestoreProcess.SNAPSHOT_RESTORE_METRICS;
+import static org.apache.ignite.internal.visor.snapshot.VisorSnapshotStatusTask.SnapshotStatus;
+
+/**
+ * Task to get the status of the current snapshot operation in the cluster.
+ */
+@GridInternal
+public class VisorSnapshotStatusTask extends VisorMultiNodeTask<Void, VisorSnapshotTaskResult, SnapshotStatus> {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /** {@inheritDoc} */
+ @Override protected VisorJob<Void, SnapshotStatus> job(Void arg) {
+ return new VisorSnapshotStatusJob(arg, debug);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected Collection<UUID> jobNodes(VisorTaskArgument<Void> arg) {
+ return F.nodeIds(ignite.cluster().nodes());
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override protected VisorSnapshotTaskResult reduce0(List<ComputeJobResult> results) {
+ if (results.isEmpty())
+ return new VisorSnapshotTaskResult(null, new IgniteException("Failed to get the snapshot status. Topology is empty."));
+
+ IgniteException error = F.find(F.viewReadOnly(results, ComputeJobResult::getException,
+ r -> r.getException() != null), null, F.notNull());
+
+ if (error != null)
+ return new VisorSnapshotTaskResult(null, new IgniteException("Failed to get the snapshot status.", error));
+
+ Collection<SnapshotStatus> res = F.viewReadOnly(results, ComputeJobResult::getData, r -> r.getData() != null);
+
+ // There is no snapshot operation.
+ if (res.isEmpty())
+ return new VisorSnapshotTaskResult(null, null);
+
+ SnapshotStatus s0 = F.first(res);
+
+ // Filter out differing requests due to concurrent updates on nodes.
+ res = F.view(res, s -> s.requestId.equals(s0.requestId));
+
+ // Merge nodes progress.
+ Map<UUID, T2<Long, Long>> progress = new HashMap<>();
+
+ res.forEach(s -> progress.putAll(s.progress));
+
+ return new VisorSnapshotTaskResult(new SnapshotStatus(s0.op, s0.name, s0.requestId, s0.startTime, progress), null);
+ }
+
+ /** */
+ private static class VisorSnapshotStatusJob extends VisorJob<Void, SnapshotStatus> {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /**
+ * @param arg Job argument.
+ * @param debug Flag indicating whether debug information should be printed into node log.
+ */
+ protected VisorSnapshotStatusJob(@Nullable Void arg, boolean debug) {
+ super(arg, debug);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected SnapshotStatus run(@Nullable Void arg) throws IgniteException {
+ IgniteSnapshotManager snpMgr = ignite.context().cache().context().snapshotMgr();
+
+ SnapshotOperationRequest req = snpMgr.currentCreateRequest();
+
+ if (req != null) {
+ MetricRegistry mreg = ignite.context().metric().registry(SNAPSHOT_METRICS);
+
+ return new SnapshotStatus(
+ SnapshotOperation.CREATE,
+ req.snapshotName(),
+ req.requestId().toString(),
+ req.startTime(),
+ F.asMap(
+ ignite.localNode().id(),
+ new T2<>(
+ mreg.<LongMetric>findMetric("CurrentSnapshotProcessedSize").value(),
+ mreg.<LongMetric>findMetric("CurrentSnapshotTotalSize").value()
+ )
+ )
+ );
+ }
+
+ MetricRegistry mreg = ignite.context().metric().registry(SNAPSHOT_RESTORE_METRICS);
+
+ long startTime = mreg.<LongMetric>findMetric("startTime").value();
+
+ if (startTime > mreg.<LongMetric>findMetric("endTime").value()) {
+ return new SnapshotStatus(
+ SnapshotOperation.RESTORE,
+ mreg.findMetric("snapshotName").getAsString(),
+ mreg.findMetric("requestId").getAsString(),
+ mreg.<LongMetric>findMetric("startTime").value(),
+ F.asMap(
+ ignite.localNode().id(),
+ new T2<>(
+ (long)mreg.<IntMetric>findMetric("processedPartitions").value(),
+ (long)mreg.<IntMetric>findMetric("totalPartitions").value()
+ )
+ )
+ );
+ }
+
+ return null;
+ }
+ }
+
+ /** Snapshot operation status. */
+ public static class SnapshotStatus implements Serializable {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /** Operation type. */
+ private final SnapshotOperation op;
+
+ /** Snapshot name. */
+ private final String name;
+
+ /** Request ID. */
+ private final String requestId;
+
+ /** Start time. */
+ private final long startTime;
+
+ /** Progress of operation on nodes. */
+ private final Map<UUID, T2<Long, Long>> progress;
+
+ /** */
+ public SnapshotStatus(SnapshotOperation op, String name, String requestId, long startTime,
+ Map<UUID, T2<Long, Long>> progress) {
+ this.op = op;
+ this.name = name;
+ this.requestId = requestId;
+ this.startTime = startTime;
+ this.progress = Collections.unmodifiableMap(progress);
+ }
+
+ /** @return Operation type. */
+ public SnapshotOperation operation() {
+ return op;
+ }
+
+ /** @return Snapshot name. */
+ public String name() {
+ return name;
+ }
+
+ /** @return Request ID. */
+ public String requestId() {
+ return requestId;
+ }
+
+ /** @return Start time. */
+ public long startTime() {
+ return startTime;
+ }
+
+ /** @return Progress of operation on nodes. */
+ public Map<UUID, T2<Long, Long>> progress() {
+ return progress;
+ }
+ }
+
+ /** Snapshot operation type. */
+ public enum SnapshotOperation {
+ /** Create snapshot. */
+ CREATE,
+
+ /** Restore snapshot. */
+ RESTORE
+ }
+}
diff --git a/modules/core/src/main/java/org/apache/ignite/mxbean/SnapshotMXBean.java b/modules/core/src/main/java/org/apache/ignite/mxbean/SnapshotMXBean.java
index b18ac51dc1b..e6cdef4a26e 100644
--- a/modules/core/src/main/java/org/apache/ignite/mxbean/SnapshotMXBean.java
+++ b/modules/core/src/main/java/org/apache/ignite/mxbean/SnapshotMXBean.java
@@ -74,4 +74,12 @@ public interface SnapshotMXBean {
*/
@MXBeanDescription("Cancel previously started snapshot restore operation.")
public void cancelSnapshotRestore(@MXBeanParameter(name = "snpName", description = "Snapshot name.") String name);
+
+ /**
+ * Get the status of the current snapshot operation in the cluster.
+ *
+ * @return The status of a current snapshot operation in the cluster.
+ */
+ @MXBeanDescription("The status of a current snapshot operation in the cluster.")
+ public String status();
}
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 8cb9049fd49..0ec6648f45d 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
@@ -31,6 +31,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.IntSupplier;
+import com.google.common.base.Throwables;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteCheckedException;
@@ -61,6 +62,7 @@ import org.apache.ignite.internal.util.distributed.DistributedProcess.Distribute
import org.apache.ignite.internal.util.distributed.SingleNodeMessage;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.G;
+import org.apache.ignite.internal.util.typedef.X;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteFuture;
import org.apache.ignite.spi.IgniteSpiException;
@@ -269,14 +271,16 @@ public class IgniteClusterSnapshotRestoreSelfTest extends IgniteClusterSnapshotR
IgniteInternalFuture<Long> fut = GridTestUtils.runMultiThreadedAsync(() -> {
try {
- nodeIdxSupplier.getAsInt();
-
grid(nodeIdxSupplier.getAsInt()).snapshot().restoreSnapshot(
SNAPSHOT_NAME, Collections.singleton(DEFAULT_CACHE_NAME)).get(TIMEOUT);
successCnt.incrementAndGet();
}
catch (Exception e) {
+ assertTrue("Unexpected exception: " + Throwables.getStackTraceAsString(e),
+ X.hasCause(e, "The previous snapshot restore operation was not completed.",
+ IgniteCheckedException.class, IgniteException.class));
+
failCnt.incrementAndGet();
}
}, 2, "runner");
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 ef44ce14e41..837038b31c8 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
@@ -22,12 +22,15 @@ import javax.management.AttributeNotFoundException;
import javax.management.DynamicMBean;
import javax.management.MBeanException;
import javax.management.ReflectionException;
+import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.IgniteEx;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.TestRecordingCommunicationSpi;
import org.apache.ignite.internal.util.distributed.SingleNodeMessage;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.G;
import org.apache.ignite.lang.IgniteFuture;
import org.apache.ignite.mxbean.SnapshotMXBean;
import org.apache.ignite.spi.metric.jmx.JmxMetricExporterSpi;
@@ -37,6 +40,7 @@ import org.junit.Test;
import static org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteSnapshotManager.SNAPSHOT_METRICS;
import static org.apache.ignite.internal.processors.cache.persistence.snapshot.SnapshotRestoreProcess.SNAPSHOT_RESTORE_METRICS;
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.assertThrowsAnyCause;
import static org.apache.ignite.testframework.GridTestUtils.waitForCondition;
@@ -44,12 +48,13 @@ import static org.apache.ignite.testframework.GridTestUtils.waitForCondition;
* Tests {@link SnapshotMXBean}.
*/
public class IgniteSnapshotMXBeanTest extends AbstractSnapshotSelfTest {
- /** Metric group name. */
- private static final String METRIC_GROUP = "Snapshot";
+ /** Snapshot group name. */
+ private static final String SNAPSHOT_GROUP = "Snapshot";
/** {@inheritDoc} */
@Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
return super.getConfiguration(igniteInstanceName)
+ .setCommunicationSpi(new TestRecordingCommunicationSpi())
.setMetricExporterSpi(new JmxMetricExporterSpi());
}
@@ -63,7 +68,7 @@ public class IgniteSnapshotMXBeanTest extends AbstractSnapshotSelfTest {
assertEquals("Snapshot end time must be undefined on first snapshot operation starts.",
0, (long)getMetric("LastSnapshotEndTime", snpMBean));
- SnapshotMXBean mxBean = getMxBean(ignite.name(), METRIC_GROUP, SnapshotMXBeanImpl.class, SnapshotMXBean.class);
+ SnapshotMXBean mxBean = getMxBean(ignite.name(), SNAPSHOT_GROUP, SnapshotMXBeanImpl.class, SnapshotMXBean.class);
mxBean.createSnapshot(SNAPSHOT_NAME, "");
@@ -84,7 +89,7 @@ public class IgniteSnapshotMXBeanTest extends AbstractSnapshotSelfTest {
IgniteEx startCli = startClientGrid(1);
IgniteEx killCli = startClientGrid(2);
- SnapshotMXBean mxBean = getMxBean(killCli.name(), METRIC_GROUP, SnapshotMXBeanImpl.class,
+ SnapshotMXBean mxBean = getMxBean(killCli.name(), SNAPSHOT_GROUP, SnapshotMXBeanImpl.class,
SnapshotMXBean.class);
doSnapshotCancellationTest(startCli,
@@ -104,7 +109,7 @@ public class IgniteSnapshotMXBeanTest extends AbstractSnapshotSelfTest {
assertEquals(0, (long)getMetric("endTime", mReg0));
assertEquals(0, (long)getMetric("endTime", mReg1));
- getMxBean(ignite.name(), METRIC_GROUP, SnapshotMXBeanImpl.class, SnapshotMXBean.class)
+ getMxBean(ignite.name(), SNAPSHOT_GROUP, SnapshotMXBeanImpl.class, SnapshotMXBean.class)
.restoreSnapshot(SNAPSHOT_NAME, "", "");
assertTrue(GridTestUtils.waitForCondition(() -> (long)getMetric("endTime", mReg0) > 0, TIMEOUT));
@@ -117,7 +122,7 @@ public class IgniteSnapshotMXBeanTest extends AbstractSnapshotSelfTest {
@Test
public void testCancelRestoreSnapshot() throws Exception {
IgniteEx ignite = startGridsWithSnapshot(2, CACHE_KEYS_RANGE, false);
- SnapshotMXBean mxBean = getMxBean(ignite.name(), METRIC_GROUP, SnapshotMXBeanImpl.class, SnapshotMXBean.class);
+ SnapshotMXBean mxBean = getMxBean(ignite.name(), SNAPSHOT_GROUP, SnapshotMXBeanImpl.class, SnapshotMXBean.class);
DynamicMBean mReg0 = metricRegistry(grid(0).name(), null, SNAPSHOT_RESTORE_METRICS);
DynamicMBean mReg1 = metricRegistry(grid(1).name(), null, SNAPSHOT_RESTORE_METRICS);
@@ -164,6 +169,80 @@ public class IgniteSnapshotMXBeanTest extends AbstractSnapshotSelfTest {
assertNull(ignite.cache(DEFAULT_CACHE_NAME));
}
+ /** @throws Exception If fails. */
+ @Test
+ public void testStatus() throws Exception {
+ IgniteEx srv = startGridsWithCache(2, dfltCacheCfg, CACHE_KEYS_RANGE);
+
+ checkSnapshotStatus(false, false, null);
+
+ TestRecordingCommunicationSpi spi = TestRecordingCommunicationSpi.spi(grid(1));
+
+ spi.blockMessages((node, msg) -> msg instanceof SingleNodeMessage);
+
+ IgniteFuture<Void> fut = srv.snapshot().createSnapshot(SNAPSHOT_NAME);
+
+ spi.waitForBlocked();
+
+ checkSnapshotStatus(true, false, SNAPSHOT_NAME);
+
+ spi.stopBlock();
+
+ fut.get(getTestTimeout());
+
+ checkSnapshotStatus(false, false, null);
+
+ srv.destroyCache(DEFAULT_CACHE_NAME);
+
+ spi.blockMessages((node, msg) -> msg instanceof SingleNodeMessage);
+
+ fut = srv.snapshot().restoreSnapshot(SNAPSHOT_NAME, F.asList(DEFAULT_CACHE_NAME));
+
+ spi.waitForBlocked();
+
+ checkSnapshotStatus(false, true, SNAPSHOT_NAME);
+
+ spi.stopBlock();
+
+ fut.get(getTestTimeout());
+
+ checkSnapshotStatus(false, false, null);
+ }
+
+ /**
+ * @param isCreating {@code True} if create snapshot operation is in progress.
+ * @param isRestoring {@code True} if restore snapshot operation is in progress.
+ * @param expName Expected snapshot name.
+ */
+ private void checkSnapshotStatus(boolean isCreating, boolean isRestoring, String expName) throws Exception {
+ assertTrue(waitForCondition(() -> G.allGrids().stream().allMatch(
+ ignite -> {
+ IgniteSnapshotManager mgr = ((IgniteEx)ignite).context().cache().context().snapshotMgr();
+
+ return isCreating == mgr.isSnapshotCreating() && isRestoring == mgr.isRestoring();
+ }),
+ getTestTimeout()));
+
+ for (Ignite grid : G.allGrids()) {
+ SnapshotMXBean bean = getMxBean(grid.name(), SNAPSHOT_GROUP, SnapshotMXBeanImpl.class, SnapshotMXBean.class);
+
+ String status = bean.status();
+
+ if (!isCreating && !isRestoring) {
+ assertContains(log, status, "There is no create or restore snapshot operation in progress");
+
+ continue;
+ }
+
+ if (isCreating)
+ assertContains(log, status, "Create snapshot operation is in progress");
+ else
+ assertContains(log, status, "Restore snapshot operation is in progress");
+
+ assertContains(log, status, "name=" + expName);
+ }
+ }
+
/**
* @param mBean Ignite snapshot restore MBean.
* @param name Metric name.
diff --git a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
index 39024a5c748..569974c2e4c 100644
--- a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
+++ b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
@@ -169,7 +169,7 @@ This utility can do the following commands:
--src path - Path to the directory where the snapshot files are located. If not specified, the default configured snapshot directory will be used.
--sync - Run the operation synchronously, the command will wait for the entire operation to complete. Otherwise, it will be performed in the background, and the command will immediately return control.
- Snapshot restore operation status:
+ Snapshot restore operation status (Command deprecated. Use '--snapshot status' instead.):
control.(sh|bat) --snapshot restore snapshot_name --status
Parameters:
@@ -181,6 +181,9 @@ This utility can do the following commands:
Parameters:
snapshot_name - Snapshot name.
+ Get the status of the current snapshot operation:
+ control.(sh|bat) --snapshot status
+
Change cluster tag to new value:
control.(sh|bat) --change-tag newTagValue [--yes]
diff --git a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
index 39024a5c748..569974c2e4c 100644
--- a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
+++ b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
@@ -169,7 +169,7 @@ This utility can do the following commands:
--src path - Path to the directory where the snapshot files are located. If not specified, the default configured snapshot directory will be used.
--sync - Run the operation synchronously, the command will wait for the entire operation to complete. Otherwise, it will be performed in the background, and the command will immediately return control.
- Snapshot restore operation status:
+ Snapshot restore operation status (Command deprecated. Use '--snapshot status' instead.):
control.(sh|bat) --snapshot restore snapshot_name --status
Parameters:
@@ -181,6 +181,9 @@ This utility can do the following commands:
Parameters:
snapshot_name - Snapshot name.
+ Get the status of the current snapshot operation:
+ control.(sh|bat) --snapshot status
+
Change cluster tag to new value:
control.(sh|bat) --change-tag newTagValue [--yes]