Skip to content

Commit 3effd28

Browse files
committed
HBASE-24648 Remove the legacy 'forceSplit' related code at region server side (#1990)
Signed-off-by: Viraj Jasani <vjasani@apache.org>
1 parent ed61044 commit 3effd28

File tree

13 files changed

+193
-252
lines changed

13 files changed

+193
-252
lines changed

hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,15 @@ public RegionInfo getDaughterTwoRI() {
167167
return daughterTwoRI;
168168
}
169169

170+
private boolean hasBestSplitRow() {
171+
return bestSplitRow != null && bestSplitRow.length > 0;
172+
}
173+
170174
/**
171175
* Check whether the region is splittable
172176
* @param env MasterProcedureEnv
173177
* @param regionToSplit parent Region to be split
174178
* @param splitRow if splitRow is not specified, will first try to get bestSplitRow from RS
175-
* @throws IOException
176179
*/
177180
private void checkSplittable(final MasterProcedureEnv env,
178181
final RegionInfo regionToSplit, final byte[] splitRow) throws IOException {
@@ -187,19 +190,20 @@ private void checkSplittable(final MasterProcedureEnv env,
187190
boolean splittable = false;
188191
if (node != null) {
189192
try {
190-
if (bestSplitRow == null || bestSplitRow.length == 0) {
191-
LOG
192-
.info("splitKey isn't explicitly specified, will try to find a best split key from RS");
193-
}
194-
// Always set bestSplitRow request as true here,
195-
// need to call Region#checkSplit to check it splittable or not
196-
GetRegionInfoResponse response = AssignmentManagerUtil.getRegionInfoResponse(env,
197-
node.getRegionLocation(), node.getRegionInfo(), true);
198-
if(bestSplitRow == null || bestSplitRow.length == 0) {
199-
bestSplitRow = response.hasBestSplitRow() ? response.getBestSplitRow().toByteArray() : null;
193+
GetRegionInfoResponse response;
194+
if (!hasBestSplitRow()) {
195+
LOG.info(
196+
"{} splitKey isn't explicitly specified, will try to find a best split key from RS {}",
197+
node.getRegionInfo().getRegionNameAsString(), node.getRegionLocation());
198+
response = AssignmentManagerUtil.getRegionInfoResponse(env, node.getRegionLocation(),
199+
node.getRegionInfo(), true);
200+
bestSplitRow =
201+
response.hasBestSplitRow() ? response.getBestSplitRow().toByteArray() : null;
202+
} else {
203+
response = AssignmentManagerUtil.getRegionInfoResponse(env, node.getRegionLocation(),
204+
node.getRegionInfo(), false);
200205
}
201206
splittable = response.hasSplittable() && response.getSplittable();
202-
203207
if (LOG.isDebugEnabled()) {
204208
LOG.debug("Splittable=" + splittable + " " + node.toShortString());
205209
}

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ public synchronized boolean requestSplit(final Region r) {
191191
HRegion hr = (HRegion)r;
192192
try {
193193
if (shouldSplitRegion() && hr.getCompactPriority() >= PRIORITY_USER) {
194-
byte[] midKey = hr.checkSplit();
194+
byte[] midKey = hr.checkSplit().orElse(null);
195195
if (midKey != null) {
196196
requestSplit(r, midKey);
197197
return true;
@@ -216,9 +216,6 @@ public synchronized void requestSplit(final Region r, byte[] midKey, User user)
216216
if (midKey == null) {
217217
LOG.debug("Region " + r.getRegionInfo().getRegionNameAsString() +
218218
" not splittable because midkey=null");
219-
if (((HRegion)r).shouldForceSplit()) {
220-
((HRegion)r).clearSplit();
221-
}
222219
return;
223220
}
224221
try {

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ protected void configureForRegion(HRegion region) {
6868

6969
@Override
7070
protected boolean shouldSplit() {
71-
boolean force = region.shouldForceSplit();
7271
boolean foundABigStore = false;
7372

7473
for (HStore store : region.getStores()) {
@@ -84,7 +83,7 @@ protected boolean shouldSplit() {
8483
}
8584
}
8685

87-
return foundABigStore || force;
86+
return foundABigStore;
8887
}
8988

9089
long getDesiredMaxFileSize() {

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,20 @@
2222
import org.apache.hadoop.hbase.HBaseInterfaceAudience;
2323

2424
/**
25-
* A {@link RegionSplitPolicy} that disables region splits.
26-
* This should be used with care, since it will disable automatic sharding.
27-
* Most of the time, using {@link ConstantSizeRegionSplitPolicy} with a
28-
* large region size (10GB, etc) is safer.
25+
* A {@link RegionSplitPolicy} that disables region splits. This should be used with care, since it
26+
* will disable automatic sharding. Most of the time, using {@link ConstantSizeRegionSplitPolicy}
27+
* with a large region size (10GB, etc) is safer.
2928
*/
3029
@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.CONFIG)
3130
public class DisabledRegionSplitPolicy extends RegionSplitPolicy {
31+
3232
@Override
3333
protected boolean shouldSplit() {
3434
return false;
3535
}
36+
37+
@Override
38+
protected boolean canSplit() {
39+
return false;
40+
}
3641
}

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

Lines changed: 19 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -691,8 +691,6 @@ void sawNoSuchFamily() {
691691

692692
// Stop updates lock
693693
private final ReentrantReadWriteLock updatesLock = new ReentrantReadWriteLock();
694-
private boolean splitRequest;
695-
private byte[] explicitSplitPoint = null;
696694

697695
private final MultiVersionConcurrencyControl mvcc;
698696

@@ -1463,7 +1461,7 @@ public boolean isAvailable() {
14631461

14641462
@Override
14651463
public boolean isSplittable() {
1466-
return isAvailable() && !hasReferences();
1464+
return splitPolicy.canSplit();
14671465
}
14681466

14691467
@Override
@@ -1962,7 +1960,8 @@ public void setMobFileCache(MobFileCache mobFileCache) {
19621960
/**
19631961
* @return split policy for this region.
19641962
*/
1965-
public RegionSplitPolicy getSplitPolicy() {
1963+
@VisibleForTesting
1964+
RegionSplitPolicy getSplitPolicy() {
19661965
return this.splitPolicy;
19671966
}
19681967

@@ -8346,9 +8345,9 @@ void checkFamily(final byte [] family)
83468345

83478346
public static final long FIXED_OVERHEAD = ClassSize.align(
83488347
ClassSize.OBJECT +
8349-
ClassSize.ARRAY +
8350-
55 * ClassSize.REFERENCE + 3 * Bytes.SIZEOF_INT +
8351-
(15 * Bytes.SIZEOF_LONG) +
8348+
56 * ClassSize.REFERENCE +
8349+
3 * Bytes.SIZEOF_INT +
8350+
14 * Bytes.SIZEOF_LONG +
83528351
3 * Bytes.SIZEOF_BOOLEAN);
83538352

83548353
// woefully out of date - currently missing:
@@ -8483,51 +8482,27 @@ public void run(com.google.protobuf.Message message) {
84838482
return responseBuilder.build();
84848483
}
84858484

8486-
boolean shouldForceSplit() {
8487-
return this.splitRequest;
8488-
}
8489-
8490-
byte[] getExplicitSplitPoint() {
8491-
return this.explicitSplitPoint;
8492-
}
8493-
8494-
void forceSplit(byte[] sp) {
8495-
// This HRegion will go away after the forced split is successful
8496-
// But if a forced split fails, we need to clear forced split.
8497-
this.splitRequest = true;
8498-
if (sp != null) {
8499-
this.explicitSplitPoint = sp;
8500-
}
8501-
}
8502-
8503-
void clearSplit() {
8504-
this.splitRequest = false;
8505-
this.explicitSplitPoint = null;
8485+
public Optional<byte[]> checkSplit() {
8486+
return checkSplit(false);
85068487
}
85078488

85088489
/**
8509-
* Return the splitpoint. null indicates the region isn't splittable
8510-
* If the splitpoint isn't explicitly specified, it will go over the stores
8511-
* to find the best splitpoint. Currently the criteria of best splitpoint
8512-
* is based on the size of the store.
8490+
* Return the split point. An empty result indicates the region isn't splittable.
85138491
*/
8514-
public byte[] checkSplit() {
8492+
public Optional<byte[]> checkSplit(boolean force) {
85158493
// Can't split META
85168494
if (this.getRegionInfo().isMetaRegion() ||
8517-
TableName.NAMESPACE_TABLE_NAME.equals(this.getRegionInfo().getTable())) {
8518-
if (shouldForceSplit()) {
8519-
LOG.warn("Cannot split meta region in HBase 0.20 and above");
8520-
}
8521-
return null;
8495+
TableName.NAMESPACE_TABLE_NAME.equals(this.getRegionInfo().getTable())) {
8496+
return Optional.empty();
85228497
}
85238498

85248499
// Can't split a region that is closing.
85258500
if (this.isClosing()) {
8526-
return null;
8501+
return Optional.empty();
85278502
}
85288503

8529-
if (!splitPolicy.shouldSplit()) {
8530-
return null;
8504+
if (!force && !splitPolicy.shouldSplit()) {
8505+
return Optional.empty();
85318506
}
85328507

85338508
byte[] ret = splitPolicy.getSplitPoint();
@@ -8537,10 +8512,12 @@ public byte[] checkSplit() {
85378512
checkRow(ret, "calculated split");
85388513
} catch (IOException e) {
85398514
LOG.error("Ignoring invalid split for region {}", this, e);
8540-
return null;
8515+
return Optional.empty();
85418516
}
8517+
return Optional.of(ret);
8518+
} else {
8519+
return Optional.empty();
85428520
}
8543-
return ret;
85448521
}
85458522

85468523
/**

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ protected void configureForRegion(HRegion region) {
7070

7171
@Override
7272
protected boolean shouldSplit() {
73-
boolean force = region.shouldForceSplit();
7473
boolean foundABigStore = false;
7574
// Get count of regions that have the same common table as this.region
7675
int tableRegionsCount = getCountOfCommonTableRegions();
@@ -95,7 +94,7 @@ protected boolean shouldSplit() {
9594
}
9695
}
9796

98-
return foundABigStore || force;
97+
return foundABigStore;
9998
}
10099

101100
/**

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ private boolean flushRegion(HRegion region, boolean emergencyFlush, boolean forc
610610
FlushResult flushResult = region.flushcache(forceFlushAllStores, false, tracker);
611611
boolean shouldCompact = flushResult.isCompactionNeeded();
612612
// We just want to check the size
613-
boolean shouldSplit = region.checkSplit() != null;
613+
boolean shouldSplit = region.checkSplit().isPresent();
614614
if (shouldSplit) {
615615
this.server.compactSplitThread.requestSplit(region);
616616
} else if (shouldCompact) {

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

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1833,35 +1833,30 @@ public GetOnlineRegionResponse getOnlineRegion(final RpcController controller,
18331833
@Override
18341834
@QosPriority(priority=HConstants.ADMIN_QOS)
18351835
public GetRegionInfoResponse getRegionInfo(final RpcController controller,
1836-
final GetRegionInfoRequest request) throws ServiceException {
1836+
final GetRegionInfoRequest request) throws ServiceException {
18371837
try {
18381838
checkOpen();
18391839
requestCount.increment();
18401840
HRegion region = getRegion(request.getRegion());
18411841
RegionInfo info = region.getRegionInfo();
1842-
byte[] bestSplitRow = null;
1843-
boolean shouldSplit = true;
1842+
byte[] bestSplitRow;
18441843
if (request.hasBestSplitRow() && request.getBestSplitRow()) {
1845-
HRegion r = region;
1846-
region.startRegionOperation(Operation.SPLIT_REGION);
1847-
r.forceSplit(null);
1848-
// Even after setting force split if split policy says no to split then we should not split.
1849-
shouldSplit = region.getSplitPolicy().shouldSplit() && !info.isMetaRegion();
1850-
bestSplitRow = r.checkSplit();
1844+
bestSplitRow = region.checkSplit(true).orElse(null);
18511845
// when all table data are in memstore, bestSplitRow = null
18521846
// try to flush region first
1853-
if(bestSplitRow == null) {
1854-
r.flush(true);
1855-
bestSplitRow = r.checkSplit();
1847+
if (bestSplitRow == null) {
1848+
region.flush(true);
1849+
bestSplitRow = region.checkSplit(true).orElse(null);
18561850
}
1857-
r.clearSplit();
1851+
} else {
1852+
bestSplitRow = null;
18581853
}
18591854
GetRegionInfoResponse.Builder builder = GetRegionInfoResponse.newBuilder();
18601855
builder.setRegionInfo(ProtobufUtil.toRegionInfo(info));
18611856
if (request.hasCompactionState() && request.getCompactionState()) {
18621857
builder.setCompactionState(ProtobufUtil.createCompactionState(region.getCompactionState()));
18631858
}
1864-
builder.setSplittable(region.isSplittable() && shouldSplit);
1859+
builder.setSplittable(region.isSplittable());
18651860
builder.setMergeable(region.isMergeable());
18661861
if (request.hasBestSplitRow() && request.getBestSplitRow() && bestSplitRow != null) {
18671862
builder.setBestSplitRow(UnsafeByteOperations.unsafeWrap(bestSplitRow));

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.apache.hadoop.conf.Configured;
2626
import org.apache.hadoop.hbase.HBaseInterfaceAudience;
2727
import org.apache.hadoop.hbase.HConstants;
28+
import org.apache.hadoop.hbase.TableName;
2829
import org.apache.hadoop.hbase.client.TableDescriptor;
2930
import org.apache.hadoop.util.ReflectionUtils;
3031
import org.apache.yetus.audience.InterfaceAudience;
@@ -70,16 +71,21 @@ protected void configureForRegion(HRegion region) {
7071
*/
7172
protected abstract boolean shouldSplit();
7273

74+
/**
75+
* @return {@code true} if the specified region can be split.
76+
*/
77+
protected boolean canSplit() {
78+
return !region.getRegionInfo().isMetaRegion() &&
79+
!TableName.NAMESPACE_TABLE_NAME.equals(region.getRegionInfo().getTable()) &&
80+
region.isAvailable() && !region.hasReferences();
81+
}
82+
7383
/**
7484
* @return the key at which the region should be split, or null
7585
* if it cannot be split. This will only be called if shouldSplit
7686
* previously returned true.
7787
*/
7888
protected byte[] getSplitPoint() {
79-
byte[] explicitSplitPoint = this.region.getExplicitSplitPoint();
80-
if (explicitSplitPoint != null) {
81-
return explicitSplitPoint;
82-
}
8389
List<HStore> stores = region.getStores();
8490

8591
byte[] splitPointFromLargestStore = null;

hbase-server/src/test/java/org/apache/hadoop/hbase/HBaseTestingUtility.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3247,9 +3247,8 @@ public void unassignRegionByRow(byte[] row, RegionLocator table) throws IOExcept
32473247
unassignRegion(hrl.getRegionInfo().getRegionName());
32483248
}
32493249

3250-
/*
3250+
/**
32513251
* Retrieves a splittable region randomly from tableName
3252-
*
32533252
* @param tableName name of table
32543253
* @param maxAttempts maximum number of attempts, unlimited for value of -1
32553254
* @return the HRegion chosen, null if none was found within limit of maxAttempts
@@ -3272,15 +3271,14 @@ public HRegion getSplittableRegion(TableName tableName, int maxAttempts) {
32723271
if (regCount > 0) {
32733272
idx = random.nextInt(regCount);
32743273
// if we have just tried this region, there is no need to try again
3275-
if (attempted.contains(idx))
3274+
if (attempted.contains(idx)) {
32763275
continue;
3277-
try {
3278-
regions.get(idx).checkSplit();
3279-
return regions.get(idx);
3280-
} catch (Exception ex) {
3281-
LOG.warn("Caught exception", ex);
3282-
attempted.add(idx);
32833276
}
3277+
HRegion region = regions.get(idx);
3278+
if (region.checkSplit().isPresent()) {
3279+
return region;
3280+
}
3281+
attempted.add(idx);
32843282
}
32853283
attempts++;
32863284
} while (maxAttempts == -1 || attempts < maxAttempts);

hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestEndToEndSplitTransaction.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import static org.junit.Assert.assertEquals;
2222
import static org.junit.Assert.assertFalse;
2323
import static org.junit.Assert.assertTrue;
24+
2425
import java.io.IOException;
2526
import java.util.ArrayList;
2627
import java.util.List;
@@ -69,6 +70,7 @@
6970
import org.junit.rules.TestName;
7071
import org.slf4j.Logger;
7172
import org.slf4j.LoggerFactory;
73+
7274
import org.apache.hbase.thirdparty.com.google.common.collect.Iterators;
7375
import org.apache.hbase.thirdparty.com.google.common.collect.Maps;
7476
import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
@@ -120,7 +122,6 @@ public void testCanSplitJustAfterASplit() throws Exception {
120122
admin.createTable(htd);
121123
TEST_UTIL.loadTable(source, fam);
122124
compactSplit.setCompactionsEnabled(false);
123-
TEST_UTIL.getHBaseCluster().getRegions(tableName).get(0).forceSplit(null);
124125
admin.split(tableName);
125126
TEST_UTIL.waitFor(60000, () -> TEST_UTIL.getHBaseCluster().getRegions(tableName).size() == 2);
126127

hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHStore.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -874,9 +874,6 @@ public void testMultipleTimestamps() throws IOException {
874874
public void testSplitWithEmptyColFam() throws IOException {
875875
init(this.name.getMethodName());
876876
assertFalse(store.getSplitPoint().isPresent());
877-
store.getHRegion().forceSplit(null);
878-
assertFalse(store.getSplitPoint().isPresent());
879-
store.getHRegion().clearSplit();
880877
}
881878

882879
@Test

0 commit comments

Comments
 (0)