Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HBASE-28064:Implement truncate_region command #5462

Merged
merged 2 commits into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1033,6 +1033,20 @@ default void modifyTable(TableDescriptor td) throws IOException {
get(modifyTableAsync(td), getSyncWaitTimeout(), TimeUnit.MILLISECONDS);
}

/**
* Truncate an individual region.
* @param regionName region to truncate
* @throws IOException if a remote or network exception occurs
*/
void truncateRegion(byte[] regionName) throws IOException;

/**
* Truncate an individual region. Asynchronous operation.
* @param regionName region to truncate
* @throws IOException if a remote or network exception occurs
*/
Future<Void> truncateRegionAsync(byte[] regionName) throws IOException;

/**
* Modify an existing table, more IRB (ruby) friendly version. Asynchronous operation. This means
* that it may be a while before your schema change is updated across all of the table. You can
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,16 @@ public Future<Void> splitRegionAsync(byte[] regionName, byte[] splitPoint) throw
return admin.splitRegion(regionName, splitPoint);
}

@Override
public void truncateRegion(byte[] regionName) throws IOException {
get(admin.truncateRegion(regionName));
}

@Override
public Future<Void> truncateRegionAsync(byte[] regionName) {
return admin.truncateRegion(regionName);
}

@Override
public Future<Void> modifyTableAsync(TableDescriptor td) throws IOException {
return admin.modifyTable(td);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,12 @@ default CompletableFuture<Void> mergeRegions(byte[] nameOfRegionA, byte[] nameOf
*/
CompletableFuture<Void> splitRegion(byte[] regionName, byte[] splitPoint);

/**
* Truncate an individual region.
* @param regionName region to truncate
*/
CompletableFuture<Void> truncateRegion(byte[] regionName);

/**
* Assign an individual region.
* @param regionName Encoded or full name of region to assign.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,11 @@ public CompletableFuture<Void> splitRegion(byte[] regionName, byte[] splitPoint)
return wrap(rawAdmin.splitRegion(regionName, splitPoint));
}

@Override
public CompletableFuture<Void> truncateRegion(byte[] regionName) {
return wrap(rawAdmin.truncateRegion(regionName));
}

@Override
public CompletableFuture<Void> assign(byte[] regionName) {
return wrap(rawAdmin.assign(regionName));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1623,6 +1623,60 @@ private CompletableFuture<Void> split(final RegionInfo hri, byte[] splitPoint) {
return future;
}

@Override
public CompletableFuture<Void> truncateRegion(byte[] regionName) {
CompletableFuture<Void> future = new CompletableFuture<>();
addListener(getRegionLocation(regionName), (location, err) -> {
if (err != null) {
future.completeExceptionally(err);
return;
}
RegionInfo regionInfo = location.getRegion();
if (regionInfo.getReplicaId() != RegionInfo.DEFAULT_REPLICA_ID) {
future.completeExceptionally(new IllegalArgumentException(
"Can't truncate replicas directly.Replicas are auto-truncated "
+ "when their primary is truncated."));
return;
}
ServerName serverName = location.getServerName();
if (serverName == null) {
future
.completeExceptionally(new NoServerForRegionException(Bytes.toStringBinary(regionName)));
return;
}
addListener(truncateRegion(regionInfo), (ret, err2) -> {
if (err2 != null) {
future.completeExceptionally(err2);
} else {
future.complete(ret);
}
});
});
return future;
}

private CompletableFuture<Void> truncateRegion(final RegionInfo hri) {
CompletableFuture<Void> future = new CompletableFuture<>();
TableName tableName = hri.getTable();
final MasterProtos.TruncateRegionRequest request;
try {
request = RequestConverter.buildTruncateRegionRequest(hri, ng.getNonceGroup(), ng.newNonce());
} catch (DeserializationException e) {
future.completeExceptionally(e);
return future;
}
addListener(this.procedureCall(tableName, request, MasterService.Interface::truncateRegion,
MasterProtos.TruncateRegionResponse::getProcId,
new TruncateRegionProcedureBiConsumer(tableName)), (ret, err2) -> {
if (err2 != null) {
future.completeExceptionally(err2);
} else {
future.complete(ret);
}
});
return future;
}

@Override
public CompletableFuture<Void> assign(byte[] regionName) {
CompletableFuture<Void> future = new CompletableFuture<>();
Expand Down Expand Up @@ -2882,6 +2936,18 @@ String getOperationType() {
}
}

private static class TruncateRegionProcedureBiConsumer extends TableProcedureBiConsumer {

TruncateRegionProcedureBiConsumer(TableName tableName) {
super(tableName);
}

@Override
String getOperationType() {
return "TRUNCATE_REGION";
}
}

private static class SnapshotProcedureBiConsumer extends TableProcedureBiConsumer {
SnapshotProcedureBiConsumer(TableName tableName) {
super(tableName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,17 @@ public static SplitTableRegionRequest buildSplitTableRegionRequest(final RegionI
return builder.build();
}

public static MasterProtos.TruncateRegionRequest
buildTruncateRegionRequest(final RegionInfo regionInfo, final long nonceGroup, final long nonce)
throws DeserializationException {
MasterProtos.TruncateRegionRequest.Builder builder =
MasterProtos.TruncateRegionRequest.newBuilder();
builder.setRegionInfo(ProtobufUtil.toRegionInfo(regionInfo));
builder.setNonceGroup(nonceGroup);
builder.setNonce(nonce);
return builder.build();
}

/**
* Create a protocol buffer AssignRegionRequest
* @return an AssignRegionRequest
Expand Down
16 changes: 16 additions & 0 deletions hbase-protocol-shaded/src/main/protobuf/server/master/Master.proto
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,16 @@ message SplitTableRegionResponse {
optional uint64 proc_id = 1;
}

message TruncateRegionRequest {
required RegionInfo region_info = 1;
optional uint64 nonce_group = 2 [default = 0];
optional uint64 nonce = 3 [default = 0];
}

message TruncateRegionResponse {
optional uint64 proc_id = 1;
}

message CreateTableRequest {
required TableSchema table_schema = 1;
repeated bytes split_keys = 2;
Expand Down Expand Up @@ -864,6 +874,12 @@ service MasterService {
rpc SplitRegion(SplitTableRegionRequest)
returns(SplitTableRegionResponse);

/**
* Truncate region
*/
rpc TruncateRegion(TruncateRegionRequest)
returns(TruncateRegionResponse);

/** Deletes a table */
rpc DeleteTable(DeleteTableRequest)
returns(DeleteTableResponse);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,14 @@ message TruncateTableStateData {
repeated RegionInfo region_info = 5;
}

enum TruncateRegionState {
TRUNCATE_REGION_PRE_OPERATION = 1;
TRUNCATE_REGION_MAKE_OFFLINE = 2;
TRUNCATE_REGION_REMOVE = 3;
TRUNCATE_REGION_MAKE_ONLINE = 4;
TRUNCATE_REGION_POST_OPERATION = 5;
}

enum DeleteTableState {
DELETE_TABLE_PRE_OPERATION = 1;
DELETE_TABLE_REMOVE_FROM_META = 2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,46 @@ default void preSplitRegionAction(final ObserverContext<MasterCoprocessorEnviron
final TableName tableName, final byte[] splitRow) throws IOException {
}

/**
* Called before the region is truncated.
* @param c The environment to interact with the framework and master
* @param regionInfo The Region being truncated
*/
@SuppressWarnings("unused")
default void preTruncateRegionAction(final ObserverContext<MasterCoprocessorEnvironment> c,
final RegionInfo regionInfo) {
}

/**
* Called before the truncate region procedure is called.
* @param c The environment to interact with the framework and master
* @param regionInfo The Region being truncated
*/
@SuppressWarnings("unused")
default void preTruncateRegion(final ObserverContext<MasterCoprocessorEnvironment> c,
RegionInfo regionInfo) {
}

/**
* Called after the truncate region procedure is called.
* @param c The environment to interact with the framework and master
* @param regionInfo The Region being truncated
*/
@SuppressWarnings("unused")
default void postTruncateRegion(final ObserverContext<MasterCoprocessorEnvironment> c,
RegionInfo regionInfo) {
}

/**
* Called post the region is truncated.
* @param c The environment to interact with the framework and master
* @param regionInfo The Region To be truncated
*/
@SuppressWarnings("unused")
default void postTruncateRegionAction(final ObserverContext<MasterCoprocessorEnvironment> c,
final RegionInfo regionInfo) {
}

/**
* Called after the region is split.
* @param c the environment to interact with the framework and master
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@
import org.apache.hadoop.hbase.master.procedure.ProcedureSyncWait;
import org.apache.hadoop.hbase.master.procedure.ReopenTableRegionsProcedure;
import org.apache.hadoop.hbase.master.procedure.ServerCrashProcedure;
import org.apache.hadoop.hbase.master.procedure.TruncateRegionProcedure;
import org.apache.hadoop.hbase.master.procedure.TruncateTableProcedure;
import org.apache.hadoop.hbase.master.region.MasterRegion;
import org.apache.hadoop.hbase.master.region.MasterRegionFactory;
Expand Down Expand Up @@ -2567,6 +2568,36 @@ protected String getDescription() {
});
}

@Override
public long truncateRegion(final RegionInfo regionInfo, final long nonceGroup, final long nonce)
throws IOException {
checkInitialized();

return MasterProcedureUtil
.submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {
@Override
protected void run() throws IOException {
getMaster().getMasterCoprocessorHost().preTruncateRegion(regionInfo);

LOG.info(
getClientIdAuditPrefix() + " truncate region " + regionInfo.getRegionNameAsString());

// Execute the operation asynchronously
ProcedurePrepareLatch latch = ProcedurePrepareLatch.createLatch(2, 0);
submitProcedure(
new TruncateRegionProcedure(procedureExecutor.getEnvironment(), regionInfo, latch));
latch.await();

getMaster().getMasterCoprocessorHost().postTruncateRegion(regionInfo);
}

@Override
protected String getDescription() {
return "TruncateRegionProcedure";
}
});
}

@Override
public long addColumn(final TableName tableName, final ColumnFamilyDescriptor column,
final long nonceGroup, final long nonce) throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,60 @@ public void call(MasterObserver observer) throws IOException {
});
}

/**
* Invoked just before calling the truncate region procedure
* @param regionInfo region being truncated
*/
public void preTruncateRegion(RegionInfo regionInfo) throws IOException {
execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
@Override
public void call(MasterObserver observer) {
observer.preTruncateRegion(this, regionInfo);
}
});
}

/**
* Invoked after calling the truncate region procedure
* @param regionInfo region being truncated
*/
public void postTruncateRegion(RegionInfo regionInfo) throws IOException {
execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
@Override
public void call(MasterObserver observer) {
observer.postTruncateRegion(this, regionInfo);
}
});
}

/**
* Invoked just before calling the truncate region procedure
* @param region Region to be truncated
* @param user The user
*/
public void preTruncateRegionAction(final RegionInfo region, User user) throws IOException {
execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
@Override
public void call(MasterObserver observer) throws IOException {
observer.preTruncateRegionAction(this, region);
}
});
}

/**
* Invoked after calling the truncate region procedure
* @param region Region which was truncated
* @param user The user
*/
public void postTruncateRegionAction(final RegionInfo region, User user) throws IOException {
execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
@Override
public void call(MasterObserver observer) throws IOException {
observer.postTruncateRegionAction(this, region);
}
});
}

/**
* This will be called before update META step as part of split table region procedure.
* @param user the user
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -958,6 +958,18 @@ public SplitTableRegionResponse splitRegion(final RpcController controller,
}
}

@Override
public MasterProtos.TruncateRegionResponse truncateRegion(RpcController controller,
final MasterProtos.TruncateRegionRequest request) throws ServiceException {
try {
long procId = server.truncateRegion(ProtobufUtil.toRegionInfo(request.getRegionInfo()),
request.getNonceGroup(), request.getNonce());
return MasterProtos.TruncateRegionResponse.newBuilder().setProcId(procId).build();
} catch (IOException ie) {
throw new ServiceException(ie);
}
}

@Override
public ClientProtos.CoprocessorServiceResponse execMasterService(final RpcController controller,
final ClientProtos.CoprocessorServiceRequest request) throws ServiceException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -488,4 +488,13 @@ boolean normalizeRegions(final NormalizeTableFilterParams ntfp, final boolean is
*/
long flushTable(final TableName tableName, final List<byte[]> columnFamilies,
final long nonceGroup, final long nonce) throws IOException;

/**
* Truncate region
* @param regionInfo region to be truncated
* @param nonceGroup the nonce group
* @param nonce the nonce
* @return procedure Id
*/
long truncateRegion(RegionInfo regionInfo, long nonceGroup, long nonce) throws IOException;
}
Loading