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 2854ff598ddd..0ca8665f3540 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 @@ -1420,8 +1420,7 @@ protected String getAlgorithm() { */ @Override public int evictBlocksByHfileName(String hfileName) { - Set keySet = blocksByHFile.subSet(new BlockCacheKey(hfileName, Long.MIN_VALUE), - true, new BlockCacheKey(hfileName, Long.MAX_VALUE), true); + Set keySet = getAllCacheKeysForFile(hfileName, 0L, Long.MAX_VALUE); int numEvicted = 0; for (BlockCacheKey key : keySet) { @@ -1433,6 +1432,25 @@ public int evictBlocksByHfileName(String hfileName) { return numEvicted; } + private Set getAllCacheKeysForFile(String hfileName, long init, long end) { + Set cacheKeys = new HashSet<>(); + // At this moment, Some Bucket Entries may be in the WriterThread queue, and not yet put into + // the backingMap. So, when executing this method, we should check both the RAMCache and + // backingMap to ensure all CacheKeys are obtained. + // For more details, please refer to HBASE-29862. + Set ramCacheKeySet = ramCache.getRamBlockCacheKeysForHFile(hfileName); + for (BlockCacheKey key : ramCacheKeySet) { + if (key.getOffset() >= init && key.getOffset() <= end) { + cacheKeys.add(key); + } + } + + // These keys are just for comparison and are short lived, so we need only file name and offset + cacheKeys.addAll(blocksByHFile.subSet(new BlockCacheKey(hfileName, init), true, + new BlockCacheKey(hfileName, end), true)); + return cacheKeys; + } + /** * Used to group bucket entries into priority buckets. There will be a BucketEntryGroup for each * priority (single, multi, memory). Once bucketed, the eviction algorithm takes the appropriate @@ -1770,5 +1788,16 @@ public void clear() { re.getData().release(); } } + + public Set getRamBlockCacheKeysForHFile(String fileName) { + Set ramCacheKeySet = new HashSet<>(); + for (BlockCacheKey blockCacheKey : delegate.keySet()) { + if (blockCacheKey.getHfileName().equals(fileName)) { + ramCacheKeySet.add(blockCacheKey); + } + } + + return ramCacheKeySet; + } } }