From a601c57f9765d81206efebc33c5fbb35fc3310ff Mon Sep 17 00:00:00 2001 From: Rajeshbabu Chintaguntla Date: Tue, 27 Mar 2018 14:46:18 -0400 Subject: [PATCH] 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 --- .../assignment/SplitTableRegionProcedure.java | 2 +- .../hbase/regionserver/RSRpcServices.java | 5 ++- .../hadoop/hbase/client/TestAdmin1.java | 32 ++++++++++++++++++- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java index ffd92d13f88..994983f4aeb 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java @@ -179,7 +179,7 @@ public class SplitTableRegionProcedure } if (!splittable) { - IOException e = new IOException(regionToSplit.getShortNameToLog() + " NOT splittable"); + IOException e = new DoNotRetryIOException(regionToSplit.getShortNameToLog() + " NOT splittable"); if (splittableCheckIOE != null) e.initCause(splittableCheckIOE); throw e; } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java index 2793d2d2528..2c2d3cccfaf 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RSRpcServices.java @@ -1736,10 +1736,13 @@ public class RSRpcServices implements HBaseRPCErrorHandler, HRegion region = getRegion(request.getRegion()); RegionInfo info = region.getRegionInfo(); byte[] bestSplitRow = null; + boolean shouldSplit = true; if (request.hasBestSplitRow() && request.getBestSplitRow()) { HRegion r = region; region.startRegionOperation(Operation.SPLIT_REGION); 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(); // when all table data are in memstore, bestSplitRow = null // try to flush region first @@ -1754,7 +1757,7 @@ public class RSRpcServices implements HBaseRPCErrorHandler, if (request.hasCompactionState() && request.getCompactionState()) { builder.setCompactionState(ProtobufUtil.createCompactionState(region.getCompactionState())); } - builder.setSplittable(region.isSplittable()); + builder.setSplittable(region.isSplittable() && shouldSplit); builder.setMergeable(region.isMergeable()); if (request.hasBestSplitRow() && request.getBestSplitRow() && bestSplitRow != null) { builder.setBestSplitRow(UnsafeByteOperations.unsafeWrap(bestSplitRow)); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java index c48d13004be..8ac2ddafcbc 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java @@ -31,6 +31,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; + import org.apache.hadoop.hbase.HBaseClassTestRule; import org.apache.hadoop.hbase.HBaseTestingUtility; 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.exceptions.MergeRegionException; 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.HStore; 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.FSUtils; import org.apache.hadoop.hbase.util.Pair; +import org.apache.hadoop.hbase.util.Threads; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; @@ -65,7 +68,6 @@ import org.junit.experimental.categories.Category; import org.junit.rules.TestName; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import org.apache.hadoop.hbase.shaded.protobuf.RequestConverter; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MergeTableRegionsRequest; @@ -1391,4 +1393,32 @@ public class TestAdmin1 { 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 allRegions = MetaTableAccessor.getTableRegions( + this.admin.getConnection(), tableName, true); + assertEquals(1, allRegions.size()); + } }