HBASE-20111 A region's splittable state now includes the configuration splitPolicy

The Master asks a RegionServer whether a Region can be split or not, primarily to
verify that the region is not closing, opening, etc. This change has the RegionServer
also consult the configured RegionSplitPolicy.

Signed-off-by: Josh Elser <elserj@apache.org>
This commit is contained in:
Rajeshbabu Chintaguntla 2018-03-27 14:46:18 -04:00 committed by Josh Elser
parent c329a3438f
commit a601c57f97
3 changed files with 36 additions and 3 deletions

View File

@ -179,7 +179,7 @@ public class SplitTableRegionProcedure
} }
if (!splittable) { if (!splittable) {
IOException e = new IOException(regionToSplit.getShortNameToLog() + " NOT splittable"); IOException e = new DoNotRetryIOException(regionToSplit.getShortNameToLog() + " NOT splittable");
if (splittableCheckIOE != null) e.initCause(splittableCheckIOE); if (splittableCheckIOE != null) e.initCause(splittableCheckIOE);
throw e; throw e;
} }

View File

@ -1736,10 +1736,13 @@ public class RSRpcServices implements HBaseRPCErrorHandler,
HRegion region = getRegion(request.getRegion()); HRegion region = getRegion(request.getRegion());
RegionInfo info = region.getRegionInfo(); RegionInfo info = region.getRegionInfo();
byte[] bestSplitRow = null; byte[] bestSplitRow = null;
boolean shouldSplit = true;
if (request.hasBestSplitRow() && request.getBestSplitRow()) { if (request.hasBestSplitRow() && request.getBestSplitRow()) {
HRegion r = region; HRegion r = region;
region.startRegionOperation(Operation.SPLIT_REGION); region.startRegionOperation(Operation.SPLIT_REGION);
r.forceSplit(null); r.forceSplit(null);
// Even after setting force split if split policy says no to split then we should not split.
shouldSplit = region.getSplitPolicy().shouldSplit() && !info.isMetaRegion();
bestSplitRow = r.checkSplit(); bestSplitRow = r.checkSplit();
// when all table data are in memstore, bestSplitRow = null // when all table data are in memstore, bestSplitRow = null
// try to flush region first // try to flush region first
@ -1754,7 +1757,7 @@ public class RSRpcServices implements HBaseRPCErrorHandler,
if (request.hasCompactionState() && request.getCompactionState()) { if (request.hasCompactionState() && request.getCompactionState()) {
builder.setCompactionState(ProtobufUtil.createCompactionState(region.getCompactionState())); builder.setCompactionState(ProtobufUtil.createCompactionState(region.getCompactionState()));
} }
builder.setSplittable(region.isSplittable()); builder.setSplittable(region.isSplittable() && shouldSplit);
builder.setMergeable(region.isMergeable()); builder.setMergeable(region.isMergeable());
if (request.hasBestSplitRow() && request.getBestSplitRow() && bestSplitRow != null) { if (request.hasBestSplitRow() && request.getBestSplitRow() && bestSplitRow != null) {
builder.setBestSplitRow(UnsafeByteOperations.unsafeWrap(bestSplitRow)); builder.setBestSplitRow(UnsafeByteOperations.unsafeWrap(bestSplitRow));

View File

@ -31,6 +31,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import org.apache.hadoop.hbase.HBaseClassTestRule; import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseTestingUtility; import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HColumnDescriptor; import org.apache.hadoop.hbase.HColumnDescriptor;
@ -46,6 +47,7 @@ import org.apache.hadoop.hbase.TableNotEnabledException;
import org.apache.hadoop.hbase.TableNotFoundException; import org.apache.hadoop.hbase.TableNotFoundException;
import org.apache.hadoop.hbase.exceptions.MergeRegionException; import org.apache.hadoop.hbase.exceptions.MergeRegionException;
import org.apache.hadoop.hbase.master.LoadBalancer; import org.apache.hadoop.hbase.master.LoadBalancer;
import org.apache.hadoop.hbase.regionserver.DisabledRegionSplitPolicy;
import org.apache.hadoop.hbase.regionserver.HRegion; import org.apache.hadoop.hbase.regionserver.HRegion;
import org.apache.hadoop.hbase.regionserver.HStore; import org.apache.hadoop.hbase.regionserver.HStore;
import org.apache.hadoop.hbase.regionserver.HStoreFile; import org.apache.hadoop.hbase.regionserver.HStoreFile;
@ -54,6 +56,7 @@ import org.apache.hadoop.hbase.testclassification.LargeTests;
import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.FSUtils; import org.apache.hadoop.hbase.util.FSUtils;
import org.apache.hadoop.hbase.util.Pair; import org.apache.hadoop.hbase.util.Pair;
import org.apache.hadoop.hbase.util.Threads;
import org.junit.After; import org.junit.After;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Before; import org.junit.Before;
@ -65,7 +68,6 @@ import org.junit.experimental.categories.Category;
import org.junit.rules.TestName; import org.junit.rules.TestName;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.apache.hadoop.hbase.shaded.protobuf.RequestConverter; import org.apache.hadoop.hbase.shaded.protobuf.RequestConverter;
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MergeTableRegionsRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MergeTableRegionsRequest;
@ -1391,4 +1393,32 @@ public class TestAdmin1 {
this.admin.deleteTable(tableName); this.admin.deleteTable(tableName);
} }
} }
@Test
public void testSplitShouldNotHappenIfSplitIsDisabledForTable()
throws Exception {
final TableName tableName = TableName.valueOf(name.getMethodName());
HTableDescriptor htd = new HTableDescriptor(tableName);
htd.addFamily(new HColumnDescriptor("f"));
htd.setRegionSplitPolicyClassName(DisabledRegionSplitPolicy.class.getName());
Table table = TEST_UTIL.createTable(htd, null);
for(int i = 0; i < 10; i++) {
Put p = new Put(Bytes.toBytes("row"+i));
byte[] q1 = Bytes.toBytes("q1");
byte[] v1 = Bytes.toBytes("v1");
p.addColumn(Bytes.toBytes("f"), q1, v1);
table.put(p);
}
this.admin.flush(tableName);
try {
this.admin.split(tableName, Bytes.toBytes("row5"));
Threads.sleep(10000);
} catch (Exception e) {
// Nothing to do.
}
// Split should not happen.
List<RegionInfo> allRegions = MetaTableAccessor.getTableRegions(
this.admin.getConnection(), tableName, true);
assertEquals(1, allRegions.size());
}
} }