[ 
https://issues.apache.org/jira/browse/HBASE-30213?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18142695#comment-18142695
 ] 

mazhengxuan commented on HBASE-30213:
-------------------------------------

I've put together a patch for this. It keeps the fix in \{{HRegion}}, using an 
atomic heap-plus-off-heap total for write-blocking and flush checks, including 
WAL replay. Component statistics, thresholds and the meta-region exemption are 
unchanged.

This avoids combining heap and off-heap values from different points in time. 
Accounting isn't transactional, though: the counters can temporarily differ 
during overlapping updates, and transient rejections are still possible. The 
totals match once updates complete.

Tests cover mixed snapshots, threshold boundaries, mixed-sign deltas, 
concurrent accounting, real compaction/flush, and cleanup on failure, including 
executor termination, WAL close attempts and global state restoration.

> Spurious RegionTooBusyException due to non-atomic update of correlated fields 
> heapSize/offHeapSize in ThreadSafeMemStoreSizing
> ------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: HBASE-30213
>                 URL: https://issues.apache.org/jira/browse/HBASE-30213
>             Project: HBase
>          Issue Type: Bug
>          Components: regionserver
>            Reporter: John Doe
>            Assignee: mazhengxuan
>            Priority: Major
>              Labels: pull-request-available
>
> A multi-variable concurrency bug in ThreadSafeMemStoreSizing can cause write 
> threads to observe a transiently inflated MemStore size and throw a spurious 
> RegionTooBusyException immediately after a flush 
> completes.ThreadSafeMemStoreSizing maintains two semantically correlated 
> AtomicLong fields, heapSize and offHeapSize, whose sum is used by 
> HRegion.checkResources() to determine whether incoming writes should be 
> rejected. During decrMemStoreSize(), these two fields are decremented by two 
> separate addAndGet() calls with no common lock: offHeapSize is decremented 
> first (line 59), heapSize second (line 60).
> A concurrent write RPC thread calling getMemStoreSize() reads heapSize first 
> and offHeapSize second (line 53). If the read falls between the two 
> decrements, it observes the stale pre-flush heapSize combined with the 
> already-decremented offHeapSize, producing a sum that overestimates the true 
> MemStore size by the full heapSizeDelta of the flush.
> If this inflated sum exceeds blockingMemStoreSize, checkResources() 
> incorrectly throws RegionTooBusyException (HRegion.java:5029), even though 
> the MemStore is already safely below the threshold.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to