Skip to content

Commit e5d59ca

Browse files
authored
HBASE-28481 Prompting table already exists after failing to create table with many region replications (apache#5789)
Signed-off-by: Duo Zhang <zhangduo@apache.org> Reviewed-by: Vineet Kumar Maheshwari <vineet.4008@gmail.com>
1 parent c1012a9 commit e5d59ca

File tree

3 files changed

+42
-3
lines changed

3 files changed

+42
-3
lines changed

hbase-client/src/main/java/org/apache/hadoop/hbase/client/MutableRegionInfo.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ private static TableName checkTableName(TableName tableName) {
9696

9797
private static int checkReplicaId(int regionId) {
9898
if (regionId > MAX_REPLICA_ID) {
99-
throw new IllegalArgumentException("ReplicaId cannot be greater than" + MAX_REPLICA_ID);
99+
throw new IllegalArgumentException("ReplicaId cannot be greater than " + MAX_REPLICA_ID);
100100
}
101101
return regionId;
102102
}

hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/CreateTableProcedure.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@
5656
public class CreateTableProcedure extends AbstractStateMachineTableProcedure<CreateTableState> {
5757
private static final Logger LOG = LoggerFactory.getLogger(CreateTableProcedure.class);
5858

59+
private static final int MAX_REGION_REPLICATION = 0x10000;
60+
5961
private TableDescriptor tableDescriptor;
6062
private List<RegionInfo> newRegions;
6163

@@ -84,10 +86,10 @@ protected Flow executeFromState(final MasterProcedureEnv env, final CreateTableS
8486
switch (state) {
8587
case CREATE_TABLE_PRE_OPERATION:
8688
// Verify if we can create the table
87-
boolean exists = !prepareCreate(env);
89+
boolean success = prepareCreate(env);
8890
releaseSyncLatch();
8991

90-
if (exists) {
92+
if (!success) {
9193
assert isFailed() : "the delete should have an exception here";
9294
return Flow.NO_MORE_STATE;
9395
}
@@ -262,6 +264,14 @@ private boolean prepareCreate(final MasterProcedureEnv env) throws IOException {
262264
"Table " + getTableName().toString() + " should have at least one column family."));
263265
return false;
264266
}
267+
268+
int regionReplicationCount = tableDescriptor.getRegionReplication();
269+
if (regionReplicationCount > MAX_REGION_REPLICATION) {
270+
setFailure("master-create-table", new IllegalArgumentException(
271+
"Region Replication cannot exceed " + MAX_REGION_REPLICATION + "."));
272+
return false;
273+
}
274+
265275
if (!tableName.isSystemTable()) {
266276
// do not check rs group for system tables as we may block the bootstrap.
267277
Supplier<String> forWhom = () -> "table " + tableName;

hbase-server/src/test/java/org/apache/hadoop/hbase/master/procedure/TestCreateTableProcedure.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import static org.apache.hadoop.hbase.regionserver.storefiletracker.StoreFileTrackerFactory.TRACKER_IMPL;
2121
import static org.junit.Assert.assertEquals;
22+
import static org.junit.Assert.assertFalse;
2223
import static org.junit.Assert.assertTrue;
2324
import static org.junit.Assert.fail;
2425

@@ -284,4 +285,32 @@ public void testOnHDFSFailure() throws Exception {
284285
new CreateTableProcedureOnHDFSFailure(procExec.getEnvironment(), htd, regions));
285286
ProcedureTestingUtility.assertProcNotFailed(procExec, procId);
286287
}
288+
289+
@Test
290+
public void testCreateTableWithManyRegionReplication() throws IOException {
291+
final int EXCEED_MAX_REGION_REPLICATION = 0x10001;
292+
TableName tableName = TableName.valueOf(name.getMethodName());
293+
ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor();
294+
295+
TableDescriptor tableWithManyRegionReplication = TableDescriptorBuilder.newBuilder(tableName)
296+
.setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("f1")).build())
297+
.setRegionReplication(EXCEED_MAX_REGION_REPLICATION).build();
298+
RegionInfo[] regions01 =
299+
ModifyRegionUtils.createRegionInfos(tableWithManyRegionReplication, null);
300+
long procId01 = ProcedureTestingUtility.submitAndWait(procExec, new CreateTableProcedure(
301+
procExec.getEnvironment(), tableWithManyRegionReplication, regions01));
302+
Procedure<?> result01 = procExec.getResult(procId01);
303+
assertTrue(result01.getException().getCause() instanceof IllegalArgumentException);
304+
assertFalse(UTIL.getAdmin().tableExists(tableName));
305+
306+
TableDescriptor tdesc = TableDescriptorBuilder.newBuilder(tableName)
307+
.setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("f1")).build())
308+
.build();
309+
RegionInfo[] regions02 = ModifyRegionUtils.createRegionInfos(tdesc, null);
310+
long procId02 = ProcedureTestingUtility.submitAndWait(procExec,
311+
new CreateTableProcedure(procExec.getEnvironment(), tdesc, regions02));
312+
Procedure<?> result02 = procExec.getResult(procId02);
313+
assertTrue(result02.isSuccess());
314+
assertTrue(UTIL.getAdmin().tableExists(tableName));
315+
}
287316
}

0 commit comments

Comments
 (0)