diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java index e620c60..ff7fd9a 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java @@ -332,7 +332,8 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi static final long DEFAULT_ROW_PROCESSOR_TIMEOUT = 60 * 1000L; final ExecutorService rowProcessorExecutor = Executors.newCachedThreadPool(); - private final ConcurrentHashMap scannerReadPoints; + private final ConcurrentMap scannerReadPoints = + new ConcurrentHashMap(); /** * The sequence ID that was encountered when this region was opened. @@ -375,17 +376,10 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi * read operation. */ public long getSmallestReadPoint() { - long minimumReadPoint; - // We need to ensure that while we are calculating the smallestReadPoint - // no new RegionScanners can grab a readPoint that we are unaware of. - // We achieve this by synchronizing on the scannerReadPoints object. - synchronized(scannerReadPoints) { - minimumReadPoint = mvcc.getReadPoint(); - - for (Long readPoint: this.scannerReadPoints.values()) { - if (readPoint < minimumReadPoint) { - minimumReadPoint = readPoint; - } + long minimumReadPoint = mvcc.getReadPoint(); + for (Entry e: this.scannerReadPoints.entrySet()) { + if (e.getValue() < minimumReadPoint) { + minimumReadPoint = e.getValue(); } } return minimumReadPoint; @@ -690,7 +684,6 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi this.rsServices = rsServices; this.threadWakeFrequency = conf.getLong(HConstants.THREAD_WAKE_FREQUENCY, 10 * 1000); setHTableSpecificConf(); - this.scannerReadPoints = new ConcurrentHashMap(); this.busyWaitDuration = conf.getLong( "hbase.busy.wait.duration", DEFAULT_BUSY_WAIT_DURATION); @@ -5599,13 +5592,11 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi // it is [startRow,endRow) and if startRow=endRow we get nothing. this.isScan = scan.isGetScan() ? -1 : 0; - // synchronize on scannerReadPoints so that nobody calculates - // getSmallestReadPoint, before scannerReadPoints is updated. - IsolationLevel isolationLevel = scan.getIsolationLevel(); - synchronized(scannerReadPoints) { - this.readPt = getReadpoint(isolationLevel); - scannerReadPoints.put(this, this.readPt); - } + // Store the current read point. Used below when we want to find the read point of the oldest + // outstanding scanner. We need this to make sure that we do not do optimistic pruning of + // versions of TTL'd Cells with a read is outstanding. + this.readPt = getReadpoint(scan.getIsolationLevel()); + scannerReadPoints.put(this, this.readPt); // Here we separate all scanners into two lists - scanner that provide data required // by the filter to operate (scanners list) and all others (joinedScanners list). @@ -6126,7 +6117,6 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi joinedHeap.close(); joinedHeap = null; } - // no need to synchronize here. scannerReadPoints.remove(this); this.filterClosed = true; }