diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/MutableRegionInfo.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/MutableRegionInfo.java index a9382f3a9bed..4217201b85e3 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/MutableRegionInfo.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/MutableRegionInfo.java @@ -96,7 +96,7 @@ private static TableName checkTableName(TableName tableName) { private static int checkReplicaId(int regionId) { if (regionId > MAX_REPLICA_ID) { - throw new IllegalArgumentException("ReplicaId cannot be greater than" + MAX_REPLICA_ID); + throw new IllegalArgumentException("ReplicaId cannot be greater than " + MAX_REPLICA_ID); } return regionId; } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/CreateTableProcedure.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/CreateTableProcedure.java index 37aea5e2f7db..08be72388213 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/CreateTableProcedure.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/CreateTableProcedure.java @@ -55,6 +55,8 @@ public class CreateTableProcedure extends AbstractStateMachineTableProcedure { private static final Logger LOG = LoggerFactory.getLogger(CreateTableProcedure.class); + private static final int MAX_REGION_REPLICATION = 0x10000; + private TableDescriptor tableDescriptor; private List newRegions; @@ -83,10 +85,10 @@ protected Flow executeFromState(final MasterProcedureEnv env, final CreateTableS switch (state) { case CREATE_TABLE_PRE_OPERATION: // Verify if we can create the table - boolean exists = !prepareCreate(env); + boolean success = prepareCreate(env); releaseSyncLatch(); - if (exists) { + if (!success) { assert isFailed() : "the delete should have an exception here"; return Flow.NO_MORE_STATE; } @@ -252,6 +254,13 @@ private boolean prepareCreate(final MasterProcedureEnv env) throws IOException { return false; } + int regionReplicationCount = tableDescriptor.getRegionReplication(); + if (regionReplicationCount > MAX_REGION_REPLICATION) { + setFailure("master-create-table", new IllegalArgumentException( + "Region Replication cannot exceed " + MAX_REGION_REPLICATION + ".")); + return false; + } + // check for store file tracker configurations StoreFileTrackerValidationUtils.checkForCreateTable(env.getMasterConfiguration(), tableDescriptor); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestCreateTableProcedure.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestCreateTableProcedure.java index 618a4a45a044..bed41f4da86c 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestCreateTableProcedure.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestCreateTableProcedure.java @@ -19,6 +19,7 @@ import static org.apache.hadoop.hbase.regionserver.storefiletracker.StoreFileTrackerFactory.TRACKER_IMPL; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -284,4 +285,32 @@ public void testOnHDFSFailure() throws Exception { new CreateTableProcedureOnHDFSFailure(procExec.getEnvironment(), htd, regions)); ProcedureTestingUtility.assertProcNotFailed(procExec, procId); } + + @Test + public void testCreateTableWithManyRegionReplication() throws IOException { + final int EXCEED_MAX_REGION_REPLICATION = 0x10001; + TableName tableName = TableName.valueOf(name.getMethodName()); + ProcedureExecutor procExec = getMasterProcedureExecutor(); + + TableDescriptor tableWithManyRegionReplication = TableDescriptorBuilder.newBuilder(tableName) + .setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("f1")).build()) + .setRegionReplication(EXCEED_MAX_REGION_REPLICATION).build(); + RegionInfo[] regions01 = + ModifyRegionUtils.createRegionInfos(tableWithManyRegionReplication, null); + long procId01 = ProcedureTestingUtility.submitAndWait(procExec, new CreateTableProcedure( + procExec.getEnvironment(), tableWithManyRegionReplication, regions01)); + Procedure result01 = procExec.getResult(procId01); + assertTrue(result01.getException().getCause() instanceof IllegalArgumentException); + assertFalse(UTIL.getAdmin().tableExists(tableName)); + + TableDescriptor tdesc = TableDescriptorBuilder.newBuilder(tableName) + .setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("f1")).build()) + .build(); + RegionInfo[] regions02 = ModifyRegionUtils.createRegionInfos(tdesc, null); + long procId02 = ProcedureTestingUtility.submitAndWait(procExec, + new CreateTableProcedure(procExec.getEnvironment(), tdesc, regions02)); + Procedure result02 = procExec.getResult(procId02); + assertTrue(result02.isSuccess()); + assertTrue(UTIL.getAdmin().tableExists(tableName)); + } }