Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.Objects;
import java.util.regex.Pattern;
import org.apache.ignite.cluster.ClusterState;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.DataRegionConfiguration;
import org.apache.ignite.configuration.DataStorageConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
Expand Down Expand Up @@ -171,6 +172,36 @@ public void testWalStateInMemoryCdcCluster() throws Exception {
assertFalse(testOut.toString().contains("cache3"));
}

/**
* Test WAL mode change for a cache group contains multiple caches.
* @throws Exception If failed.
*/
@Test
public void testWalChangeForMultiCacheGroup() throws Exception {
clusterState = 0; // PDS cluster.

IgniteEx srv = startGrids(2);
srv.cluster().state(ClusterState.ACTIVE);

srv.createCache(new CacheConfiguration<>("cache1")
.setGroupName("testGroup"));
srv.createCache(new CacheConfiguration<>("cache2")
.setGroupName("testGroup"));

assertEquals(EXIT_CODE_OK, execute("--wal", "state", "--groups", "testGroup"));
outputContains(".*testGroup.*true.*true.*true.*true.*false");

assertEquals(EXIT_CODE_OK, execute("--wal", "disable", "--groups", "testGroup"));

assertEquals(EXIT_CODE_OK, execute("--wal", "state", "--groups", "testGroup"));
outputContains(".*testGroup.*true.*false.*true.*true.*false");

assertEquals(EXIT_CODE_OK, execute("--wal", "enable", "--groups", "testGroup"));

assertEquals(EXIT_CODE_OK, execute("--wal", "state", "--groups", "testGroup"));
outputContains(".*testGroup.*true.*true.*true.*true.*false");
}

/** */
private void outputContains(String regexp) {
assertTrue(Pattern.compile(regexp).matcher(testOut.toString()).find());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -536,13 +536,13 @@ public IgniteFuture<Collection<ClusterStartNodeResult>> startNodesAsync(Collecti
* Cache may be stuck in inconsistent state due to violation of these conditions. It is advised to destroy
* such cache.
*
* @param cacheName Cache name.
* @param cacheOrGrpName Cache or cache group name.
* @return Whether WAL disabled by this call.
* @throws IgniteException If error occurs.
* @see #enableWal(String)
* @see #isWalEnabled(String)
*/
public boolean disableWal(String cacheName) throws IgniteException;
public boolean disableWal(String cacheOrGrpName) throws IgniteException;

/**
* Enables write-ahead logging for specified cache. Restoring crash-recovery guarantees of a previous call to
Expand All @@ -560,13 +560,13 @@ public IgniteFuture<Collection<ClusterStartNodeResult>> startNodesAsync(Collecti
* Cache may be stuck in inconsistent state due to violation of these conditions. It is advised to destroy
* such cache.
*
* @param cacheName Cache name.
* @param cacheOrGrpName Cache or cache group name.
* @return Whether WAL enabled by this call.
* @throws IgniteException If error occurs.
* @see #disableWal(String)
* @see #isWalEnabled(String)
*/
public boolean enableWal(String cacheName) throws IgniteException;
public boolean enableWal(String cacheOrGrpName) throws IgniteException;

/**
* Checks if write-ahead logging is enabled for specified cache.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -345,13 +345,13 @@ public IgniteClusterAsyncImpl(IgniteClusterImpl cluster) {
}

/** {@inheritDoc} */
@Override public boolean enableWal(String cacheName) throws IgniteException {
return cluster.enableWal(cacheName);
@Override public boolean enableWal(String cacheOrGrpName) throws IgniteException {
return cluster.enableWal(cacheOrGrpName);
}

/** {@inheritDoc} */
@Override public boolean disableWal(String cacheName) throws IgniteException {
return cluster.disableWal(cacheName);
@Override public boolean disableWal(String cacheOrGrpName) throws IgniteException {
return cluster.disableWal(cacheOrGrpName);
}

/** {@inheritDoc} */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import org.apache.ignite.internal.GridKernalContext;
import org.apache.ignite.internal.IgniteComponentType;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.processors.cache.CacheGroupDescriptor;
import org.apache.ignite.internal.processors.cache.DynamicCacheDescriptor;
import org.apache.ignite.internal.processors.cluster.BaselineTopology;
import org.apache.ignite.internal.processors.cluster.baseline.autoadjust.BaselineAutoAdjustStatus;
Expand Down Expand Up @@ -631,29 +632,44 @@ private void setBaselineTopology(long topVer, boolean isBaselineAutoAdjust) {
}

/** {@inheritDoc} */
@Override public boolean enableWal(String cacheName) throws IgniteException {
return changeWalMode(cacheName, true);
@Override public boolean enableWal(String cacheOrGrpName) throws IgniteException {
return changeWalMode(cacheOrGrpName, true);
}

/** {@inheritDoc} */
@Override public boolean disableWal(String cacheName) throws IgniteException {
return changeWalMode(cacheName, false);
@Override public boolean disableWal(String cacheOrGrpName) throws IgniteException {
return changeWalMode(cacheOrGrpName, false);
}

/**
* Change WAL mode.
*
* @param cacheName Cache name.
* @param cacheOrGrpName Cache or cache group name.
* @param enabled Enabled flag.
* @return {@code True} if WAL mode was changed as a result of this call.
*/
private boolean changeWalMode(String cacheName, boolean enabled) {
A.notNull(cacheName, "cacheName");
private boolean changeWalMode(String cacheOrGrpName, boolean enabled) {
A.notNull(cacheOrGrpName, "cacheOrGrpName");

guard();

try {
return ctx.cache().context().walState().changeWalMode(Collections.singleton(cacheName), enabled).get();
Collection<String> cacheNames;

int cacheOrGrpId = CU.cacheId(cacheOrGrpName);
CacheGroupDescriptor grpDesc = ctx.cache().cacheGroupDescriptor(cacheOrGrpId);

if (grpDesc != null) {
Map<String, Integer> cachesInGrp = grpDesc.caches();
if (cachesInGrp.isEmpty())
throw new IgniteException("Cache group '" + cacheOrGrpName + "' does not contain any caches.");
else
cacheNames = cachesInGrp.keySet();
}
else
cacheNames = Collections.singleton(cacheOrGrpName);

return ctx.cache().context().walState().changeWalMode(cacheNames, enabled).get();
}
catch (IgniteCheckedException e) {
throw U.convertException(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
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;
Expand Down Expand Up @@ -67,15 +66,10 @@ protected WalDisableJob(@Nullable WalDisableCommandArg arg, boolean debug) {
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());
ignite.cluster().enableWal(grpName);
else
ignite.cluster().disableWal(cctx.name());
ignite.cluster().disableWal(grpName);
}

return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteException;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.internal.IgniteClientReconnectAbstractTest;
import org.apache.ignite.internal.IgniteEx;
import org.apache.ignite.internal.IgniteInternalFuture;
Expand Down Expand Up @@ -566,7 +567,8 @@ public void testCacheDestroy() throws Exception {
String msg = e.getMessage();

assert msg.startsWith("Cache doesn't exist") ||
msg.startsWith("Failed to change WAL mode because some caches no longer exist") :
msg.startsWith("Failed to change WAL mode because some caches no longer exist") ||
msg.startsWith("Cache group") && msg.contains("does not contain any caches") :
e.getMessage();
}
finally {
Expand Down Expand Up @@ -699,4 +701,91 @@ private static void checkConcurrentOperations(AtomicBoolean done, Ignite node) {
throw new RuntimeException(e);
}
}

/**
* Test that WAL mode change for caches from the same group requires all caches to be specified.
*
* @throws Exception If failed.
*/
@Test
public void testWalModeChangeRequiresAllGroupCaches() throws Exception {
IgniteEx srv = startGrid(config(SRV_1, false, false));

srv.cluster().state(ACTIVE);

CacheConfiguration<Integer, Integer> cacheCfg1 = cacheConfig(CACHE_NAME, PARTITIONED, TRANSACTIONAL);
CacheConfiguration<Integer, Integer> cacheCfg2 = cacheConfig(CACHE_NAME_2, PARTITIONED, TRANSACTIONAL);

cacheCfg1.setGroupName("testGroup");
cacheCfg2.setGroupName("testGroup");

srv.getOrCreateCache(cacheCfg1);
srv.getOrCreateCache(cacheCfg2);

assertForAllNodes(CACHE_NAME, true);
assertForAllNodes(CACHE_NAME_2, true);

assertThrows(
() -> {
srv.cluster().disableWal(CACHE_NAME);
return null;
},
IgniteException.class,
"Cannot change WAL mode because not all cache names belonging to the group are provided"
);

assertThrows(
() -> {
srv.cluster().disableWal(CACHE_NAME_2);
return null;
},
IgniteException.class,
"Cannot change WAL mode because not all cache names belonging to the group are provided"
);

assertForAllNodes(CACHE_NAME, true);
assertForAllNodes(CACHE_NAME_2, true);

assertThrows(
() -> {
srv.cluster().enableWal(CACHE_NAME);
return null;
},
IgniteException.class,
"Cannot change WAL mode because not all cache names belonging to the group are provided"
);

srv.cluster().disableWal("testGroup");

assertForAllNodes(CACHE_NAME, false);
assertForAllNodes(CACHE_NAME_2, false);

assertThrows(
() -> {
srv.cluster().enableWal(CACHE_NAME_2);
return null;
},
IgniteException.class,
"Cannot change WAL mode because not all cache names belonging to the group are provided"
);

srv.cluster().enableWal("testGroup");

assertForAllNodes(CACHE_NAME, true);
assertForAllNodes(CACHE_NAME_2, true);

srv.destroyCache(CACHE_NAME_2);

srv.cluster().disableWal(CACHE_NAME);
assertForAllNodes(CACHE_NAME, false);

srv.cluster().enableWal("testGroup");
assertForAllNodes(CACHE_NAME, true);

srv.cluster().disableWal("testGroup");
assertForAllNodes(CACHE_NAME, false);

srv.cluster().enableWal(CACHE_NAME);
assertForAllNodes(CACHE_NAME, true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,12 @@ public IgniteClusterProcessProxy(IgniteProcessProxy proxy) {
}

/** {@inheritDoc} */
@Override public boolean enableWal(String cacheName) throws IgniteException {
@Override public boolean enableWal(String cacheOrGrpName) throws IgniteException {
throw new UnsupportedOperationException("Operation is not supported yet.");
}

/** {@inheritDoc} */
@Override public boolean disableWal(String cacheName) throws IgniteException {
@Override public boolean disableWal(String cacheOrGrpName) throws IgniteException {
throw new UnsupportedOperationException("Operation is not supported yet.");
}

Expand Down
Loading