Repository: ignite Updated Branches: refs/heads/master 2f330a1cd -> bf5131fa4
IGNITE-7540 Prevent page memory metadata corruption during checkpoint and group destroying. - Fixes #3490. Signed-off-by: Alexey Goncharuk <alexey.goncha...@gmail.com> Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/bf5131fa Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/bf5131fa Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/bf5131fa Branch: refs/heads/master Commit: bf5131fa40706e1538a69de1db99025a2ed72a41 Parents: 2f330a1 Author: Pavel Kovalenko <jokse...@gmail.com> Authored: Fri Feb 9 16:55:15 2018 +0300 Committer: Alexey Goncharuk <alexey.goncha...@gmail.com> Committed: Fri Feb 9 16:55:15 2018 +0300 ---------------------------------------------------------------------- .../processors/cache/GridCacheProcessor.java | 19 +++ ...nitePdsCacheDestroyDuringCheckpointTest.java | 161 +++++++++++++++++++ .../IgnitePdsWithIndexingCoreTestSuite.java | 2 + 3 files changed, 182 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/bf5131fa/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java index 1561f25..ec456e1 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java @@ -89,6 +89,7 @@ import org.apache.ignite.internal.processors.cache.jta.CacheJtaManagerAdapter; import org.apache.ignite.internal.processors.cache.local.GridLocalCache; import org.apache.ignite.internal.processors.cache.local.atomic.GridLocalAtomicCache; import org.apache.ignite.internal.processors.cache.persistence.DataRegion; +import org.apache.ignite.internal.processors.cache.persistence.DbCheckpointListener; import org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager; import org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager; import org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager; @@ -2232,6 +2233,24 @@ public class GridCacheProcessor extends GridProcessorAdapter { } } + sharedCtx.database().checkpointReadLock(); + + try { + // Do not invoke checkpoint listeners for groups are going to be destroyed to prevent metadata corruption. + for (ExchangeActions.CacheGroupActionData action : exchActions.cacheGroupsToStop()) { + Integer groupId = action.descriptor().groupId(); + CacheGroupContext grp = cacheGrps.get(groupId); + + if (grp != null && grp.persistenceEnabled() && sharedCtx.database() instanceof GridCacheDatabaseSharedManager) { + GridCacheDatabaseSharedManager mngr = (GridCacheDatabaseSharedManager) sharedCtx.database(); + mngr.removeCheckpointListener((DbCheckpointListener) grp.offheap()); + } + } + } + finally { + sharedCtx.database().checkpointReadUnlock(); + } + List<IgniteBiTuple<CacheGroupContext, Boolean>> stoppedGroups = new ArrayList<>(); for (ExchangeActions.CacheGroupActionData action : exchActions.cacheGroupsToStop()) { http://git-wip-us.apache.org/repos/asf/ignite/blob/bf5131fa/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/file/IgnitePdsCacheDestroyDuringCheckpointTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/file/IgnitePdsCacheDestroyDuringCheckpointTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/file/IgnitePdsCacheDestroyDuringCheckpointTest.java new file mode 100644 index 0000000..72f73aa --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/file/IgnitePdsCacheDestroyDuringCheckpointTest.java @@ -0,0 +1,161 @@ +/* + * 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.persistence.db.file; + +import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.IgniteDataStreamer; +import org.apache.ignite.cache.CacheAtomicityMode; +import org.apache.ignite.cache.CachePeekMode; +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.internal.IgniteEx; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; + +import static org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.DFLT_STORE_DIR; + +/** + * Test for cache creation/deletion with frequent checkpoints. + */ +public class IgnitePdsCacheDestroyDuringCheckpointTest extends GridCommonAbstractTest { + /** */ + private static final String NAME_PREFIX = "CACHE-"; + + /** */ + private static final int NUM_ITERATIONS = 10; + + /** */ + private static final int NUM_CACHES = 10; + + /** */ + private static final int NUM_ENTRIES_PER_CACHE = 200; + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(gridName); + + cfg.setDataStorageConfiguration(createDbConfig()); + + if (getTestIgniteInstanceIndex(gridName) == 1) + cfg.setClientMode(true); + + return cfg; + } + + /** + * @return DB config. + */ + private DataStorageConfiguration createDbConfig() { + DataStorageConfiguration storageCfg = new DataStorageConfiguration(); + storageCfg.setCheckpointFrequency(300); + + DataRegionConfiguration regionConfig = new DataRegionConfiguration(); + regionConfig.setPersistenceEnabled(true); + + storageCfg.setDefaultDataRegionConfiguration(regionConfig); + + return storageCfg; + } + + /** {@inheritDoc} */ + @Override protected void beforeTestsStarted() throws Exception { + super.beforeTestsStarted(); + + deleteWorkFiles(); + } + + /** {@inheritDoc} */ + @Override protected void afterTestsStopped() throws Exception { + super.afterTestsStopped(); + + stopAllGrids(); + + deleteWorkFiles(); + } + + /** + * @throws Exception If fail. + */ + public void testCacheCreatePutCheckpointDestroy() throws Exception { + IgniteEx ig = startGrid(0); + ig.active(true); + + for (int j = 0; j < NUM_ITERATIONS; j++) { + Ignite client = startGrid(1); + + for (int i = 0; i < NUM_CACHES; i++) { + IgniteCache<?, ?> cache = ig.cache(NAME_PREFIX + i); + if (cache != null) + cache.destroy(); + } + + populateCache(client); + checkCacheSizes(client); + + client.close(); + } + } + + + /** */ + private void populateCache(Ignite client) { + for (int i = 0; i < NUM_CACHES; i++) { + CacheConfiguration cfg = new CacheConfiguration(); + cfg.setName(NAME_PREFIX + i).setAtomicityMode(CacheAtomicityMode.ATOMIC) + .setBackups(1).setStatisticsEnabled(true).setManagementEnabled(true); + client.getOrCreateCache(cfg); + + IgniteDataStreamer<Object, Object> streamer = client.dataStreamer(NAME_PREFIX + i); + + for (int j = 0; j < NUM_ENTRIES_PER_CACHE; j++) { + String bo = i + "|" + j + "|WHATEVER"; + streamer.addData(j, bo); + } + + streamer.close(); + log.info("Streamer closed"); + } + } + + /** */ + private void checkCacheSizes(Ignite client) { + for (int i = 0; i < NUM_CACHES; i++) { + IgniteCache<Object, Object> cache = client.getOrCreateCache(NAME_PREFIX + i); + + int size = cache.size(CachePeekMode.ALL); + + if (NUM_ENTRIES_PER_CACHE != size) { + for (Object o : cache) { + log.info("O " + o); + } + assertTrue(false); + } + } + } + + /** + * @throws IgniteCheckedException If fail. + */ + private void deleteWorkFiles() throws IgniteCheckedException { + deleteRecursively(U.resolveWorkDirectory(U.defaultWorkDirectory(), DFLT_STORE_DIR, false)); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/bf5131fa/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgnitePdsWithIndexingCoreTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgnitePdsWithIndexingCoreTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgnitePdsWithIndexingCoreTestSuite.java index 9f86e0d..d3256c2 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgnitePdsWithIndexingCoreTestSuite.java +++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgnitePdsWithIndexingCoreTestSuite.java @@ -25,6 +25,7 @@ import org.apache.ignite.internal.processors.cache.persistence.IgnitePdsTxCacheR import org.apache.ignite.internal.processors.cache.persistence.IgnitePersistentStoreCacheGroupsTest; import org.apache.ignite.internal.processors.cache.persistence.db.IgnitePdsMultiNodePutGetRestartTest; import org.apache.ignite.internal.processors.cache.persistence.db.IgnitePdsPageEvictionTest; +import org.apache.ignite.internal.processors.cache.persistence.db.file.IgnitePdsCacheDestroyDuringCheckpointTest; import org.apache.ignite.internal.processors.cache.persistence.db.file.IgnitePdsCacheIntegrationTest; import org.apache.ignite.internal.processors.cache.persistence.db.file.IgnitePdsDiskErrorsRecoveringTest; import org.apache.ignite.internal.processors.cache.persistence.db.file.IgnitePdsNoActualWalHistoryTest; @@ -59,6 +60,7 @@ public class IgnitePdsWithIndexingCoreTestSuite extends TestSuite { suite.addTestSuite(IgniteWalRecoveryPPCTest.class); suite.addTestSuite(IgnitePdsDiskErrorsRecoveringTest.class); + suite.addTestSuite(IgnitePdsCacheDestroyDuringCheckpointTest.class); suite.addTestSuite(IgnitePdsBinaryMetadataOnClusterRestartTest.class); suite.addTestSuite(IgnitePdsMarshallerMappingRestoreOnNodeStartTest.class);