[
https://issues.apache.org/jira/browse/HBASE-26281?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
chenglei updated HBASE-26281:
-----------------------------
Description:
{{DBB}} got from BucketCache would be freed unexpectedly before RPC completed
for following two cases:
# Because of splitting or stream read,two or more read threads may try to cache
the same block concurrently and one thread read all of the next block header
could replace the another one didn't(see HBASE-20447). When replacing
{{Block}},the following {{BucketCache.WriterThread.putIntoBackingMap}} method
invokes {{BucketCache.blockEvicted}},which free
the {{BucketEntry}} directly in line 544, not through the {{RefCount}}
{code:java}
912 private void putIntoBackingMap(BlockCacheKey key, BucketEntry bucketEntry)
{
913 BucketEntry previousEntry = backingMap.put(key, bucketEntry);
914 if (previousEntry != null && previousEntry != bucketEntry) {
915 previousEntry.withWriteLock(offsetLock, () -> {
blockEvicted(key, previousEntry, false);
return null;
});
}
}
543 void blockEvicted(BlockCacheKey cacheKey, BucketEntry bucketEntry, boolean
decrementBlockNumber) {
544 bucketAllocator.freeBlock(bucketEntry.offset());
545 realCacheSize.add(-1 * bucketEntry.getLength());
546 blocksByHFile.remove(cacheKey);
547 if (decrementBlockNumber) {
548 this.blockNumber.decrement();
549 }
550 }
{code}
was:
{{DBB}} got from BucketCache would be freed unexpectedly before RPC completed
for following two cases:
#
> DBB got from BucketCache would be freed unexpectedly before RPC completed
> -------------------------------------------------------------------------
>
> Key: HBASE-26281
> URL: https://issues.apache.org/jira/browse/HBASE-26281
> Project: HBase
> Issue Type: Bug
> Components: BucketCache
> Affects Versions: 3.0.0-alpha-1, 2.4.6
> Reporter: chenglei
> Priority: Critical
>
> {{DBB}} got from BucketCache would be freed unexpectedly before RPC completed
> for following two cases:
> # Because of splitting or stream read,two or more read threads may try to
> cache the same block concurrently and one thread read all of the next block
> header could replace the another one didn't(see HBASE-20447). When
> replacing {{Block}},the following
> {{BucketCache.WriterThread.putIntoBackingMap}} method invokes
> {{BucketCache.blockEvicted}},which free
> the {{BucketEntry}} directly in line 544, not through the {{RefCount}}
> {code:java}
> 912 private void putIntoBackingMap(BlockCacheKey key, BucketEntry
> bucketEntry) {
> 913 BucketEntry previousEntry = backingMap.put(key, bucketEntry);
> 914 if (previousEntry != null && previousEntry != bucketEntry) {
> 915 previousEntry.withWriteLock(offsetLock, () -> {
> blockEvicted(key, previousEntry, false);
> return null;
> });
> }
> }
> 543 void blockEvicted(BlockCacheKey cacheKey, BucketEntry bucketEntry,
> boolean decrementBlockNumber) {
> 544 bucketAllocator.freeBlock(bucketEntry.offset());
> 545 realCacheSize.add(-1 * bucketEntry.getLength());
> 546 blocksByHFile.remove(cacheKey);
> 547 if (decrementBlockNumber) {
> 548 this.blockNumber.decrement();
> 549 }
> 550 }
>
> {code}
--
This message was sent by Atlassian Jira
(v8.3.4#803005)