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