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

wchevreuil pushed a commit to branch branch-3
in repository https://gitbox.apache.org/repos/asf/hbase.git


The following commit(s) were added to refs/heads/branch-3 by this push:
     new f697d0f6f2e HBASE-28211 BucketCache.blocksByHFile may leak on 
allocationFailure or if we reach io errors tolerated (#5530)
f697d0f6f2e is described below

commit f697d0f6f2e8ad500a93a3f802da42373898d996
Author: Wellington Ramos Chevreuil <wchevre...@apache.org>
AuthorDate: Wed Nov 29 10:40:33 2023 +0000

    HBASE-28211 BucketCache.blocksByHFile may leak on allocationFailure or if 
we reach io errors tolerated (#5530)
    
    Signed-off-by: Duo Zhang <zhang...@apache.org>
---
 .../org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java | 12 ++++++------
 .../hadoop/hbase/io/hfile/bucket/TestBucketWriterThread.java |  4 ++++
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java
index ba33d5e02c4..0d510457260 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java
@@ -222,7 +222,7 @@ public class BucketCache implements BlockCache, HeapSize {
    */
   transient final IdReadWriteLock<Long> offsetLock;
 
-  private final NavigableSet<BlockCacheKey> blocksByHFile = new 
ConcurrentSkipListSet<>((a, b) -> {
+  final NavigableSet<BlockCacheKey> blocksByHFile = new 
ConcurrentSkipListSet<>((a, b) -> {
     int nameComparison = a.getHfileName().compareTo(b.getHfileName());
     if (nameComparison != 0) {
       return nameComparison;
@@ -644,12 +644,14 @@ public class BucketCache implements BlockCache, HeapSize {
     blocksByHFile.remove(cacheKey);
     if (decrementBlockNumber) {
       this.blockNumber.decrement();
+      if (ioEngine.isPersistent()) {
+        removeFileFromPrefetch(cacheKey.getHfileName());
+      }
     }
     if (evictedByEvictionProcess) {
       cacheStats.evicted(bucketEntry.getCachedTime(), cacheKey.isPrimary());
     }
     if (ioEngine.isPersistent()) {
-      removeFileFromPrefetch(cacheKey.getHfileName());
       setCacheInconsistent(true);
     }
   }
@@ -1084,6 +1086,7 @@ public class BucketCache implements BlockCache, HeapSize {
    */
   protected void putIntoBackingMap(BlockCacheKey key, BucketEntry bucketEntry) 
{
     BucketEntry previousEntry = backingMap.put(key, bucketEntry);
+    blocksByHFile.add(key);
     if (previousEntry != null && previousEntry != bucketEntry) {
       previousEntry.withWriteLock(offsetLock, () -> {
         blockEvicted(key, previousEntry, false, false);
@@ -1164,10 +1167,6 @@ public class BucketCache implements BlockCache, HeapSize 
{
           index++;
           continue;
         }
-        BlockCacheKey cacheKey = re.getKey();
-        if (ramCache.containsKey(cacheKey)) {
-          blocksByHFile.add(cacheKey);
-        }
         // Reset the position for reuse.
         // It should be guaranteed that the data in the metaBuff has been 
transferred to the
         // ioEngine safely. Otherwise, this reuse is problematic. Fortunately, 
the data is already
@@ -1518,6 +1517,7 @@ public class BucketCache implements BlockCache, HeapSize {
     if (!ioEngine.isPersistent() || persistencePath == null) {
       // If persistent ioengine and a path, we will serialize out the 
backingMap.
       this.backingMap.clear();
+      this.blocksByHFile.clear();
       this.fullyCachedFiles.clear();
       this.regionCachedSizeMap.clear();
     }
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/bucket/TestBucketWriterThread.java
 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/bucket/TestBucketWriterThread.java
index 4b729f33411..429fffa38f6 100644
--- 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/bucket/TestBucketWriterThread.java
+++ 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/bucket/TestBucketWriterThread.java
@@ -122,6 +122,8 @@ public class TestBucketWriterThread {
     
Mockito.when(tooBigCacheable.getSerializedLength()).thenReturn(Integer.MAX_VALUE);
     this.bc.cacheBlock(this.plainKey, tooBigCacheable);
     doDrainOfOneEntry(this.bc, this.wt, this.q);
+    assertTrue(bc.blocksByHFile.isEmpty());
+    assertTrue(bc.getBackingMap().isEmpty());
   }
 
   /**
@@ -138,6 +140,8 @@ public class TestBucketWriterThread {
       Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any());
     this.q.add(spiedRqe);
     doDrainOfOneEntry(bc, wt, q);
+    assertTrue(bc.blocksByHFile.isEmpty());
+    assertTrue(bc.getBackingMap().isEmpty());
     // Cache disabled when ioes w/o ever healing.
     assertTrue(!bc.isCacheEnabled());
   }

Reply via email to