Skip to content

Commit 4b5db21

Browse files
authored
HBASE-25549 Provide a switch that allows avoiding reopening all regions when modifying a table to prevent RIT storms. (#2924)
Co-authored-by: Huangzhuoyue <huangzhuoyue@apache.org> Signed-off-by: Bryan Beaudreault <bbeaudreault@apache.org> Signed-off-by: Wellington Chevreuil <wchevreuil@apache.org> Signed-off-by: Viraj Jasani <vjasani@apache.org> Signed-off-by: Bharath Vissapragada <bharathv@apache.org> Signed-off-by: Esteban Gutierrez <esteban@apache.org> Reviewed-by: Sean Busbey <busbey@apache.org> Reviewed-by: Gourab Taparia
1 parent d8b5198 commit 4b5db21

20 files changed

Lines changed: 332 additions & 23 deletions

File tree

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1058,7 +1058,24 @@ default void modifyTable(TableDescriptor td) throws IOException {
10581058
* @return the result of the async modify. You can use Future.get(long, TimeUnit) to wait on the
10591059
* operation to complete
10601060
*/
1061-
Future<Void> modifyTableAsync(TableDescriptor td) throws IOException;
1061+
default Future<Void> modifyTableAsync(TableDescriptor td) throws IOException {
1062+
return modifyTableAsync(td, true);
1063+
}
1064+
1065+
/**
1066+
* The same as {@link #modifyTableAsync(TableDescriptor td)}, except for the reopenRegions
1067+
* parameter, which controls whether the process of modifying the table should reopen all regions.
1068+
* @param td description of the table
1069+
* @param reopenRegions By default, 'modifyTable' reopens all regions, potentially causing a RIT
1070+
* (Region In Transition) storm in large tables. If set to 'false', regions
1071+
* will remain unaware of the modification until they are individually
1072+
* reopened. Please note that this may temporarily result in configuration
1073+
* inconsistencies among regions.
1074+
* @return the result of the async modify. You can use Future.get(long, TimeUnit) to wait on the
1075+
* operation to complete
1076+
* @throws IOException if a remote or network exception occurs
1077+
*/
1078+
Future<Void> modifyTableAsync(TableDescriptor td, boolean reopenRegions) throws IOException;
10621079

10631080
/**
10641081
* Change the store file tracker of the given table.

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,13 @@ public Future<Void> truncateRegionAsync(byte[] regionName) {
502502

503503
@Override
504504
public Future<Void> modifyTableAsync(TableDescriptor td) throws IOException {
505-
return admin.modifyTable(td);
505+
return modifyTableAsync(td, true);
506+
}
507+
508+
@Override
509+
public Future<Void> modifyTableAsync(TableDescriptor td, boolean reopenRegions)
510+
throws IOException {
511+
return admin.modifyTable(td, reopenRegions);
506512
}
507513

508514
@Override

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,20 @@ CompletableFuture<Void> createTable(TableDescriptor desc, byte[] startKey, byte[
198198
* Modify an existing table, more IRB friendly version.
199199
* @param desc modified description of the table
200200
*/
201-
CompletableFuture<Void> modifyTable(TableDescriptor desc);
201+
default CompletableFuture<Void> modifyTable(TableDescriptor desc) {
202+
return modifyTable(desc, true);
203+
}
204+
205+
/**
206+
* Modify an existing table, more IRB friendly version.
207+
* @param desc description of the table
208+
* @param reopenRegions By default, 'modifyTable' reopens all regions, potentially causing a RIT
209+
* (Region In Transition) storm in large tables. If set to 'false', regions
210+
* will remain unaware of the modification until they are individually
211+
* reopened. Please note that this may temporarily result in configuration
212+
* inconsistencies among regions.
213+
*/
214+
CompletableFuture<Void> modifyTable(TableDescriptor desc, boolean reopenRegions);
202215

203216
/**
204217
* Change the store file tracker of the given table.

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,12 @@ public CompletableFuture<Void> createTable(TableDescriptor desc, byte[][] splitK
153153

154154
@Override
155155
public CompletableFuture<Void> modifyTable(TableDescriptor desc) {
156-
return wrap(rawAdmin.modifyTable(desc));
156+
return modifyTable(desc, true);
157+
}
158+
159+
@Override
160+
public CompletableFuture<Void> modifyTable(TableDescriptor desc, boolean reopenRegions) {
161+
return wrap(rawAdmin.modifyTable(desc, reopenRegions));
157162
}
158163

159164
@Override

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -694,9 +694,14 @@ private CompletableFuture<Void> createTable(TableName tableName, CreateTableRequ
694694

695695
@Override
696696
public CompletableFuture<Void> modifyTable(TableDescriptor desc) {
697+
return modifyTable(desc, true);
698+
}
699+
700+
@Override
701+
public CompletableFuture<Void> modifyTable(TableDescriptor desc, boolean reopenRegions) {
697702
return this.<ModifyTableRequest, ModifyTableResponse> procedureCall(desc.getTableName(),
698703
RequestConverter.buildModifyTableRequest(desc.getTableName(), desc, ng.getNonceGroup(),
699-
ng.newNonce()),
704+
ng.newNonce(), reopenRegions),
700705
(s, c, req, done) -> s.modifyTable(c, req, done), (resp) -> resp.getProcId(),
701706
new ModifyTableProcedureBiConsumer(this, desc.getTableName()));
702707
}

hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/RequestConverter.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1108,12 +1108,14 @@ public static CreateTableRequest buildCreateTableRequest(final TableDescriptor t
11081108
* @return a ModifyTableRequest
11091109
*/
11101110
public static ModifyTableRequest buildModifyTableRequest(final TableName tableName,
1111-
final TableDescriptor tableDesc, final long nonceGroup, final long nonce) {
1111+
final TableDescriptor tableDesc, final long nonceGroup, final long nonce,
1112+
final boolean reopenRegions) {
11121113
ModifyTableRequest.Builder builder = ModifyTableRequest.newBuilder();
11131114
builder.setTableName(ProtobufUtil.toProtoTableName(tableName));
11141115
builder.setTableSchema(ProtobufUtil.toTableSchema(tableDesc));
11151116
builder.setNonceGroup(nonceGroup);
11161117
builder.setNonce(nonce);
1118+
builder.setReopenRegions(reopenRegions);
11171119
return builder.build();
11181120
}
11191121

hbase-protocol-shaded/src/main/protobuf/server/master/Master.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ message ModifyTableRequest {
204204
required TableSchema table_schema = 2;
205205
optional uint64 nonce_group = 3 [default = 0];
206206
optional uint64 nonce = 4 [default = 0];
207+
optional bool reopen_regions = 5 [default = true];
207208
}
208209

209210
message ModifyTableResponse {

hbase-protocol-shaded/src/main/protobuf/server/master/MasterProcedure.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ message ModifyTableStateData {
8282
required TableSchema modified_table_schema = 3;
8383
required bool delete_column_family_in_modify = 4;
8484
optional bool should_check_descriptor = 5;
85+
optional bool reopen_regions = 6;
8586
}
8687

8788
enum TruncateTableState {

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,7 +1164,7 @@ private void finishActiveMasterInitialization() throws IOException, InterruptedE
11641164
procedureExecutor.submitProcedure(new ModifyTableProcedure(
11651165
procedureExecutor.getEnvironment(), TableDescriptorBuilder.newBuilder(metaDesc)
11661166
.setRegionReplication(replicasNumInConf).build(),
1167-
null, metaDesc, false));
1167+
null, metaDesc, false, true));
11681168
}
11691169
}
11701170
}
@@ -2794,6 +2794,13 @@ protected String getDescription() {
27942794
private long modifyTable(final TableName tableName,
27952795
final TableDescriptorGetter newDescriptorGetter, final long nonceGroup, final long nonce,
27962796
final boolean shouldCheckDescriptor) throws IOException {
2797+
return modifyTable(tableName, newDescriptorGetter, nonceGroup, nonce, shouldCheckDescriptor,
2798+
true);
2799+
}
2800+
2801+
private long modifyTable(final TableName tableName,
2802+
final TableDescriptorGetter newDescriptorGetter, final long nonceGroup, final long nonce,
2803+
final boolean shouldCheckDescriptor, final boolean reopenRegions) throws IOException {
27972804
return MasterProcedureUtil
27982805
.submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {
27992806
@Override
@@ -2812,7 +2819,7 @@ protected void run() throws IOException {
28122819
// checks. This will block only the beginning of the procedure. See HBASE-19953.
28132820
ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();
28142821
submitProcedure(new ModifyTableProcedure(procedureExecutor.getEnvironment(),
2815-
newDescriptor, latch, oldDescriptor, shouldCheckDescriptor));
2822+
newDescriptor, latch, oldDescriptor, shouldCheckDescriptor, reopenRegions));
28162823
latch.await();
28172824

28182825
getMaster().getMasterCoprocessorHost().postModifyTable(tableName, oldDescriptor,
@@ -2829,14 +2836,14 @@ protected String getDescription() {
28292836

28302837
@Override
28312838
public long modifyTable(final TableName tableName, final TableDescriptor newDescriptor,
2832-
final long nonceGroup, final long nonce) throws IOException {
2839+
final long nonceGroup, final long nonce, final boolean reopenRegions) throws IOException {
28332840
checkInitialized();
28342841
return modifyTable(tableName, new TableDescriptorGetter() {
28352842
@Override
28362843
public TableDescriptor get() throws IOException {
28372844
return newDescriptor;
28382845
}
2839-
}, nonceGroup, nonce, false);
2846+
}, nonceGroup, nonce, false, reopenRegions);
28402847

28412848
}
28422849

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1544,7 +1544,8 @@ public ModifyTableResponse modifyTable(RpcController controller, ModifyTableRequ
15441544
throws ServiceException {
15451545
try {
15461546
long procId = server.modifyTable(ProtobufUtil.toTableName(req.getTableName()),
1547-
ProtobufUtil.toTableDescriptor(req.getTableSchema()), req.getNonceGroup(), req.getNonce());
1547+
ProtobufUtil.toTableDescriptor(req.getTableSchema()), req.getNonceGroup(), req.getNonce(),
1548+
req.getReopenRegions());
15481549
return ModifyTableResponse.newBuilder().setProcId(procId).build();
15491550
} catch (IOException ioe) {
15501551
throw new ServiceException(ioe);

0 commit comments

Comments
 (0)