This is an automated email from the ASF dual-hosted git repository. ilyak 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 f806b01 IGNITE-13658 Introduce volatileDsMemPlc for volatile data structures caches f806b01 is described below commit f806b014c02f55490e09e01673aa729e8b67e6b2 Author: zstan <stanilov...@gmail.com> AuthorDate: Thu Nov 5 17:50:20 2020 +0300 IGNITE-13658 Introduce volatileDsMemPlc for volatile data structures caches Implement checking for volatile data region feature. Always start and use volatile data region, since only a subset of nodes may be persistent. Fixes #8423. Signed-off-by: Ilya Kasnacheev <ilya.kasnach...@gmail.com> --- .../util/GridCommandHandlerClusterByClassTest.java | 18 ++- .../org/apache/ignite/internal/IgniteFeatures.java | 3 + .../dht/GridDhtTopologyFutureAdapter.java | 9 +- .../IgniteCacheDatabaseSharedManager.java | 34 +++- .../datastructures/DataStructuresProcessor.java | 29 +++- .../internal/GridNodeMetricsLogSelfTest.java | 6 +- .../GridCacheConfigurationValidationSelfTest.java | 10 ++ .../OutOfMemoryVolatileRegionTest.java | 175 +++++++++++++++++++++ .../MemoryPolicyInitializationTest.java | 12 +- .../IgniteCacheDataStructuresSelfTestSuite.java | 2 + .../Cache/DataRegionMetricsTest.cs | 13 +- .../Cache/MemoryMetricsTest.cs | 10 +- 12 files changed, 293 insertions(+), 28 deletions(-) diff --git a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerClusterByClassTest.java b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerClusterByClassTest.java index 4403e38..a8dc398 100644 --- a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerClusterByClassTest.java +++ b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerClusterByClassTest.java @@ -891,15 +891,18 @@ public class GridCommandHandlerClusterByClassTest extends GridCommandHandlerClus corruptDataEntry(storedSysCacheCtx.caches().get(0), new GridCacheInternalKeyImpl("sq" + parts / 2, "default-ds-group"), false, true); - CacheGroupContext memorySysCacheCtx = ignite.context().cache().cacheGroup(CU.cacheId("default-volatile-ds-group")); + CacheGroupContext memoryVolatileCacheCtx = ignite.context().cache().cacheGroup(CU.cacheId( + "default-volatile-ds-group@volatileDsMemPlc")); - assertNotNull(memorySysCacheCtx); + assertNotNull(memoryVolatileCacheCtx); + assertEquals("volatileDsMemPlc", memoryVolatileCacheCtx.dataRegion().config().getName()); + assertEquals(false, memoryVolatileCacheCtx.dataRegion().config().isPersistenceEnabled()); - corruptDataEntry(memorySysCacheCtx.caches().get(0), new GridCacheInternalKeyImpl("s0", - "default-volatile-ds-group"), true, false); + corruptDataEntry(memoryVolatileCacheCtx.caches().get(0), new GridCacheInternalKeyImpl("s0", + "default-volatile-ds-group@volatileDsMemPlc"), true, false); - corruptDataEntry(memorySysCacheCtx.caches().get(0), new GridCacheInternalKeyImpl("s" + parts / 2, - "default-volatile-ds-group"), false, true); + corruptDataEntry(memoryVolatileCacheCtx.caches().get(0), new GridCacheInternalKeyImpl("s" + parts / 2, + "default-volatile-ds-group@volatileDsMemPlc"), false, true); assertEquals(EXIT_CODE_OK, execute("--cache", "idle_verify", "--dump", "--cache-filter", "SYSTEM")); @@ -910,7 +913,8 @@ public class GridCommandHandlerClusterByClassTest extends GridCommandHandlerClus U.log(log, dumpWithConflicts); - assertContains(log, dumpWithConflicts, "found 4 conflict partitions: [counterConflicts=2, " + + // Non-persistent caches do not have counter conflicts + assertContains(log, dumpWithConflicts, "found 3 conflict partitions: [counterConflicts=1, " + "hashConflicts=2]"); } else diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteFeatures.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteFeatures.java index e1f09e5..f9704ae 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteFeatures.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteFeatures.java @@ -108,6 +108,9 @@ public enum IgniteFeatures { /** Distributed change timeout for dump long operations. */ DISTRIBUTED_CHANGE_LONG_OPERATIONS_DUMP_TIMEOUT(30), + /** New region for volatile data. */ + VOLATILE_DATA_STRUCTURES_REGION(33), + /** Check secondary indexes inline size on join/by control utility request. */ CHECK_INDEX_INLINE_SIZES(36), diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTopologyFutureAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTopologyFutureAdapter.java index b5e5590..3f637c52 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTopologyFutureAdapter.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTopologyFutureAdapter.java @@ -33,7 +33,6 @@ import org.jetbrains.annotations.Nullable; import static java.lang.String.format; import static org.apache.ignite.cache.PartitionLossPolicy.READ_ONLY_ALL; import static org.apache.ignite.cache.PartitionLossPolicy.READ_ONLY_SAFE; -import static org.apache.ignite.internal.processors.cache.GridCacheProcessor.CLUSTER_READ_ONLY_MODE_ERROR_MSG_FORMAT; import static org.apache.ignite.internal.processors.cache.GridCacheUtils.isSystemCache; /** @@ -41,6 +40,10 @@ import static org.apache.ignite.internal.processors.cache.GridCacheUtils.isSyste */ public abstract class GridDhtTopologyFutureAdapter extends GridFutureAdapter<AffinityTopologyVersion> implements GridDhtTopologyFuture { + /** Error message format if cluster in read-only mode and write operation tries to execute.*/ + private static final String CLUSTER_READ_ONLY_ERROR_MSG = + "Failed to perform cache operation (cluster is in read-only mode) [cacheGrp=%s, cache=%s]"; + /** Cache groups validation results. */ protected volatile Map<Integer, CacheGroupValidation> grpValidRes = Collections.emptyMap(); @@ -85,7 +88,7 @@ public abstract class GridDhtTopologyFutureAdapter extends GridFutureAdapter<Aff if (!clusterIsActive) { return new CacheInvalidStateException( - "Failed to perform cache operation (cluster is not activated): " + cctx.name()); + "Failed to perform cache operation (cluster is not activated): " + cctx.name()); } if (cctx.cache() == null) @@ -96,7 +99,7 @@ public abstract class GridDhtTopologyFutureAdapter extends GridFutureAdapter<Aff if (cctx.shared().readOnlyMode() && !read && !isSystemCache(cctx.name())) { return new CacheInvalidStateException(new IgniteClusterReadOnlyException( - format(CLUSTER_READ_ONLY_MODE_ERROR_MSG_FORMAT, "cache", cctx.group().name(), cctx.name()) + format(CLUSTER_READ_ONLY_ERROR_MSG, grp.name(), cctx.name()) )); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IgniteCacheDatabaseSharedManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IgniteCacheDatabaseSharedManager.java index 5f93734..1d77566 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IgniteCacheDatabaseSharedManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IgniteCacheDatabaseSharedManager.java @@ -103,6 +103,7 @@ import static org.apache.ignite.configuration.DataStorageConfiguration.DFLT_WAL_ import static org.apache.ignite.configuration.DataStorageConfiguration.DFLT_WAL_HISTORY_SIZE; import static org.apache.ignite.internal.processors.cache.mvcc.txlog.TxLog.TX_LOG_CACHE_NAME; import static org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager.METASTORE_DATA_REGION_NAME; +import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.VOLATILE_DATA_REGION_NAME; /** * @@ -363,6 +364,8 @@ public class IgniteCacheDatabaseSharedManager extends GridCacheSharedManagerAdap protected void initDataRegions0(DataStorageConfiguration memCfg) throws IgniteCheckedException { DataRegionConfiguration[] dataRegionCfgs = memCfg.getDataRegionConfigurations(); + boolean persistenceEnabled = CU.isPersistenceEnabled(memCfg); + if (dataRegionCfgs != null) { for (DataRegionConfiguration dataRegionCfg : dataRegionCfgs) addDataRegion(memCfg, dataRegionCfg, dataRegionCfg.isPersistenceEnabled()); @@ -379,9 +382,18 @@ public class IgniteCacheDatabaseSharedManager extends GridCacheSharedManagerAdap createSystemDataRegion( memCfg.getSystemRegionInitialSize(), memCfg.getSystemRegionMaxSize(), - CU.isPersistenceEnabled(memCfg) + persistenceEnabled + ), + persistenceEnabled + ); + + addDataRegion( + memCfg, + createVolatileDataRegion( + memCfg.getSystemRegionInitialSize(), + memCfg.getSystemRegionMaxSize() ), - CU.isPersistenceEnabled(memCfg) + false ); for (DatabaseLifecycleListener lsnr : getDatabaseListeners(cctx.kernalContext())) @@ -533,8 +545,24 @@ public class IgniteCacheDatabaseSharedManager extends GridCacheSharedManagerAdap } /** - * Validation of memory configuration. + * @param volatileCacheInitSize Initial size of PageMemory to be created for volatile cache. + * @param volatileCacheMaxSize Maximum size of PageMemory to be created for volatile cache. * + * @return {@link DataRegionConfiguration configuration} of DataRegion for volatile cache. + */ + private DataRegionConfiguration createVolatileDataRegion(long volatileCacheInitSize, long volatileCacheMaxSize) { + DataRegionConfiguration res = new DataRegionConfiguration(); + + res.setName(VOLATILE_DATA_REGION_NAME); + res.setInitialSize(volatileCacheInitSize); + res.setMaxSize(volatileCacheMaxSize); + res.setPersistenceEnabled(false); + res.setLazyMemoryAllocation(true); + + return res; + } + + /** * @param memCfg configuration to validate. * @throws IgniteCheckedException In case of validation violation. */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/DataStructuresProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/DataStructuresProcessor.java index e72692d..232f5fc 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/DataStructuresProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/DataStructuresProcessor.java @@ -105,6 +105,9 @@ import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_REA * Manager of data structures. */ public final class DataStructuresProcessor extends GridProcessorAdapter implements IgniteChangeGlobalStateSupport { + /** DataRegionConfiguration name reserved for volatile caches. */ + public static final String VOLATILE_DATA_REGION_NAME = "volatileDsMemPlc"; + /** */ public static final String DEFAULT_VOLATILE_DS_GROUP_NAME = "default-volatile-ds-group"; @@ -359,8 +362,9 @@ public final class DataStructuresProcessor extends GridProcessorAdapter implemen * @return {@code True} if group name is reserved to store data structures. */ public static boolean isReservedGroup(@Nullable String grpName) { - return DEFAULT_DS_GROUP_NAME.equals(grpName) || - DEFAULT_VOLATILE_DS_GROUP_NAME.equals(grpName); + return grpName != null && + (DEFAULT_DS_GROUP_NAME.equals(grpName) || + grpName.startsWith(DEFAULT_VOLATILE_DS_GROUP_NAME)); } /** @@ -511,11 +515,18 @@ public final class DataStructuresProcessor extends GridProcessorAdapter implemen cfg = dfltAtomicCfg; } + String dataRegionName = null; final String grpName; - if (type.isVolatile()) - grpName = DEFAULT_VOLATILE_DS_GROUP_NAME; - else if (cfg.getGroupName() != null) + if (type.isVolatile()) { + String volatileGrpName = DEFAULT_VOLATILE_DS_GROUP_NAME; + + dataRegionName = VOLATILE_DATA_REGION_NAME; + + volatileGrpName += "@" + dataRegionName; + + grpName = volatileGrpName; + } else if (cfg.getGroupName() != null) grpName = cfg.getGroupName(); else grpName = DEFAULT_DS_GROUP_NAME; @@ -528,7 +539,7 @@ public final class DataStructuresProcessor extends GridProcessorAdapter implemen if (!create && ctx.cache().cacheDescriptor(cacheName) == null) return null; - ctx.cache().dynamicStartCache(cacheConfiguration(cfg, cacheName, grpName), + ctx.cache().dynamicStartCache(cacheConfiguration(cfg, cacheName, grpName, dataRegionName), cacheName, null, CacheType.DATA_STRUCTURES, @@ -888,9 +899,12 @@ public final class DataStructuresProcessor extends GridProcessorAdapter implemen * @param cfg Atomic configuration. * @param name Cache name. * @param grpName Group name. + * @param dataRegionName Name of data region for this cache. + * * @return Cache configuration. */ - private CacheConfiguration cacheConfiguration(AtomicConfiguration cfg, String name, String grpName) { + private CacheConfiguration cacheConfiguration(AtomicConfiguration cfg, String name, String grpName, + String dataRegionName) { CacheConfiguration ccfg = new CacheConfiguration(); ccfg.setName(name); @@ -901,6 +915,7 @@ public final class DataStructuresProcessor extends GridProcessorAdapter implemen ccfg.setCacheMode(cfg.getCacheMode()); ccfg.setNodeFilter(CacheConfiguration.ALL_NODES); ccfg.setAffinity(cfg.getAffinity()); + ccfg.setDataRegionName(dataRegionName); if (cfg.getCacheMode() == PARTITIONED) ccfg.setBackups(cfg.getBackups()); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/GridNodeMetricsLogSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/GridNodeMetricsLogSelfTest.java index 3557994..57a1599 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/GridNodeMetricsLogSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/GridNodeMetricsLogSelfTest.java @@ -25,6 +25,7 @@ import java.util.stream.Collectors; import org.apache.ignite.IgniteCache; import org.apache.ignite.configuration.ExecutorConfiguration; import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.testframework.GridStringLogger; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; @@ -163,11 +164,14 @@ public class GridNodeMetricsLogSelfTest extends GridCommonAbstractTest { } else assertTrue(F.isEmpty(matcher.group("total"))); - regions.add(matcher.group("name").trim()); + String regName = matcher.group("name").trim(); + + regions.add(regName); } Set<String> expRegions = grid(0).context().cache().context().database().dataRegions().stream() .map(v -> v.config().getName().trim()) + .filter(regName -> !DataStructuresProcessor.VOLATILE_DATA_REGION_NAME.equals(regName)) .collect(Collectors.toSet()); assertFalse("No data regions in the log.", regions.isEmpty()); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConfigurationValidationSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConfigurationValidationSelfTest.java index b57c208..2a084f5 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConfigurationValidationSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheConfigurationValidationSelfTest.java @@ -64,6 +64,10 @@ public class GridCacheConfigurationValidationSelfTest extends GridCommonAbstract "reservedForDsCacheGroupNameCheckFails"; /** */ + private static final String RESERVED_FOR_VOLATILE_DATASTRUCTURES_CACHE_GROUP_NAME_IGNITE_INSTANCE_NAME = + "reservedForVolatileDsCacheGroupNameCheckFails"; + + /** */ private static final String CACHE_NAME_WITH_SPECIAL_CHARACTERS_REPLICATED = "--№=+:(replicated)"; /** */ @@ -135,6 +139,9 @@ public class GridCacheConfigurationValidationSelfTest extends GridCommonAbstract if (igniteInstanceName.contains(RESERVED_FOR_DATASTRUCTURES_CACHE_GROUP_NAME_IGNITE_INSTANCE_NAME)) namedCacheCfg.setGroupName("default-ds-group"); + if (igniteInstanceName.contains(RESERVED_FOR_VOLATILE_DATASTRUCTURES_CACHE_GROUP_NAME_IGNITE_INSTANCE_NAME)) + namedCacheCfg.setGroupName("default-volatile-ds-group@volatileDsMemPlc"); + return cfg; } @@ -178,6 +185,9 @@ public class GridCacheConfigurationValidationSelfTest extends GridCommonAbstract // This grid should not start. startInvalidGrid(RESERVED_FOR_DATASTRUCTURES_CACHE_GROUP_NAME_IGNITE_INSTANCE_NAME); + // This grid should not start. + startInvalidGrid(RESERVED_FOR_VOLATILE_DATASTRUCTURES_CACHE_GROUP_NAME_IGNITE_INSTANCE_NAME); + // This grid will start normally. startGrid(1); } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/OutOfMemoryVolatileRegionTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/OutOfMemoryVolatileRegionTest.java new file mode 100644 index 0000000..58e6290 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/datastructures/OutOfMemoryVolatileRegionTest.java @@ -0,0 +1,175 @@ +/* + * 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.processors.cache.datastructures; + +import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.cache.CacheAtomicityMode; +import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.DataRegionConfiguration; +import org.apache.ignite.configuration.DataStorageConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.failure.AbstractFailureHandler; +import org.apache.ignite.failure.FailureContext; +import org.apache.ignite.internal.mem.IgniteOutOfMemoryException; +import org.apache.ignite.internal.util.typedef.X; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; +import org.junit.Test; + +import static org.apache.ignite.cache.CacheAtomicityMode.ATOMIC; +import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL; + +/** + * Tests behavior of volatile data structures and regular caches + * when {@link IgniteOutOfMemoryException} is thrown. + */ +public class OutOfMemoryVolatileRegionTest extends GridCommonAbstractTest { + /** Minimal region size. */ + private static final long DATA_REGION_SIZE = 15L * 1024 * 1024; + + /** */ + private static final int ATTEMPTS_NUM = 3; + + /** Failure handler triggered. */ + private static volatile boolean failure; + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(gridName); + + cfg.setDataStorageConfiguration(new DataStorageConfiguration() + .setPageSize(4096) + .setSystemRegionInitialSize(DATA_REGION_SIZE) + .setSystemRegionMaxSize(DATA_REGION_SIZE) + .setDefaultDataRegionConfiguration( + new DataRegionConfiguration() + .setPersistenceEnabled(true) + .setMetricsEnabled(true))); + + cfg.setFailureHandler(new AbstractFailureHandler() { + /** {@inheritDoc} */ + @Override protected boolean handle(Ignite ignite, FailureContext failureCtx) { + failure = true; + + // Do not invalidate a node context. + return false; + } + }); + + cfg.setCacheConfiguration(cacheConfiguration(ATOMIC), cacheConfiguration(TRANSACTIONAL)); + + return cfg; + } + + /** + * Creates a new cache configuration with the given cache atomicity mode. + * + * @param mode Cache atomicity mode. + * @return Cache configuration. + */ + private CacheConfiguration cacheConfiguration(CacheAtomicityMode mode) { + return new CacheConfiguration(mode.name()) + .setAtomicityMode(mode) + .setAffinity(new RendezvousAffinityFunction(false, 32)); + } + + /** {@inheritDoc} */ + @Override protected void beforeTestsStarted() throws Exception { + cleanPersistenceDir(); + + startGrid(0); + startGrid(1); + } + + /** {@inheritDoc} */ + @Override protected void afterTestsStopped() throws Exception { + stopAllGrids(); + + cleanPersistenceDir(); + } + + /** + * @throws Exception If failed. + */ + @Test + public void testLoadAndClearAtomicCache() throws Exception { + loadAndClearCache(ATOMIC, ATTEMPTS_NUM); + } + + /** + * @throws Exception If failed. + */ + @Test + public void testLoadAndClearTransactionalCache() throws Exception { + loadAndClearCache(TRANSACTIONAL, ATTEMPTS_NUM); + } + + /** + * Creates a new cache with the given atomicity node and tries to load & clear it in a loop. + * It is assumed that {@link IgniteOutOfMemoryException} is thrown during loading the cache, + * however {@link IgniteCache#clear()} should return the cache to the operable state. + * + * @param mode Cache atomicity mode. + * @param attempts Number of attempts to load and clear the cache. + */ + private void loadAndClearCache(CacheAtomicityMode mode, int attempts) { + grid(0).cluster().active(true); + + failure = false; + + IgniteCache<Object, Object> cache = grid(0).cache(mode.name()); + + for (int i = 0; i < attempts; ++i) { + for (int key = 0; key < 5_000; ++key) + cache.put(key, new byte[40]); + + cache.clear(); + } + + assertFalse("Failure handler should not be notified", failure); + + try { + for (int j = 0; j < 100000; j++) { + grid(0).reentrantLock("l" + getClass().getName() + j, + j % 2 == 0, j % 3 == 0, true); + grid(1).semaphore("s" + getClass().getName() + j, + 1 + (j % 7), j % 3 == 0, true); + grid(0).countDownLatch("c" + getClass().getName() + j, + 1 + (j % 13), j % 2 == 0, true); + } + + fail("OutOfMemoryException hasn't been thrown"); + } + catch (Exception e) { + if (!X.hasCause(e, IgniteOutOfMemoryException.class)) + fail("Unexpected exception" + e); + + log.info("Expected exception, n: " + e); + } + + assertTrue("Failure handler wasn't notified", failure); + + for (int i = 0; i < attempts; ++i) { + for (int key = 0; key < 5_000; ++key) + cache.put(key, new byte[40]); + + cache.clear(); + } + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/MemoryPolicyInitializationTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/MemoryPolicyInitializationTest.java index 1864c0b..cee869f 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/MemoryPolicyInitializationTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/MemoryPolicyInitializationTest.java @@ -30,6 +30,7 @@ import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; import org.junit.Test; import static org.apache.ignite.configuration.MemoryConfiguration.DFLT_MEM_PLC_DEFAULT_NAME; +import static org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor.VOLATILE_DATA_REGION_NAME; /** * @@ -77,7 +78,7 @@ public class MemoryPolicyInitializationTest extends GridCommonAbstractTest { Collection<DataRegion> allMemPlcs = ignite.context().cache().context().database().dataRegions(); - assertEquals(3, allMemPlcs.size()); + assertEquals(4, allMemPlcs.size()); verifyDefaultAndSystemMemoryPolicies(allMemPlcs); } @@ -94,7 +95,7 @@ public class MemoryPolicyInitializationTest extends GridCommonAbstractTest { Collection<DataRegion> allMemPlcs = ignite.context().cache().context().database().dataRegions(); - assertEquals(4, allMemPlcs.size()); + assertEquals(5, allMemPlcs.size()); verifyDefaultAndSystemMemoryPolicies(allMemPlcs); @@ -116,7 +117,7 @@ public class MemoryPolicyInitializationTest extends GridCommonAbstractTest { Collection<DataRegion> allMemPlcs = dbMgr.dataRegions(); - assertEquals(3, allMemPlcs.size()); + assertEquals(4, allMemPlcs.size()); verifyDefaultAndSystemMemoryPolicies(allMemPlcs); @@ -141,7 +142,7 @@ public class MemoryPolicyInitializationTest extends GridCommonAbstractTest { Collection<DataRegion> allMemPlcs = dbMgr.dataRegions(); - assertEquals(4, allMemPlcs.size()); + assertEquals(5, allMemPlcs.size()); verifyDefaultAndSystemMemoryPolicies(allMemPlcs); @@ -290,6 +291,9 @@ public class MemoryPolicyInitializationTest extends GridCommonAbstractTest { assertTrue("System memory policy is not presented", isMemoryPolicyPresented(allMemPlcs, IgniteCacheDatabaseSharedManager.SYSTEM_DATA_REGION_NAME)); + + assertTrue("Volatile memory policy is not presented", + isMemoryPolicyPresented(allMemPlcs, VOLATILE_DATA_REGION_NAME)); } /** diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheDataStructuresSelfTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheDataStructuresSelfTestSuite.java index 0e09d4c..4a1abc1 100644 --- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheDataStructuresSelfTestSuite.java +++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheDataStructuresSelfTestSuite.java @@ -41,6 +41,7 @@ import org.apache.ignite.internal.processors.cache.datastructures.IgniteDataStru import org.apache.ignite.internal.processors.cache.datastructures.IgniteQueueClusterReadOnlyTest; import org.apache.ignite.internal.processors.cache.datastructures.IgniteSequenceInternalCleanupTest; import org.apache.ignite.internal.processors.cache.datastructures.IgniteSetClusterReadOnlyTest; +import org.apache.ignite.internal.processors.cache.datastructures.OutOfMemoryVolatileRegionTest; import org.apache.ignite.internal.processors.cache.datastructures.SemaphoreFailoverNoWaitingAcquirerTest; import org.apache.ignite.internal.processors.cache.datastructures.SemaphoreFailoverSafeReleasePermitsTest; import org.apache.ignite.internal.processors.cache.datastructures.local.GridCacheLocalAtomicQueueApiSelfTest; @@ -134,6 +135,7 @@ import org.junit.runners.Suite; IgniteReplicatedLockSelfTest.class, IgniteCacheAtomicReplicatedNodeRestartSelfTest.class, GridCacheReplicatedQueueRemoveSelfTest.class, + OutOfMemoryVolatileRegionTest.class, GridCachePartitionedSequenceApiSelfTest.class, GridCachePartitionedSequenceMultiNodeSelfTest.class, diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/DataRegionMetricsTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/DataRegionMetricsTest.cs index d0b7332..4c26d0a 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/DataRegionMetricsTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/DataRegionMetricsTest.cs @@ -73,7 +73,8 @@ namespace Apache.Ignite.Core.Tests.Cache RegionWithMetrics, RegionWithMetricsAndPersistence, "sysMemPlc", - "TxLog" + "TxLog", + "volatileDsMemPlc" }, names, string.Join(", ", names)); @@ -96,11 +97,15 @@ namespace Apache.Ignite.Core.Tests.Cache memMetrics.PhysicalMemoryPages * (memMetrics.PageSize + PageOverhead)); Assert.Greater(memMetrics.OffHeapSize, memMetrics.PhysicalMemoryPages); Assert.Greater(memMetrics.OffheapUsedSize, memMetrics.PhysicalMemoryPages); - + var sysMetrics = metrics[4]; Assert.AreEqual("sysMemPlc", sysMetrics.Name); AssertMetricsAreEmpty(sysMetrics); + var volatileMetrics = metrics[6]; + Assert.AreEqual("volatileDsMemPlc", volatileMetrics.Name); + AssertMetricsAreEmpty(volatileMetrics); + // Metrics by name. // In-memory region. emptyMetrics = ignite.GetDataRegionMetrics(RegionNoMetrics); @@ -120,6 +125,10 @@ namespace Apache.Ignite.Core.Tests.Cache Assert.AreEqual("sysMemPlc", sysMetrics.Name); AssertMetricsAreEmpty(sysMetrics); + volatileMetrics = ignite.GetDataRegionMetrics("volatileDsMemPlc"); + Assert.AreEqual("volatileDsMemPlc", volatileMetrics.Name); + AssertMetricsAreEmpty(volatileMetrics); + // Invalid name. Assert.IsNull(ignite.GetDataRegionMetrics("boo")); } diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/MemoryMetricsTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/MemoryMetricsTest.cs index 352c1e9..a2b1c87 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/MemoryMetricsTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/MemoryMetricsTest.cs @@ -44,7 +44,7 @@ namespace Apache.Ignite.Core.Tests.Cache // Verify metrics. var metrics = ignite.GetMemoryMetrics().OrderBy(x => x.Name).ToArray(); - Assert.AreEqual(4, metrics.Length); // two defined plus system and plus TxLog. + Assert.AreEqual(5, metrics.Length); // two defined plus system, TxLog and volatile. var emptyMetrics = metrics[0]; Assert.AreEqual(MemoryPolicyNoMetrics, emptyMetrics.Name); @@ -62,6 +62,14 @@ namespace Apache.Ignite.Core.Tests.Cache Assert.AreEqual("sysMemPlc", sysMetrics.Name); AssertMetricsAreEmpty(sysMetrics); + var txLogMetrics = metrics[3]; + Assert.AreEqual("TxLog", txLogMetrics.Name); + AssertMetricsAreEmpty(txLogMetrics); + + var volatileMetrics = metrics[4]; + Assert.AreEqual("volatileDsMemPlc", volatileMetrics.Name); + AssertMetricsAreEmpty(volatileMetrics); + // Metrics by name. emptyMetrics = ignite.GetMemoryMetrics(MemoryPolicyNoMetrics); Assert.AreEqual(MemoryPolicyNoMetrics, emptyMetrics.Name);