This is an automated email from the ASF dual-hosted git repository.

zyk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 50789004d35 PBTree: Prevent SchemaFile deadlock when check read page 
(#11858)
50789004d35 is described below

commit 50789004d35d1f89c4a9173506578d12c7e53619
Author: ZhaoXin <[email protected]>
AuthorDate: Sun Jan 7 00:20:20 2024 +0800

    PBTree: Prevent SchemaFile deadlock when check read page (#11858)
---
 .../schemafile/pagemgr/BTreePageManager.java       | 65 +++++++++++-----------
 1 file changed, 32 insertions(+), 33 deletions(-)

diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/pbtree/schemafile/pagemgr/BTreePageManager.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/pbtree/schemafile/pagemgr/BTreePageManager.java
index 00bafcaf2ff..4e1b347460c 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/pbtree/schemafile/pagemgr/BTreePageManager.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/pbtree/schemafile/pagemgr/BTreePageManager.java
@@ -406,45 +406,44 @@ public class BTreePageManager extends PageManager {
     boolean safeFlag = false;
     // check like crabbing
     ISchemaPage crabPage;
-    while (!safeFlag) {
-      SchemaPageContext doubleCheckContext = new SchemaPageContext();
-      if (getPageIndex(getNodeAddress(parent)) != initPage.getPageIndex()) {
-        // transplanted, release the stale and check the new
-        long addrB4Lock = getNodeAddress(parent);
-        int piB4Lock = getPageIndex(addrB4Lock);
+    SchemaPageContext doubleCheckContext;
+    while (getPageIndex(getNodeAddress(parent)) != initPage.getPageIndex()) {
+      // transplanted, release the stale and obtain/lock the new
+      doubleCheckContext = new SchemaPageContext();
+      long addrB4Lock = getNodeAddress(parent);
+      int piB4Lock = getPageIndex(addrB4Lock);
+
+      initPage.decrementAndGetRefCnt();
+      initPage.getLock().readLock().unlock();
+
+      crabPage = getPageInstance(piB4Lock, doubleCheckContext);
+      crabPage.getLock().readLock().lock();
 
-        crabPage = getPageInstance(piB4Lock, doubleCheckContext);
-        crabPage.getLock().readLock().lock();
+      // UNNECESSARY to TRACE lock since the very page will be unlocked at end 
of read
+      cxt.referredPages.remove(initPage.getPageIndex());
+      cxt.referredPages.put(crabPage.getPageIndex(), crabPage);
+      initPage = crabPage;
+    }
 
+    // a fresh context to read-through from global cache
+    doubleCheckContext = new SchemaPageContext();
+    crabPage = getPageInstance(initPage.getPageIndex(), doubleCheckContext);
+    if (crabPage != initPage) {
+      // replaced, the lock and ref count should be the same
+      if (crabPage.getLock() != initPage.getLock()
+          || crabPage.getRefCnt() != initPage.getRefCnt()) {
+        crabPage.decrementAndGetRefCnt();
         initPage.decrementAndGetRefCnt();
         initPage.getLock().readLock().unlock();
-
-        // UNNECESSARY to TRACE lock since the very page will be unlocked at 
end of read
-        cxt.referredPages.remove(initPage.getPageIndex());
-        cxt.referredPages.put(crabPage.getPageIndex(), crabPage);
-        initPage = crabPage;
-        continue;
-      }
-
-      crabPage = getPageInstance(initPage.getPageIndex(), doubleCheckContext);
-      if (crabPage != initPage) {
-        // replaced, the lock and ref count should be the same
-        if (crabPage.getLock() != initPage.getLock()
-            || crabPage.getRefCnt() != initPage.getRefCnt()) {
-          crabPage.decrementAndGetRefCnt();
-          initPage.decrementAndGetRefCnt();
-          initPage.getLock().readLock().unlock();
-          throw new MetadataException(
-              "Page[%d] replacement error: Different ref count or lock 
object.");
-        }
-        // update context is enough, ref and lock is left for main read process
-        cxt.referredPages.put(initPage.getPageIndex(), crabPage);
-        initPage = crabPage;
+        throw new MetadataException(
+            "Page[%d] replacement error: Different ref count or lock object.");
       }
-      // same page shall only be referred once
-      crabPage.decrementAndGetRefCnt();
-      safeFlag = true;
+      // update context is enough, ref and lock is left for main read process
+      cxt.referredPages.put(initPage.getPageIndex(), crabPage);
+      initPage = crabPage;
     }
+    // same page shall only be referred once
+    crabPage.decrementAndGetRefCnt();
     return initPage;
   }
 

Reply via email to