Skip to content

Commit 5842b40

Browse files
committed
HBASE-25709 Close region may stuck when region is compacting and skipped most cells read
1 parent 446f22f commit 5842b40

File tree

4 files changed

+28
-5
lines changed

4 files changed

+28
-5
lines changed

hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/NoLimitScannerContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
public class NoLimitScannerContext extends ScannerContext {
3737

3838
public NoLimitScannerContext() {
39-
super(false, null, false);
39+
super(false, null, false, false);
4040
}
4141

4242
/**

hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/ScannerContext.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,13 @@ public class ScannerContext {
110110
*/
111111
final ServerSideScanMetrics metrics;
112112

113-
ScannerContext(boolean keepProgress, LimitFields limitsToCopy, boolean trackMetrics) {
113+
/**
114+
* Set this to true will prevent the looping skip of heap cells, see HBASE-25709.
115+
*/
116+
private boolean preventLoopReadEnabled = false;
117+
118+
ScannerContext(boolean keepProgress, LimitFields limitsToCopy, boolean trackMetrics,
119+
boolean preventLoopReadEnabled) {
114120
this.limits = new LimitFields();
115121
if (limitsToCopy != null) {
116122
this.limits.copy(limitsToCopy);
@@ -122,12 +128,17 @@ public class ScannerContext {
122128
this.keepProgress = keepProgress;
123129
this.scannerState = DEFAULT_STATE;
124130
this.metrics = trackMetrics ? new ServerSideScanMetrics() : null;
131+
this.preventLoopReadEnabled = preventLoopReadEnabled;
125132
}
126133

127134
public boolean isTrackingMetrics() {
128135
return this.metrics != null;
129136
}
130137

138+
public boolean isPreventLoopReadEnabled() {
139+
return preventLoopReadEnabled;
140+
}
141+
131142
/**
132143
* Get the metrics instance. Should only be called after a call to {@link #isTrackingMetrics()}
133144
* has been made to confirm that metrics are indeed being tracked.
@@ -372,6 +383,7 @@ public static final class Builder {
372383
boolean keepProgress = DEFAULT_KEEP_PROGRESS;
373384
boolean trackMetrics = false;
374385
LimitFields limits = new LimitFields();
386+
boolean preventLoopReadEnabled = false;
375387

376388
private Builder() {
377389
}
@@ -408,8 +420,13 @@ public Builder setBatchLimit(int batchLimit) {
408420
return this;
409421
}
410422

423+
public Builder setPreventLoopReadEnabled(boolean enabled) {
424+
this.preventLoopReadEnabled = enabled;
425+
return this;
426+
}
427+
411428
public ScannerContext build() {
412-
return new ScannerContext(keepProgress, limits, trackMetrics);
429+
return new ScannerContext(keepProgress, limits, trackMetrics, preventLoopReadEnabled);
413430
}
414431
}
415432

hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,10 @@ public boolean next(List<Cell> outResult, ScannerContext scannerContext) throws
751751
default:
752752
throw new RuntimeException("UNEXPECTED");
753753
}
754+
// when reach heartbeat check, try to avoid loop read cells
755+
if (kvsScanned % cellsPerHeartbeatCheck == 0 && scannerContext.isPreventLoopReadEnabled()) {
756+
return scannerContext.setScannerState(NextState.MORE_VALUES).hasMoreValues();
757+
}
754758
} while ((cell = this.heap.peek()) != null);
755759

756760
if (count > 0) {

hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/compactions/Compactor.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,8 +401,10 @@ protected boolean performCompaction(FileDetails fd, InternalScanner scanner, Cel
401401
String compactionName = ThroughputControlUtil.getNameForThrottling(store, "compaction");
402402
long now = 0;
403403
boolean hasMore;
404-
ScannerContext scannerContext =
405-
ScannerContext.newBuilder().setBatchLimit(compactionKVMax).build();
404+
ScannerContext scannerContext = ScannerContext.newBuilder()
405+
.setBatchLimit(compactionKVMax)
406+
.setPreventLoopReadEnabled(true)
407+
.build();
406408

407409
throughputController.start(compactionName);
408410
KeyValueScanner kvs = (scanner instanceof KeyValueScanner) ? (KeyValueScanner) scanner : null;

0 commit comments

Comments
 (0)