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;
     }
 }

Reply via email to