Skip to content

Commit 3bc82c7

Browse files
committed
HBASE-28064:Implement truncate_region command to truncate region directly from FS
Implemented truncate_region command.
1 parent 391dfda commit 3bc82c7

File tree

26 files changed

+857
-1
lines changed

26 files changed

+857
-1
lines changed

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,6 +1033,20 @@ default void modifyTable(TableDescriptor td) throws IOException {
10331033
get(modifyTableAsync(td), getSyncWaitTimeout(), TimeUnit.MILLISECONDS);
10341034
}
10351035

1036+
/**
1037+
* Truncate an individual region.
1038+
* @param regionName region to truncate
1039+
* @throws IOException if a remote or network exception occurs
1040+
*/
1041+
void truncateRegion(byte[] regionName) throws IOException;
1042+
1043+
/**
1044+
* Truncate an individual region. Asynchronous operation.
1045+
* @param regionName region to truncate
1046+
* @throws IOException if a remote or network exception occurs
1047+
*/
1048+
Future<Void> truncateRegionAsync(byte[] regionName) throws IOException;
1049+
10361050
/**
10371051
* Modify an existing table, more IRB (ruby) friendly version. Asynchronous operation. This means
10381052
* that it may be a while before your schema change is updated across all of the table. You can

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,16 @@ public Future<Void> splitRegionAsync(byte[] regionName, byte[] splitPoint) throw
490490
return admin.splitRegion(regionName, splitPoint);
491491
}
492492

493+
@Override
494+
public void truncateRegion(byte[] regionName) throws IOException {
495+
get(admin.truncateRegion(regionName));
496+
}
497+
498+
@Override
499+
public Future<Void> truncateRegionAsync(byte[] regionName) {
500+
return admin.truncateRegion(regionName);
501+
}
502+
493503
@Override
494504
public Future<Void> modifyTableAsync(TableDescriptor td) throws IOException {
495505
return admin.modifyTable(td);

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,12 @@ default CompletableFuture<Void> mergeRegions(byte[] nameOfRegionA, byte[] nameOf
618618
*/
619619
CompletableFuture<Void> splitRegion(byte[] regionName, byte[] splitPoint);
620620

621+
/**
622+
* Truncate an individual region.
623+
* @param regionName region to truncate
624+
*/
625+
CompletableFuture<Void> truncateRegion(byte[] regionName);
626+
621627
/**
622628
* Assign an individual region.
623629
* @param regionName Encoded or full name of region to assign.

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,11 @@ public CompletableFuture<Void> splitRegion(byte[] regionName, byte[] splitPoint)
386386
return wrap(rawAdmin.splitRegion(regionName, splitPoint));
387387
}
388388

389+
@Override
390+
public CompletableFuture<Void> truncateRegion(byte[] regionName) {
391+
return wrap(rawAdmin.truncateRegion(regionName));
392+
}
393+
389394
@Override
390395
public CompletableFuture<Void> assign(byte[] regionName) {
391396
return wrap(rawAdmin.assign(regionName));

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

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1623,6 +1623,61 @@ private CompletableFuture<Void> split(final RegionInfo hri, byte[] splitPoint) {
16231623
return future;
16241624
}
16251625

1626+
@Override
1627+
public CompletableFuture<Void> truncateRegion(byte[] regionName) {
1628+
CompletableFuture<Void> future = new CompletableFuture<>();
1629+
addListener(getRegionLocation(regionName), (location, err) -> {
1630+
if (err != null) {
1631+
future.completeExceptionally(err);
1632+
return;
1633+
}
1634+
RegionInfo regionInfo = location.getRegion();
1635+
if (regionInfo.getReplicaId() != RegionInfo.DEFAULT_REPLICA_ID) {
1636+
future.completeExceptionally(new IllegalArgumentException(
1637+
"Can't truncate replicas directly.Replicas are auto-truncated "
1638+
+ "when their primary is truncated."));
1639+
return;
1640+
}
1641+
ServerName serverName = location.getServerName();
1642+
if (serverName == null) {
1643+
future
1644+
.completeExceptionally(new NoServerForRegionException(Bytes.toStringBinary(regionName)));
1645+
return;
1646+
}
1647+
addListener(truncate_region(regionInfo), (ret, err2) -> {
1648+
if (err2 != null) {
1649+
future.completeExceptionally(err2);
1650+
} else {
1651+
future.complete(ret);
1652+
}
1653+
});
1654+
});
1655+
return future;
1656+
}
1657+
1658+
private CompletableFuture<Void> truncate_region(final RegionInfo hri) {
1659+
CompletableFuture<Void> future = new CompletableFuture<>();
1660+
TableName tableName = hri.getTable();
1661+
final MasterProtos.TruncateRegionRequest request;
1662+
try {
1663+
request =
1664+
RequestConverter.buildSTruncateRegionRequest(hri, ng.getNonceGroup(), ng.newNonce());
1665+
} catch (DeserializationException e) {
1666+
future.completeExceptionally(e);
1667+
return future;
1668+
}
1669+
addListener(this.procedureCall(tableName, request, MasterService.Interface::truncateRegion,
1670+
MasterProtos.TruncateRegionResponse::getProcId,
1671+
new TruncateRegionProcedureBiConsumer(tableName)), (ret, err2) -> {
1672+
if (err2 != null) {
1673+
future.completeExceptionally(err2);
1674+
} else {
1675+
future.complete(ret);
1676+
}
1677+
});
1678+
return future;
1679+
}
1680+
16261681
@Override
16271682
public CompletableFuture<Void> assign(byte[] regionName) {
16281683
CompletableFuture<Void> future = new CompletableFuture<>();
@@ -2882,6 +2937,18 @@ String getOperationType() {
28822937
}
28832938
}
28842939

2940+
private static class TruncateRegionProcedureBiConsumer extends TableProcedureBiConsumer {
2941+
2942+
TruncateRegionProcedureBiConsumer(TableName tableName) {
2943+
super(tableName);
2944+
}
2945+
2946+
@Override
2947+
String getOperationType() {
2948+
return "TRUNCATE_REGION";
2949+
}
2950+
}
2951+
28852952
private static class SnapshotProcedureBiConsumer extends TableProcedureBiConsumer {
28862953
SnapshotProcedureBiConsumer(TableName tableName) {
28872954
super(tableName);

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -989,6 +989,17 @@ public static SplitTableRegionRequest buildSplitTableRegionRequest(final RegionI
989989
return builder.build();
990990
}
991991

992+
public static MasterProtos.TruncateRegionRequest buildSTruncateRegionRequest(
993+
final RegionInfo regionInfo, final long nonceGroup, final long nonce)
994+
throws DeserializationException {
995+
MasterProtos.TruncateRegionRequest.Builder builder =
996+
MasterProtos.TruncateRegionRequest.newBuilder();
997+
builder.setRegionInfo(ProtobufUtil.toRegionInfo(regionInfo));
998+
builder.setNonceGroup(nonceGroup);
999+
builder.setNonce(nonce);
1000+
return builder.build();
1001+
}
1002+
9921003
/**
9931004
* Create a protocol buffer AssignRegionRequest
9941005
* @return an AssignRegionRequest

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,16 @@ message SplitTableRegionResponse {
137137
optional uint64 proc_id = 1;
138138
}
139139

140+
message TruncateRegionRequest {
141+
required RegionInfo region_info = 1;
142+
optional uint64 nonce_group = 2 [default = 0];
143+
optional uint64 nonce = 3 [default = 0];
144+
}
145+
146+
message TruncateRegionResponse {
147+
optional uint64 proc_id = 1;
148+
}
149+
140150
message CreateTableRequest {
141151
required TableSchema table_schema = 1;
142152
repeated bytes split_keys = 2;
@@ -864,6 +874,12 @@ service MasterService {
864874
rpc SplitRegion(SplitTableRegionRequest)
865875
returns(SplitTableRegionResponse);
866876

877+
/**
878+
* Truncate region
879+
*/
880+
rpc TruncateRegion(TruncateRegionRequest)
881+
returns(TruncateRegionResponse);
882+
867883
/** Deletes a table */
868884
rpc DeleteTable(DeleteTableRequest)
869885
returns(DeleteTableResponse);

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,20 @@ message TruncateTableStateData {
102102
repeated RegionInfo region_info = 5;
103103
}
104104

105+
enum TruncateRegionState {
106+
TRUNCATE_REGION_PRE_OPERATION = 1;
107+
TRUNCATE_REGION_MAKE_OFFLINE = 2;
108+
TRUNCATE_REGION_REMOVE = 3;
109+
TRUNCATE_REGION_MAKE_ONLINE = 4;
110+
TRUNCATE_REGION_POST_OPERATION = 5;
111+
}
112+
113+
message TruncateRegionStateData {
114+
required UserInformation user_info = 1;
115+
required RegionInfo region = 2;
116+
optional RegionInfo new_region = 3;
117+
}
118+
105119
enum DeleteTableState {
106120
DELETE_TABLE_PRE_OPERATION = 1;
107121
DELETE_TABLE_REMOVE_FROM_META = 2;

hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,26 @@ default void preSplitRegionAction(final ObserverContext<MasterCoprocessorEnviron
585585
final TableName tableName, final byte[] splitRow) throws IOException {
586586
}
587587

588+
/**
589+
* Called before the region is truncated.
590+
* @param c The environment to interact with the framework and master
591+
* @param regionInfo The Region To be truncated
592+
*/
593+
@SuppressWarnings("unused")
594+
default void preTruncateRegionAction(final ObserverContext<MasterCoprocessorEnvironment> c,
595+
final RegionInfo regionInfo) {
596+
}
597+
598+
/**
599+
* Called post the region is truncated.
600+
* @param c The environment to interact with the framework and master
601+
* @param regionInfo The Region To be truncated
602+
*/
603+
@SuppressWarnings("unused")
604+
default void postTruncateRegionAction(final ObserverContext<MasterCoprocessorEnvironment> c,
605+
final RegionInfo regionInfo) {
606+
}
607+
588608
/**
589609
* Called after the region is split.
590610
* @param c the environment to interact with the framework and master

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2275,6 +2275,29 @@ protected String getDescription() {
22752275
});
22762276
}
22772277

2278+
@Override
2279+
public long truncateRegion(final RegionInfo regionInfo, final long nonceGroup, final long nonce)
2280+
throws IOException {
2281+
checkInitialized();
2282+
2283+
return MasterProcedureUtil
2284+
.submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {
2285+
@Override
2286+
protected void run() throws IOException {
2287+
LOG.info(
2288+
getClientIdAuditPrefix() + " truncate region " + regionInfo.getRegionNameAsString());
2289+
2290+
// Execute the operation asynchronously
2291+
submitProcedure(getAssignmentManager().createTruncateRegionProcedure(regionInfo));
2292+
}
2293+
2294+
@Override
2295+
protected String getDescription() {
2296+
return "TruncateRegionProcedure";
2297+
}
2298+
});
2299+
}
2300+
22782301
private void warmUpRegion(ServerName server, RegionInfo region) {
22792302
FutureUtils.addListener(asyncClusterConnection.getRegionServerAdmin(server)
22802303
.warmupRegion(RequestConverter.buildWarmupRegionRequest(region)), (r, e) -> {

0 commit comments

Comments
 (0)