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 342c36a2ace IGNITE-26742 WAL state/enable/disable commands (#12440)
342c36a2ace is described below
commit 342c36a2ace27092dc9efa5876d4576cfee1b3d4
Author: Nikolay <[email protected]>
AuthorDate: Tue Oct 21 11:04:40 2025 +0300
IGNITE-26742 WAL state/enable/disable commands (#12440)
---
.../testsuites/IgniteControlUtilityTestSuite.java | 4 +-
.../ignite/util/GridCommandHandlerWalTest.java | 178 ++++++++++++++++++++
.../ignite/internal/management/wal/WalCommand.java | 5 +-
.../internal/management/wal/WalDisableCommand.java | 51 ++++++
.../wal/{WalCommand.java => WalEnableCommand.java} | 32 +++-
.../internal/management/wal/WalSetStateTask.java | 84 ++++++++++
.../internal/management/wal/WalStateCommand.java | 79 +++++++++
.../management/wal/WalStateCommandArg.java | 58 +++++++
.../internal/management/wal/WalStateTask.java | 183 +++++++++++++++++++++
...ridCommandHandlerClusterByClassTest_help.output | 21 +++
...andHandlerClusterByClassWithSSLTest_help.output | 21 +++
11 files changed, 705 insertions(+), 11 deletions(-)
diff --git
a/modules/control-utility/src/test/java/org/apache/ignite/testsuites/IgniteControlUtilityTestSuite.java
b/modules/control-utility/src/test/java/org/apache/ignite/testsuites/IgniteControlUtilityTestSuite.java
index d4e0c22d2f2..175540df381 100644
---
a/modules/control-utility/src/test/java/org/apache/ignite/testsuites/IgniteControlUtilityTestSuite.java
+++
b/modules/control-utility/src/test/java/org/apache/ignite/testsuites/IgniteControlUtilityTestSuite.java
@@ -37,6 +37,7 @@ import
org.apache.ignite.util.GridCommandHandlerLegacyClientTest;
import org.apache.ignite.util.GridCommandHandlerMetadataTest;
import org.apache.ignite.util.GridCommandHandlerSslTest;
import org.apache.ignite.util.GridCommandHandlerTest;
+import org.apache.ignite.util.GridCommandHandlerWalTest;
import org.apache.ignite.util.GridCommandHandlerWithSslFactoryTest;
import org.apache.ignite.util.GridCommandHandlerWithSslTest;
import org.apache.ignite.util.GridPersistenceCommandsTest;
@@ -78,7 +79,8 @@ import org.junit.runners.Suite;
BaselineEventsLocalTest.class,
BaselineEventsRemoteTest.class,
- GridCommandHandlerConsistencyRepairCorrectnessTransactionalTest.class
+ GridCommandHandlerConsistencyRepairCorrectnessTransactionalTest.class,
+ GridCommandHandlerWalTest.class
})
public class IgniteControlUtilityTestSuite {
}
diff --git
a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerWalTest.java
b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerWalTest.java
new file mode 100644
index 00000000000..19ae93986dd
--- /dev/null
+++
b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerWalTest.java
@@ -0,0 +1,178 @@
+/*
+ * 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.util;
+
+import java.util.Objects;
+import java.util.regex.Pattern;
+import org.apache.ignite.cluster.ClusterState;
+import org.apache.ignite.configuration.DataRegionConfiguration;
+import org.apache.ignite.configuration.DataStorageConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.WALMode;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.util.typedef.internal.CU;
+import org.junit.Test;
+
+import static
org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_INVALID_ARGUMENTS;
+import static
org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_OK;
+
+/** */
+public class GridCommandHandlerWalTest extends GridCommandHandlerAbstractTest {
+ /** */
+ private int clusterState;
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String
igniteInstanceName) throws Exception {
+ IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+ if (clusterState == 1)
+ cfg.setDataStorageConfiguration(null);
+ else if (clusterState == 2) {
+ cfg.setDataStorageConfiguration(new DataStorageConfiguration()
+ .setDefaultDataRegionConfiguration(new
DataRegionConfiguration()
+ .setCdcEnabled(true)
+ .setPersistenceEnabled(false)));
+ }
+ else {
+
cfg.getDataStorageConfiguration().setWalMode(getTestIgniteInstanceName(0).equals(igniteInstanceName)
+ ? WALMode.BACKGROUND
+ : WALMode.LOG_ONLY);
+ }
+
+ return cfg;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTest() throws Exception {
+ stopAllGrids();
+
+ cleanPersistenceDir();
+
+ injectTestSystemOut();
+
+ super.beforeTest();
+ }
+
+ /** */
+ @Test
+ public void testWalStatePersistenceCluster() throws Exception {
+ clusterState = 0; // PDS cluster.
+
+ IgniteEx srv = startGrids(2);
+ IgniteEx cli = startClientGrid("client");
+
+ srv.cluster().state(ClusterState.ACTIVE);
+
+ assertEquals(EXIT_CODE_OK, execute("--wal", "state"));
+
+ String out = testOut.toString();
+
+ assertFalse(out.contains(cli.localNode().id().toString()));
+
assertFalse(out.contains(Objects.toString(cli.localNode().consistentId())));
+
+ outputContains("Node \\[consistentId=" + getTestIgniteInstanceName(0)
+ ".*" + WALMode.BACKGROUND);
+ outputContains("Node \\[consistentId=" + getTestIgniteInstanceName(1)
+ ".*" + WALMode.LOG_ONLY);
+ outputContains(CU.UTILITY_CACHE_NAME +
".*true.*true.*true.*true.*false");
+
+ srv.createCache("cache1");
+ srv.createCache("cache2");
+ srv.createCache("cache3");
+
+ assertEquals(EXIT_CODE_OK, execute("--wal", "disable", "--groups",
"cache2"));
+ assertEquals(EXIT_CODE_OK, execute("--wal", "state"));
+
+ outputContains(".*cache2.*true.*false.*true.*true.*false");
+
+ assertEquals(EXIT_CODE_OK, execute("--wal", "enable", "--groups",
"cache2"));
+ assertEquals(EXIT_CODE_OK, execute("--wal", "state", "--groups",
"cache1,cache2"));
+
+ outputContains(".*cache1.*true.*true.*true.*true.*false");
+ outputContains(".*cache2.*true.*true.*true.*true.*false");
+
+ assertFalse(testOut.toString().contains("cache3"));
+ }
+
+ /** */
+ @Test
+ public void testWalStateInMemoryCluster() throws Exception {
+ clusterState = 1; // In-memory.
+
+ IgniteEx srv = startGrids(2);
+ IgniteEx cli = startClientGrid("client");
+
+ srv.createCache("cache1");
+
+ assertEquals(EXIT_CODE_OK, execute("--wal", "state"));
+
+ String out = testOut.toString();
+
+ assertFalse(out.contains(cli.localNode().id().toString()));
+
assertFalse(out.contains(Objects.toString(cli.localNode().consistentId())));
+
+ outputContains("Node \\[consistentId=" + getTestIgniteInstanceName(0)
+ ".*null");
+ outputContains("Node \\[consistentId=" + getTestIgniteInstanceName(1)
+ ".*null");
+ outputContains(CU.UTILITY_CACHE_NAME +
".*false.*false.*true.*true.*false");
+ outputContains("cache1.*false.*false.*true.*true.*false");
+
+ assertEquals(EXIT_CODE_INVALID_ARGUMENTS, execute("--wal",
"--disable", "--groups", CU.UTILITY_CACHE_NAME));
+ }
+
+ /** */
+ @Test
+ public void testWalStateInMemoryCdcCluster() throws Exception {
+ clusterState = 2; // In-memory CDC.
+
+ IgniteEx srv = startGrids(2);
+ IgniteEx cli = startClientGrid("client");
+
+ srv.cluster().state(ClusterState.ACTIVE);
+
+ assertEquals(EXIT_CODE_OK, execute("--wal", "state"));
+
+ String out = testOut.toString();
+
+ assertFalse(out.contains(cli.localNode().id().toString()));
+
assertFalse(out.contains(Objects.toString(cli.localNode().consistentId())));
+
+ outputContains("Node \\[consistentId=" + getTestIgniteInstanceName(0)
+ ".*" + WALMode.LOG_ONLY);
+ outputContains("Node \\[consistentId=" + getTestIgniteInstanceName(1)
+ ".*" + WALMode.LOG_ONLY);
+ outputContains(CU.UTILITY_CACHE_NAME +
".*false.*true.*true.*true.*false");
+
+ srv.createCache("cache1");
+ srv.createCache("cache2");
+ srv.createCache("cache3");
+
+ assertEquals(EXIT_CODE_OK, execute("--wal", "disable", "--groups",
"cache2"));
+ assertEquals(EXIT_CODE_OK, execute("--wal", "state"));
+
+ outputContains(".*cache2.*false.*true.*true.*true.*true");
+
+ assertEquals(EXIT_CODE_OK, execute("--wal", "enable", "--groups",
"cache2"));
+ assertEquals(EXIT_CODE_OK, execute("--wal", "state", "--groups",
"cache1,cache2"));
+
+ outputContains(".*cache1.*false.*true.*true.*true.*true");
+ outputContains(".*cache2.*false.*true.*true.*true.*true");
+
+ assertFalse(testOut.toString().contains("cache3"));
+ }
+
+ /** */
+ private void outputContains(String regexp) {
+ assertTrue(Pattern.compile(regexp).matcher(testOut.toString()).find());
+ }
+}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalCommand.java
b/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalCommand.java
index 4e47c3ae3ab..5eb9d6f0702 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalCommand.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalCommand.java
@@ -27,7 +27,10 @@ public class WalCommand extends CommandRegistryImpl {
public WalCommand() {
super(
new WalPrintCommand(),
- new WalDeleteCommand()
+ new WalDeleteCommand(),
+ new WalStateCommand(),
+ new WalDisableCommand(),
+ new WalEnableCommand()
);
}
}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalDisableCommand.java
b/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalDisableCommand.java
new file mode 100644
index 00000000000..9802dc31864
--- /dev/null
+++
b/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalDisableCommand.java
@@ -0,0 +1,51 @@
+/*
+ * 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.management.wal;
+
+import org.apache.ignite.internal.management.api.ComputeCommand;
+
+/** */
+public class WalDisableCommand implements
ComputeCommand<WalDisableCommand.WalDisableCommandArg, Void> {
+ /** {@inheritDoc} */
+ @Override public Class<WalSetStateTask> taskClass() {
+ return WalSetStateTask.class;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String description() {
+ return "Disable WAL for specific cache groups";
+ }
+
+ /** {@inheritDoc} */
+ @Override public Class<WalDisableCommandArg> argClass() {
+ return WalDisableCommandArg.class;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String confirmationPrompt(WalDisableCommandArg arg) {
+ return "Are you sure? Any node failure without WAL can lead to the
loss of all PDS data. CDC events will be lost without WAL.";
+ }
+
+ /** */
+ public static class WalDisableCommandArg extends WalStateCommandArg {
+ /** */
+ private static final long serialVersionUID = 0;
+
+ // No-op.
+ }
+}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalCommand.java
b/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalEnableCommand.java
similarity index 52%
copy from
modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalCommand.java
copy to
modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalEnableCommand.java
index 4e47c3ae3ab..950f416e54a 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalCommand.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalEnableCommand.java
@@ -17,17 +17,31 @@
package org.apache.ignite.internal.management.wal;
-import org.apache.ignite.internal.management.api.CommandRegistryImpl;
-import org.apache.ignite.lang.IgniteExperimental;
+import org.apache.ignite.internal.management.api.ComputeCommand;
+import
org.apache.ignite.internal.management.wal.WalDisableCommand.WalDisableCommandArg;
/** */
-@IgniteExperimental
-public class WalCommand extends CommandRegistryImpl {
+public class WalEnableCommand implements ComputeCommand<WalDisableCommandArg,
Void> {
+ /** {@inheritDoc} */
+ @Override public Class<WalSetStateTask> taskClass() {
+ return WalSetStateTask.class;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String description() {
+ return "Enable WAL for specific cache groups";
+ }
+
+ /** {@inheritDoc} */
+ @Override public Class<WalEnableCommandArg> argClass() {
+ return WalEnableCommandArg.class;
+ }
+
/** */
- public WalCommand() {
- super(
- new WalPrintCommand(),
- new WalDeleteCommand()
- );
+ public static class WalEnableCommandArg extends WalDisableCommandArg {
+ /** */
+ private static final long serialVersionUID = 0;
+
+ // No-op.
}
}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalSetStateTask.java
b/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalSetStateTask.java
new file mode 100644
index 00000000000..63dde2b8606
--- /dev/null
+++
b/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalSetStateTask.java
@@ -0,0 +1,84 @@
+/*
+ * 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.management.wal;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.compute.ComputeJobResult;
+import
org.apache.ignite.internal.management.wal.WalDisableCommand.WalDisableCommandArg;
+import
org.apache.ignite.internal.management.wal.WalEnableCommand.WalEnableCommandArg;
+import org.apache.ignite.internal.processors.cache.CacheGroupContext;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.visor.VisorJob;
+import org.apache.ignite.internal.visor.VisorMultiNodeTask;
+import org.jetbrains.annotations.Nullable;
+
+/** */
+public class WalSetStateTask extends VisorMultiNodeTask<WalDisableCommandArg,
Void, Void> {
+ /** */
+ private static final long serialVersionUID = 0;
+
+ /** {@inheritDoc} */
+ @Override protected VisorJob<WalDisableCommandArg, Void>
job(WalDisableCommandArg arg) {
+ return new WalDisableJob(arg, false);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected @Nullable Void reduce0(List<ComputeJobResult> res)
throws IgniteException {
+ return null;
+ }
+
+ /** */
+ private static class WalDisableJob extends VisorJob<WalDisableCommandArg,
Void> {
+ /** */
+ private static final long serialVersionUID = 0;
+
+ /** */
+ protected WalDisableJob(@Nullable WalDisableCommandArg arg, boolean
debug) {
+ super(arg, debug);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected Void run(@Nullable WalDisableCommandArg arg)
throws IgniteException {
+ Set<String> grps = F.isEmpty(arg.groups()) ? null : new
HashSet<>(Arrays.asList(arg.groups()));
+
+ for (CacheGroupContext gctx :
ignite.context().cache().cacheGroups()) {
+ String grpName = gctx.cacheOrGroupName();
+
+ if (grps != null && !grps.contains(grpName))
+ continue;
+
+ GridCacheContext<?, ?> cctx = F.first(gctx.caches());
+
+ if (cctx == null)
+ continue;
+
+ if (arg instanceof WalEnableCommandArg)
+ ignite.cluster().enableWal(cctx.name());
+ else
+ ignite.cluster().disableWal(cctx.name());
+ }
+
+ return null;
+ }
+ }
+}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalStateCommand.java
b/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalStateCommand.java
new file mode 100644
index 00000000000..2fdda12a704
--- /dev/null
+++
b/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalStateCommand.java
@@ -0,0 +1,79 @@
+/*
+ * 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.management.wal;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+import org.apache.ignite.internal.management.SystemViewCommand;
+import org.apache.ignite.internal.management.api.CommandUtils;
+import org.apache.ignite.internal.management.api.ComputeCommand;
+import org.apache.ignite.internal.management.wal.WalStateTask.GroupWalState;
+import org.apache.ignite.internal.management.wal.WalStateTask.NodeWalState;
+import org.jetbrains.annotations.Nullable;
+
+import static
org.apache.ignite.internal.management.SystemViewTask.SimpleType.STRING;
+
+/** */
+public class WalStateCommand implements ComputeCommand<WalStateCommandArg,
List<NodeWalState>> {
+ /** {@inheritDoc} */
+ @Override public Class<WalStateTask> taskClass() {
+ return WalStateTask.class;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String description() {
+ return "Print state of WAL:\n" +
+ " Global - WAL enabled for group cluster-wide. May be
disabled by `--wal disable` command.\n" +
+ " Local - WAL enabled for group on specific node. May be
disabled during rebalance or other system processes.\n" +
+ " Index - WAL enabled for groups indexes on specific node.
May be disabled during index rebuilt";
+ }
+
+ /** {@inheritDoc} */
+ @Override public Class<WalStateCommandArg> argClass() {
+ return WalStateCommandArg.class;
+ }
+
+ /** {@inheritDoc} */
+ @Override public @Nullable
Collection<org.apache.ignite.cluster.ClusterNode> nodes(
+ Collection<org.apache.ignite.cluster.ClusterNode> nodes,
+ WalStateCommandArg arg
+ ) {
+ return CommandUtils.servers(nodes);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void printResult(WalStateCommandArg arg,
List<NodeWalState> res, Consumer<String> printer) {
+ for (NodeWalState r : res)
+ printer.accept("Node [consistentId=" + r.consId + ", id=" + r.id +
"] config WAL mode: " + r.mode);
+
+ printer.accept("");
+
+ SystemViewCommand.printTable(
+ List.of("Node", "Group", "Persistence", "Global", "Local",
"Index", "CDC"),
+ List.of(STRING, STRING, STRING, STRING, STRING, STRING, STRING),
+ res.stream().flatMap(r -> r.states.entrySet().stream()
+ .map(e -> {
+ GroupWalState s = e.getValue();
+ return List.of(r.consId, e.getKey(),
s.persistenceEnabled(), s.global(), s.local(), s.index(), s.cdc());
+ })).collect(Collectors.toList()),
+ printer
+ );
+ }
+}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalStateCommandArg.java
b/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalStateCommandArg.java
new file mode 100644
index 00000000000..9cf59a5ff9f
--- /dev/null
+++
b/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalStateCommandArg.java
@@ -0,0 +1,58 @@
+/*
+ * 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.management.wal;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import org.apache.ignite.internal.dto.IgniteDataTransferObject;
+import org.apache.ignite.internal.management.api.Argument;
+import org.apache.ignite.internal.util.typedef.internal.U;
+
+/** */
+public class WalStateCommandArg extends IgniteDataTransferObject {
+ /** */
+ private static final long serialVersionUID = 0;
+
+ /** */
+ @Argument(
+ description = "Comma-separated list of cache groups. If not set action
applied to all groups",
+ optional = true
+ )
+ private String[] groups;
+
+ /** {@inheritDoc} */
+ @Override protected void writeExternalData(ObjectOutput out) throws
IOException {
+ U.writeArray(out, groups);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void readExternalData(ObjectInput in) throws
IOException, ClassNotFoundException {
+ groups = U.readArray(in, String.class);
+ }
+
+ /** */
+ public String[] groups() {
+ return groups;
+ }
+
+ /** */
+ public void groups(String[] groups) {
+ this.groups = groups;
+ }
+}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalStateTask.java
b/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalStateTask.java
new file mode 100644
index 00000000000..909b9e94c5d
--- /dev/null
+++
b/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalStateTask.java
@@ -0,0 +1,183 @@
+/*
+ * 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.management.wal;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.stream.Collectors;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.compute.ComputeJobResult;
+import org.apache.ignite.configuration.DataStorageConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.WALMode;
+import org.apache.ignite.internal.processors.cache.CacheGroupContext;
+import org.apache.ignite.internal.processors.task.GridInternal;
+import org.apache.ignite.internal.util.lang.GridTuple5;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.visor.VisorJob;
+import org.apache.ignite.internal.visor.VisorMultiNodeTask;
+import org.jetbrains.annotations.Nullable;
+
+import static
org.apache.ignite.internal.processors.cache.GridCacheUtils.isCdcEnabled;
+import static
org.apache.ignite.internal.processors.cache.GridCacheUtils.isPersistenceEnabled;
+
+/**
+ * Get state of WAL on each server node.
+ */
+@GridInternal
+public class WalStateTask extends
+ VisorMultiNodeTask<WalStateCommandArg, List<WalStateTask.NodeWalState>,
WalStateTask.NodeWalState> {
+ /** */
+ private static final long serialVersionUID = 0;
+
+ /** {@inheritDoc} */
+ @Override protected VisorJob<WalStateCommandArg, NodeWalState>
job(WalStateCommandArg arg) {
+ return new WalStateJob(arg, false);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected @Nullable List<NodeWalState>
reduce0(List<ComputeJobResult> res) throws IgniteException {
+ return res.stream()
+ .peek(r -> {
+ if (r.getException() != null)
+ throw r.getException();
+ })
+ .map(r -> (NodeWalState)r.getData())
+ .collect(Collectors.toList());
+ }
+
+ /** */
+ private static class WalStateJob extends VisorJob<WalStateCommandArg,
NodeWalState> {
+ /** */
+ private static final long serialVersionUID = 0;
+
+ /** */
+ protected WalStateJob(@Nullable WalStateCommandArg arg, boolean debug)
{
+ super(arg, debug);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected NodeWalState run(@Nullable WalStateCommandArg arg)
throws IgniteException {
+ Set<String> grps = F.isEmpty(arg.groups()) ? null : new
HashSet<>(Arrays.asList(arg.groups()));
+
+ Map<String, GroupWalState> res = new HashMap<>();
+
+ for (CacheGroupContext gctx :
ignite.context().cache().cacheGroups()) {
+ String grpName = gctx.cacheOrGroupName();
+
+ if (grps != null && !grps.contains(grpName))
+ continue;
+
+ res.put(
+ grpName,
+ new GroupWalState(
+ gctx.persistenceEnabled(),
+ gctx.globalWalEnabled(),
+ gctx.localWalEnabled(),
+ gctx.indexWalEnabled(),
+ gctx.cdcEnabled()
+ )
+ );
+ }
+
+ DataStorageConfiguration dsCfg =
ignite.configuration().getDataStorageConfiguration();
+
+ return new NodeWalState(
+ ignite.localNode().id(),
+ ignite.localNode().consistentId(),
+ (isPersistenceEnabled(ignite.configuration()) ||
isCdcEnabled(ignite.configuration())) && dsCfg != null
+ ? dsCfg.getWalMode()
+ : null,
+ res
+ );
+ }
+ }
+
+ /** */
+ public static class NodeWalState implements Serializable {
+ /** */
+ private static final long serialVersionUID = 0;
+
+ /** @see IgniteConfiguration#getNodeId() */
+ final UUID id;
+
+ /** @see IgniteConfiguration#getConsistentId() */
+ final Object consId;
+
+ /** @see DataStorageConfiguration#setWalMode(WALMode) */
+ @Nullable final WALMode mode;
+
+ /** */
+ final Map<String, GroupWalState> states;
+
+ /** */
+ public NodeWalState(UUID id, Object consId, @Nullable WALMode mode,
Map<String, GroupWalState> states) {
+ this.id = id;
+ this.consId = consId;
+ this.mode = mode;
+ this.states = states;
+ }
+ }
+
+ /** Global, Local, Index states of WAL for group. */
+ public static class GroupWalState extends GridTuple5<Boolean, Boolean,
Boolean, Boolean, Boolean> {
+ /** */
+ private static final long serialVersionUID = 0;
+
+ /** */
+ public GroupWalState() {
+ // No-op.
+ }
+
+ /** */
+ public GroupWalState(boolean val1, boolean val2, boolean val3, boolean
val4, boolean val5) {
+ super(val1, val2, val3, val4, val5);
+ }
+
+ /** */
+ boolean persistenceEnabled() {
+ return get1();
+ }
+
+ /** */
+ boolean global() {
+ return get2();
+ }
+
+ /** */
+ boolean local() {
+ return get3();
+ }
+
+ /** */
+ boolean index() {
+ return get4();
+ }
+
+ /** */
+ boolean cdc() {
+ return get5();
+ }
+ }
+}
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 662227a1938..35a0878fec5 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
@@ -88,6 +88,27 @@ This utility can do the following commands:
Delete unused archived wal segments on each node:
control.(sh|bat) --wal delete
[consistentId1,consistentId2,....,consistentIdN] [--yes]
+ Print state of WAL:
+ Global - WAL enabled for group cluster-wide. May be disabled by `--wal
disable` command.
+ Local - WAL enabled for group on specific node. May be disabled
during rebalance or other system processes.
+ Index - WAL enabled for groups indexes on specific node. May be
disabled during index rebuilt:
+ control.(sh|bat) --wal state [--groups group1[,group2,....,groupN]]
+
+ Parameters:
+ --groups group1[,group2,....,groupN] - Comma-separated list of cache
groups. If not set action applied to all groups.
+
+ Disable WAL for specific cache groups:
+ control.(sh|bat) --wal disable [--groups group1[,group2,....,groupN]]
+
+ Parameters:
+ --groups group1[,group2,....,groupN] - Comma-separated list of cache
groups. If not set action applied to all groups.
+
+ Enable WAL for specific cache groups:
+ control.(sh|bat) --wal enable [--groups group1[,group2,....,groupN]]
+
+ Parameters:
+ --groups group1[,group2,....,groupN] - Comma-separated list of cache
groups. If not set action applied to all groups.
+
Print diagnostic command help:
control.(sh|bat) --diagnostic
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 4ca9e56b1ea..bd8712d6147 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
@@ -88,6 +88,27 @@ This utility can do the following commands:
Delete unused archived wal segments on each node:
control.(sh|bat) --wal delete
[consistentId1,consistentId2,....,consistentIdN] [--yes]
+ Print state of WAL:
+ Global - WAL enabled for group cluster-wide. May be disabled by `--wal
disable` command.
+ Local - WAL enabled for group on specific node. May be disabled
during rebalance or other system processes.
+ Index - WAL enabled for groups indexes on specific node. May be
disabled during index rebuilt:
+ control.(sh|bat) --wal state [--groups group1[,group2,....,groupN]]
+
+ Parameters:
+ --groups group1[,group2,....,groupN] - Comma-separated list of cache
groups. If not set action applied to all groups.
+
+ Disable WAL for specific cache groups:
+ control.(sh|bat) --wal disable [--groups group1[,group2,....,groupN]]
+
+ Parameters:
+ --groups group1[,group2,....,groupN] - Comma-separated list of cache
groups. If not set action applied to all groups.
+
+ Enable WAL for specific cache groups:
+ control.(sh|bat) --wal enable [--groups group1[,group2,....,groupN]]
+
+ Parameters:
+ --groups group1[,group2,....,groupN] - Comma-separated list of cache
groups. If not set action applied to all groups.
+
Print diagnostic command help:
control.(sh|bat) --diagnostic