Repository: ignite Updated Branches: refs/heads/master 7bc48acb4 -> 6a1aa1f06
IGNITE-9445 Use valid tag for page write unlock while reading cold page from disk - Fixes #4708. Signed-off-by: Alexey Goncharuk <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/6a1aa1f0 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/6a1aa1f0 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/6a1aa1f0 Branch: refs/heads/master Commit: 6a1aa1f061a4399527215ffe71b02086847cd506 Parents: 7bc48ac Author: Aleksei Scherbakov <[email protected]> Authored: Mon Sep 10 18:43:41 2018 +0300 Committer: Alexey Goncharuk <[email protected]> Committed: Mon Sep 10 18:43:41 2018 +0300 ---------------------------------------------------------------------- .../persistence/pagemem/PageMemoryImpl.java | 7 +- .../CachePageWriteLockUnlockTest.java | 196 +++++++++++++++++++ .../testsuites/IgniteCacheTestSuite7.java | 3 + 3 files changed, 205 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/6a1aa1f0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImpl.java index 75cc036..ba565c9 100755 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImpl.java @@ -778,9 +778,13 @@ public class PageMemoryImpl implements PageMemoryEx { ByteBuffer buf = wrapPointer(pageAddr, pageSize()); + long actualPageId = 0; + try { storeMgr.read(grpId, pageId, buf); + actualPageId = PageIO.getPageId(buf); + memMetrics.onPageRead(); } catch (IgniteDataIntegrityViolationException ignore) { @@ -794,7 +798,8 @@ public class PageMemoryImpl implements PageMemoryEx { memMetrics.onPageRead(); } finally { - rwLock.writeUnlock(lockedPageAbsPtr + PAGE_LOCK_OFFSET, OffheapReadWriteLock.TAG_LOCK_ALWAYS); + rwLock.writeUnlock(lockedPageAbsPtr + PAGE_LOCK_OFFSET, + actualPageId == 0 ? OffheapReadWriteLock.TAG_LOCK_ALWAYS : PageIdUtils.tag(actualPageId)); } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/6a1aa1f0/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CachePageWriteLockUnlockTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CachePageWriteLockUnlockTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CachePageWriteLockUnlockTest.java new file mode 100644 index 0000000..f6a5ec1 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CachePageWriteLockUnlockTest.java @@ -0,0 +1,196 @@ +/* + * 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.distributed; + +import java.util.Iterator; +import javax.cache.Cache; +import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteCheckedException; +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.configuration.WALMode; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.IgniteKernal; +import org.apache.ignite.internal.pagemem.store.IgnitePageStoreManager; +import org.apache.ignite.internal.pagemem.store.PageStore; +import org.apache.ignite.internal.processors.cache.CacheGroupContext; +import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter; +import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLocalPartition; +import org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager; +import org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMemoryEx; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; + +import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.OWNING; + +/** + * + */ +public class CachePageWriteLockUnlockTest extends GridCommonAbstractTest { + /** */ + public static final int PARTITION = 0; + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName); + + cfg.setCacheConfiguration(new CacheConfiguration(DEFAULT_CACHE_NAME). + setAffinity(new RendezvousAffinityFunction(false, 32))); + + cfg.setActiveOnStart(false); + + DataStorageConfiguration memCfg = new DataStorageConfiguration() + .setDefaultDataRegionConfiguration( + new DataRegionConfiguration() + .setPersistenceEnabled(true) + .setMaxSize(DataStorageConfiguration.DFLT_DATA_REGION_INITIAL_SIZE) + ) + .setWalMode(WALMode.LOG_ONLY).setCheckpointFrequency(Integer.MAX_VALUE); + + cfg.setDataStorageConfiguration(memCfg); + + return cfg; + } + + /** + * + */ + public void testPreloadPartition() throws Exception { + try { + IgniteEx grid0 = startGrid(0); + + grid0.cluster().active(true); + + int total = 512; + + putData(grid0, total, PARTITION); + + grid0.cache(DEFAULT_CACHE_NAME).removeAll(); + + forceCheckpoint(); + + stopGrid(0); + + grid0 = startGrid(0); + + grid0.cluster().active(true); + + putData(grid0, total, PARTITION); // Will use pages from reuse pool. + + forceCheckpoint(); + + stopGrid(0); + + grid0 = startGrid(0); + + preloadPartition(grid0, DEFAULT_CACHE_NAME, PARTITION); + + Iterator<Cache.Entry<Object, Object>> it = grid0.cache(DEFAULT_CACHE_NAME).iterator(); + + int c0 = 0; + + while (it.hasNext()) { + Cache.Entry<Object, Object> entry = it.next(); + + c0++; + } + + assertEquals(total, c0); + } + finally { + stopAllGrids(); + } + } + + /** + * @param grid Grid. + * @param total Total. + * @param part Partition. + */ + private void putData(Ignite grid, int total, int part) { + int c = 0, k = 0; + + while(c < total) { + if (grid(0).affinity(DEFAULT_CACHE_NAME).partition(k) == part) { + grid.cache(DEFAULT_CACHE_NAME).put(k, k); + + c++; + } + + k++; + } + } + + /** + * Preload partition fast by iterating on all pages in disk order. + * + * @param grid Grid. + * @param cacheName Cache name. + * @param p P. + */ + private void preloadPartition(Ignite grid, String cacheName, int p) throws IgniteCheckedException { + GridDhtCacheAdapter<Object, Object> dht = ((IgniteKernal)grid).internalCache(cacheName).context().dht(); + + GridDhtLocalPartition part = dht.topology().localPartition(p); + + assertNotNull(part); + + assertTrue(part.state() == OWNING); + + CacheGroupContext grpCtx = dht.context().group(); + + if (part.state() != OWNING) + return; + + IgnitePageStoreManager pageStoreMgr = grpCtx.shared().pageStore(); + + if (pageStoreMgr instanceof FilePageStoreManager) { + FilePageStoreManager filePageStoreMgr = (FilePageStoreManager)pageStoreMgr; + + PageStore pageStore = filePageStoreMgr.getStore(grpCtx.groupId(), part.id()); + + PageMemoryEx pageMemory = (PageMemoryEx)grpCtx.dataRegion().pageMemory(); + + long pageId = pageMemory.partitionMetaPageId(grpCtx.groupId(), part.id()); + + for (int pageNo = 0; pageNo < pageStore.pages(); pageId++, pageNo++) { + long pagePointer = -1; + + try { + pagePointer = pageMemory.acquirePage(grpCtx.groupId(), pageId); + } + finally { + if (pagePointer != -1) + pageMemory.releasePage(grpCtx.groupId(), pageId, pagePointer); + } + } + } + } + + /** {@inheritDoc} */ + @Override protected void beforeTest() throws Exception { + cleanPersistenceDir(); + } + + /** {@inheritDoc} */ + @Override protected void afterTest() throws Exception { + cleanPersistenceDir(); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/6a1aa1f0/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite7.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite7.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite7.java index 0a2f86e..6c48ecc 100755 --- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite7.java +++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite7.java @@ -33,6 +33,7 @@ import org.apache.ignite.internal.processors.cache.WalModeChangeAdvancedSelfTest import org.apache.ignite.internal.processors.cache.WalModeChangeCoordinatorNotAffinityNodeSelfTest; import org.apache.ignite.internal.processors.cache.WalModeChangeSelfTest; import org.apache.ignite.internal.processors.cache.distributed.Cache64kPartitionsTest; +import org.apache.ignite.internal.processors.cache.distributed.CachePageWriteLockUnlockTest; import org.apache.ignite.internal.processors.cache.distributed.CacheRentingStateRepairTest; import org.apache.ignite.internal.processors.cache.distributed.CacheDataLossOnPartitionMoveTest; import org.apache.ignite.internal.processors.cache.distributed.dht.IgniteCacheStartWithLoadTest; @@ -101,6 +102,8 @@ public class IgniteCacheTestSuite7 extends TestSuite { suite.addTestSuite(TransactionIntegrityWithPrimaryIndexCorruptionTest.class); suite.addTestSuite(CacheDataLossOnPartitionMoveTest.class); + suite.addTestSuite(CachePageWriteLockUnlockTest.class); + return suite; } }
