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
 


Reply via email to