Repository: ignite
Updated Branches:
  refs/heads/master 501bbed0d -> 1761a3c66


IGNITE-7698 Page read during replacement should be outside segment lock - Fixes 
#3529.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/1761a3c6
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/1761a3c6
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/1761a3c6

Branch: refs/heads/master
Commit: 1761a3c66dfa42fffa35e5cc736e2420e22851b8
Parents: 501bbed
Author: dpavlov <dpav...@gridgain.com>
Authored: Thu Feb 22 11:52:44 2018 +0300
Committer: Alexey Goncharuk <alexey.goncha...@gmail.com>
Committed: Thu Feb 22 11:52:44 2018 +0300

----------------------------------------------------------------------
 .../persistence/pagemem/PageMemoryImpl.java     | 57 +++++++++++++-------
 1 file changed, 38 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/1761a3c6/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 c9670bc..e52d4fc 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
@@ -651,6 +651,9 @@ public class PageMemoryImpl implements PageMemoryEx {
 
         seg.writeLock().lock();
 
+        long lockedPageAbsPtr = -1;
+        boolean readPageFromStore = false;
+
         try {
             // Double-check.
             long relPtr = seg.loadedPages.get(
@@ -691,24 +694,10 @@ public class PageMemoryImpl implements PageMemoryEx {
                 long pageAddr = absPtr + PAGE_OVERHEAD;
 
                 if (!restore) {
-                    try {
-                        ByteBuffer buf = wrapPointer(pageAddr, pageSize());
-
-                        if (delayedPageReplacementTracker != null)
-                            delayedPageReplacementTracker.waitUnlock(fullId);
-
-                        storeMgr.read(cacheId, pageId, buf);
-                    }
-                    catch (IgniteDataIntegrityViolationException ignore) {
-                        U.warn(log, "Failed to read page (data integrity 
violation encountered, will try to " +
-                            "restore using existing WAL) [fullPageId=" + 
fullId + ']');
-
-                        tryToRestorePage(fullId, absPtr);
+                    if (delayedPageReplacementTracker != null)
+                        delayedPageReplacementTracker.waitUnlock(fullId);
 
-                        seg.acquirePage(absPtr);
-
-                        return absPtr;
-                    }
+                    readPageFromStore = true;
                 }
                 else {
                     GridUnsafe.setMemory(absPtr + PAGE_OVERHEAD, pageSize(), 
(byte)0);
@@ -718,6 +707,14 @@ public class PageMemoryImpl implements PageMemoryEx {
                 }
 
                 rwLock.init(absPtr + PAGE_LOCK_OFFSET, 
PageIdUtils.tag(pageId));
+
+                if (readPageFromStore) {
+                    boolean locked = rwLock.writeLock(absPtr + 
PAGE_LOCK_OFFSET, OffheapReadWriteLock.TAG_LOCK_ALWAYS);
+
+                    assert locked: "Page ID " + fullId + " expected to be 
locked";
+
+                    lockedPageAbsPtr = absPtr;
+                }
             }
             else if (relPtr == OUTDATED_REL_PTR) {
                 assert PageIdUtils.pageIndex(pageId) == 0 : fullId;
@@ -752,6 +749,28 @@ public class PageMemoryImpl implements PageMemoryEx {
 
             if (delayedWriter != null)
                 delayedWriter.finishReplacement();
+
+            if (readPageFromStore) {
+                assert lockedPageAbsPtr != -1 : "Page is expected to have a 
valid address [pageId=" + fullId +
+                    ", lockedPageAbsPtr=" + U.hexLong(lockedPageAbsPtr) + ']';
+
+                try {
+                    long pageAddr = lockedPageAbsPtr + PAGE_OVERHEAD;
+
+                    ByteBuffer buf = wrapPointer(pageAddr, pageSize());
+
+                    storeMgr.read(cacheId, pageId, buf);
+                }
+                catch (IgniteDataIntegrityViolationException ignore) {
+                    U.warn(log, "Failed to read page (data integrity violation 
encountered, will try to " +
+                        "restore using existing WAL) [fullPageId=" + fullId + 
']');
+
+                    tryToRestorePage(fullId, lockedPageAbsPtr);
+                }
+                finally {
+                    rwLock.writeUnlock(lockedPageAbsPtr + PAGE_LOCK_OFFSET, 
OffheapReadWriteLock.TAG_LOCK_ALWAYS);
+                }
+            }
         }
     }
 
@@ -2033,8 +2052,8 @@ public class PageMemoryImpl implements PageMemoryEx {
             if (!pageReplacementWarned) {
                 pageReplacementWarned = true;
 
-                U.warn(log, "Page evictions started, this will affect storage 
performance (consider increasing " +
-                    "DataRegionConfiguration#setMaxSize).");
+                U.warn(log, "Page replacements started, pages will be rotated 
with disk, " +
+                    "this will affect storage performance (consider increasing 
DataRegionConfiguration#setMaxSize).");
             }
 
             final ThreadLocalRandom rnd = ThreadLocalRandom.current();

Reply via email to