HBASE-23904 Procedure updating meta and Master shutdown are incompatible: CODE-BUG

Restore behavior from before HBASE-21789 (hbase-2.2.0) where we convert
all exceptions to IOEs, even RuntimeExceptions. Actual fix is this change (in case
obscured by doc and lambda simplification):

     } catch (Throwable e) {
-      Throwables.propagateIfPossible(e, IOException.class);
+      // Throw if an IOE else wrap in an IOE EVEN IF IT IS a RuntimeException (e.g.
+      // a RejectedExecutionException because the hosting exception is shutting down.
+      // This is old behavior worth reexamining. Procedures doing merge or split
+      // currently don't handle RuntimeExceptions coming up out of meta table edits.
+      // Would have to work on this at least. See HBASE-23904.
+      Throwables.throwIfInstanceOf(e, IOException.class);
This commit is contained in:
stack 2020-02-26 22:16:11 -08:00
parent 6777e2c2d1
commit a420f0482e
1 changed files with 35 additions and 33 deletions

View File

@ -233,8 +233,7 @@ public class MetaTableAccessor {
* @return An {@link Table} for <code>hbase:meta</code> * @return An {@link Table} for <code>hbase:meta</code>
* @throws NullPointerException if {@code connection} is {@code null} * @throws NullPointerException if {@code connection} is {@code null}
*/ */
public static Table getMetaHTable(final Connection connection) public static Table getMetaHTable(final Connection connection) throws IOException {
throws IOException {
// We used to pass whole CatalogTracker in here, now we just pass in Connection // We used to pass whole CatalogTracker in here, now we just pass in Connection
Objects.requireNonNull(connection, "Connection cannot be null"); Objects.requireNonNull(connection, "Connection cannot be null");
if (connection.isClosed()) { if (connection.isClosed()) {
@ -1674,44 +1673,47 @@ public class MetaTableAccessor {
} }
/** /**
* Performs an atomic multi-mutate operation against the given table. * Performs an atomic multi-mutate operation against the given table. Used by the likes of
* merge and split as these want to make atomic mutations across multiple rows.
* @throws IOException even if we encounter a RuntimeException, we'll still wrap it in an IOE.
*/ */
private static void multiMutate(final Table table, byte[] row, final List<Mutation> mutations) @VisibleForTesting
static void multiMutate(final Table table, byte[] row, final List<Mutation> mutations)
throws IOException { throws IOException {
debugLogMutations(mutations); debugLogMutations(mutations);
Batch.Call<MultiRowMutationService, MutateRowsResponse> callable = Batch.Call<MultiRowMutationService, MutateRowsResponse> callable = instance -> {
new Batch.Call<MultiRowMutationService, MutateRowsResponse>() { MutateRowsRequest.Builder builder = MutateRowsRequest.newBuilder();
for (Mutation mutation : mutations) {
@Override if (mutation instanceof Put) {
public MutateRowsResponse call(MultiRowMutationService instance) throws IOException { builder.addMutationRequest(
MutateRowsRequest.Builder builder = MutateRowsRequest.newBuilder(); ProtobufUtil.toMutation(ClientProtos.MutationProto.MutationType.PUT, mutation));
for (Mutation mutation : mutations) { } else if (mutation instanceof Delete) {
if (mutation instanceof Put) { builder.addMutationRequest(
builder.addMutationRequest( ProtobufUtil.toMutation(ClientProtos.MutationProto.MutationType.DELETE, mutation));
ProtobufUtil.toMutation(ClientProtos.MutationProto.MutationType.PUT, mutation)); } else {
} else if (mutation instanceof Delete) { throw new DoNotRetryIOException(
builder.addMutationRequest( "multi in MetaEditor doesn't support " + mutation.getClass().getName());
ProtobufUtil.toMutation(ClientProtos.MutationProto.MutationType.DELETE, mutation));
} else {
throw new DoNotRetryIOException(
"multi in MetaEditor doesn't support " + mutation.getClass().getName());
}
}
ServerRpcController controller = new ServerRpcController();
CoprocessorRpcUtils.BlockingRpcCallback<MutateRowsResponse> rpcCallback =
new CoprocessorRpcUtils.BlockingRpcCallback<>();
instance.mutateRows(controller, builder.build(), rpcCallback);
MutateRowsResponse resp = rpcCallback.get();
if (controller.failedOnException()) {
throw controller.getFailedOn();
}
return resp;
} }
}; }
ServerRpcController controller = new ServerRpcController();
CoprocessorRpcUtils.BlockingRpcCallback<MutateRowsResponse> rpcCallback =
new CoprocessorRpcUtils.BlockingRpcCallback<>();
instance.mutateRows(controller, builder.build(), rpcCallback);
MutateRowsResponse resp = rpcCallback.get();
if (controller.failedOnException()) {
throw controller.getFailedOn();
}
return resp;
};
try { try {
table.coprocessorService(MultiRowMutationService.class, row, row, callable); table.coprocessorService(MultiRowMutationService.class, row, row, callable);
} catch (Throwable e) { } catch (Throwable e) {
Throwables.propagateIfPossible(e, IOException.class); // Throw if an IOE else wrap in an IOE EVEN IF IT IS a RuntimeException (e.g.
// a RejectedExecutionException because the hosting exception is shutting down.
// This is old behavior worth reexamining. Procedures doing merge or split
// currently don't handle RuntimeExceptions coming up out of meta table edits.
// Would have to work on this at least. See HBASE-23904.
Throwables.throwIfInstanceOf(e, IOException.class);
throw new IOException(e); throw new IOException(e);
} }
} }