You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by zh...@apache.org on 2020/10/13 03:42:22 UTC
[hbase] 09/09: HBASE-25013 Avoid reset the backup master root cache
every time when syncing (#2392)
This is an automated email from the ASF dual-hosted git repository.
zhangduo pushed a commit to branch HBASE-24950
in repository https://gitbox.apache.org/repos/asf/hbase.git
commit 26059a944daea06fc567a2ecdf5c8a0b514f484a
Author: Duo Zhang <zh...@apache.org>
AuthorDate: Mon Sep 21 20:32:15 2020 +0800
HBASE-25013 Avoid reset the backup master root cache every time when syncing (#2392)
Signed-off-by: Guanghao Zhang <zg...@apache.org>
---
.../org/apache/hadoop/hbase/MetaTableAccessor.java | 21 +--
.../hadoop/hbase/ClientMetaTableAccessor.java | 23 ++++
.../hadoop/hbase/client/ConnectionUtils.java | 39 +-----
.../apache/hadoop/hbase/client/MasterRegistry.java | 11 +-
.../hadoop/hbase/client/ZKConnectionRegistry.java | 25 +++-
.../src/main/protobuf/server/master/Master.proto | 14 ++
.../hbase/client/AsyncClusterConnection.java | 3 +-
.../hbase/client/AsyncClusterConnectionImpl.java | 52 +++++--
.../hadoop/hbase/coprocessor/MasterObserver.java | 20 +++
.../org/apache/hadoop/hbase/master/HMaster.java | 70 +++-------
.../hadoop/hbase/master/MasterCoprocessorHost.java | 19 +++
.../hadoop/hbase/master/MasterRpcServices.java | 62 +++++++--
.../hadoop/hbase/master/MetaLocationCache.java | 45 ++++--
.../hbase/master/assignment/AssignmentManager.java | 33 ++---
.../hbase/master/assignment/RegionStateStore.java | 128 +++++++----------
.../hadoop/hbase/master/region/MasterRegion.java | 9 ++
.../region/RegionScannerAsResultScanner.java | 88 ++++++++++++
.../hadoop/hbase/master/region/RootStore.java | 153 +++++++++++++++++++++
.../apache/hadoop/hbase/regionserver/HRegion.java | 1 -
.../hbase/client/DummyAsyncClusterConnection.java | 5 +-
.../hadoop/hbase/client/TestAsyncAdminBase.java | 5 +-
.../client/TestFailedMetaReplicaAssigment.java | 10 +-
.../hbase/master/TestBackupMasterSyncRoot.java | 113 +++++++++++++++
.../hbase/master/TestCloseAnOpeningRegion.java | 6 +-
.../hbase/master/TestClusterRestartFailover.java | 10 +-
.../hadoop/hbase/master/TestMetaLocationCache.java | 12 +-
.../master/assignment/MockMasterServices.java | 8 +-
.../assignment/TestOpenRegionProcedureBackoff.java | 10 +-
.../assignment/TestOpenRegionProcedureHang.java | 10 +-
.../assignment/TestRaceBetweenSCPAndDTP.java | 10 +-
.../assignment/TestRaceBetweenSCPAndTRSP.java | 10 +-
.../TestRegionAssignedToMultipleRegionServers.java | 10 +-
.../assignment/TestReportOnlineRegionsRace.java | 10 +-
...tReportRegionStateTransitionFromDeadServer.java | 10 +-
.../TestReportRegionStateTransitionRetry.java | 10 +-
.../master/assignment/TestSCPGetRegionsRace.java | 10 +-
.../assignment/TestWakeUpUnexpectedProcedure.java | 10 +-
.../apache/hadoop/hbase/util/TestRegionMover2.java | 13 +-
38 files changed, 776 insertions(+), 322 deletions(-)
diff --git a/hbase-balancer/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java b/hbase-balancer/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java
index 09552ed..91e41f5 100644
--- a/hbase-balancer/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java
+++ b/hbase-balancer/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java
@@ -465,8 +465,7 @@ public final class MetaTableAccessor {
public static void scanMeta(Connection connection, @Nullable final byte[] startRow,
@Nullable final byte[] stopRow, QueryType type, @Nullable Filter filter, int maxRows,
final ClientMetaTableAccessor.Visitor visitor) throws IOException {
- int rowUpperLimit = maxRows > 0 ? maxRows : Integer.MAX_VALUE;
- Scan scan = getMetaScan(connection.getConfiguration(), rowUpperLimit);
+ Scan scan = getMetaScan(connection.getConfiguration(), maxRows);
for (byte[] family : type.getFamilies()) {
scan.addFamily(family);
@@ -483,26 +482,12 @@ public final class MetaTableAccessor {
if (LOG.isTraceEnabled()) {
LOG.trace("Scanning META" + " starting at row=" + Bytes.toStringBinary(startRow) +
- " stopping at row=" + Bytes.toStringBinary(stopRow) + " for max=" + rowUpperLimit +
+ " stopping at row=" + Bytes.toStringBinary(stopRow) + " for max=" + maxRows +
" with caching=" + scan.getCaching());
}
-
- int currentRow = 0;
try (Table metaTable = getMetaHTable(connection)) {
try (ResultScanner scanner = metaTable.getScanner(scan)) {
- Result data;
- while ((data = scanner.next()) != null) {
- if (data.isEmpty()) {
- continue;
- }
- // Break if visit returns false.
- if (!visitor.visit(data)) {
- break;
- }
- if (++currentRow >= rowUpperLimit) {
- break;
- }
- }
+ ClientMetaTableAccessor.visit(scanner, visitor, maxRows);
}
}
}
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/ClientMetaTableAccessor.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/ClientMetaTableAccessor.java
index ed0d9b4..f19c913 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/ClientMetaTableAccessor.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/ClientMetaTableAccessor.java
@@ -32,6 +32,7 @@ import org.apache.hadoop.hbase.client.Consistency;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.RegionInfo;
import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Scan.ReadType;
import org.apache.hadoop.hbase.client.TableState;
@@ -486,4 +487,26 @@ public final class ClientMetaTableAccessor {
}
return stopRow;
}
+
+ /**
+ * Visit all the result of the given {@code scanner}.
+ * <p/>
+ * It is the caller's duty to close the {@code scanner}.
+ * @param maxRows maximum rows to visit, or -1 means unlimited.
+ */
+ public static void visit(ResultScanner scanner, Visitor visitor, int maxRows) throws IOException {
+ for (int rows = 0;;) {
+ Result result = scanner.next();
+ if (result == null) {
+ return;
+ }
+ if (!visitor.visit(result)) {
+ return;
+ }
+ rows++;
+ if (maxRows > 0 && rows >= maxRows) {
+ return;
+ }
+ }
+ }
}
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionUtils.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionUtils.java
index 8f298e6..4be7546 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionUtils.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionUtils.java
@@ -38,7 +38,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.function.Supplier;
-import java.util.stream.Collectors;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellComparator;
@@ -53,7 +52,6 @@ import org.apache.hadoop.hbase.client.metrics.ScanMetrics;
import org.apache.hadoop.hbase.exceptions.ClientExceptionsUtil;
import org.apache.hadoop.hbase.ipc.HBaseRpcController;
import org.apache.hadoop.hbase.ipc.RpcClient;
-import org.apache.hadoop.hbase.ipc.RpcControllerFactory;
import org.apache.hadoop.hbase.ipc.ServerNotRunningYetException;
import org.apache.hadoop.hbase.ipc.ServerRpcController;
import org.apache.hadoop.hbase.security.User;
@@ -77,8 +75,6 @@ import org.apache.hadoop.hbase.shaded.protobuf.ResponseConverter;
import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos;
import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.ClientService;
import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.ScanResponse;
-import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ClientMetaService;
-import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetAllMetaRegionLocationsRequest;
/**
* Utility used by client connections.
@@ -649,8 +645,8 @@ public final class ConnectionUtils {
}
}
- public static void tryClearMasterStubCache(IOException error,
- ClientMetaService.Interface currentStub, AtomicReference<ClientMetaService.Interface> stub) {
+ public static <T> void tryClearMasterStubCache(IOException error,
+ T currentStub, AtomicReference<T> stub) {
if (ClientExceptionsUtil.isConnectionException(error) ||
error instanceof ServerNotRunningYetException) {
stub.compareAndSet(currentStub, null);
@@ -725,35 +721,4 @@ public final class ConnectionUtils {
}
}
}
-
- public static CompletableFuture<List<HRegionLocation>> getAllMetaRegionLocations(
- boolean excludeOfflinedSplitParents,
- CompletableFuture<ClientMetaService.Interface> getStubFuture,
- AtomicReference<ClientMetaService.Interface> stubRef,
- RpcControllerFactory rpcControllerFactory, int callTimeoutMs) {
- CompletableFuture<List<HRegionLocation>> future = new CompletableFuture<>();
- addListener(getStubFuture, (stub, error) -> {
- if (error != null) {
- future.completeExceptionally(error);
- return;
- }
- HBaseRpcController controller = rpcControllerFactory.newController();
- if (callTimeoutMs > 0) {
- controller.setCallTimeout(callTimeoutMs);
- }
- stub.getAllMetaRegionLocations(controller, GetAllMetaRegionLocationsRequest.newBuilder()
- .setExcludeOfflinedSplitParents(excludeOfflinedSplitParents).build(), resp -> {
- if (controller.failed()) {
- IOException ex = controller.getFailed();
- tryClearMasterStubCache(ex, stub, stubRef);
- future.completeExceptionally(ex);
- return;
- }
- List<HRegionLocation> locs = resp.getMetaLocationsList().stream()
- .map(ProtobufUtil::toRegionLocation).collect(Collectors.toList());
- future.complete(locs);
- });
- });
- return future;
- }
}
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/MasterRegistry.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/MasterRegistry.java
index d760cf0..d07e133 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/MasterRegistry.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/MasterRegistry.java
@@ -361,8 +361,12 @@ public class MasterRegistry implements ConnectionRegistry {
LocateMetaRegionRequest request =
LocateMetaRegionRequest.newBuilder().setRow(ByteString.copyFrom(row))
.setLocateType(ProtobufUtil.toProtoRegionLocateType(locateType)).build();
- return this.<LocateMetaRegionResponse> call((c, s, d) -> s.locateMetaRegion(c, request, d),
- r -> true, "locateMeta()").thenApply(this::transformRegionLocations);
+ return this
+ .<LocateMetaRegionResponse> call((c, s, d) -> s.locateMetaRegion(c, request, d),
+ r -> r.getMetaLocationsList().stream()
+ .anyMatch(l -> l.hasRegionInfo() && l.hasServerName()),
+ "locateMeta()")
+ .thenApply(this::transformRegionLocations);
}
private List<HRegionLocation>
@@ -378,7 +382,8 @@ public class MasterRegistry implements ConnectionRegistry {
.setExcludeOfflinedSplitParents(excludeOfflinedSplitParents).build();
return this
.<GetAllMetaRegionLocationsResponse> call(
- (c, s, d) -> s.getAllMetaRegionLocations(c, request, d), r -> true,
+ (c, s, d) -> s.getAllMetaRegionLocations(c, request, d),
+ r -> r.getMetaLocationsCount() > 0,
"getAllMetaRegionLocations(" + excludeOfflinedSplitParents + ")")
.thenApply(this::transformRegionLocationList);
}
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ZKConnectionRegistry.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ZKConnectionRegistry.java
index c5d6161..93da881 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ZKConnectionRegistry.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ZKConnectionRegistry.java
@@ -20,6 +20,7 @@ package org.apache.hadoop.hbase.client;
import static org.apache.hadoop.hbase.HConstants.DEFAULT_HBASE_RPC_TIMEOUT;
import static org.apache.hadoop.hbase.HConstants.HBASE_RPC_READ_TIMEOUT_KEY;
import static org.apache.hadoop.hbase.HConstants.HBASE_RPC_TIMEOUT_KEY;
+import static org.apache.hadoop.hbase.client.ConnectionUtils.tryClearMasterStubCache;
import static org.apache.hadoop.hbase.client.RegionInfo.DEFAULT_REPLICA_ID;
import static org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil.lengthOfPBMagic;
import static org.apache.hadoop.hbase.util.FutureUtils.addListener;
@@ -58,6 +59,7 @@ import org.apache.hbase.thirdparty.com.google.protobuf.ByteString;
import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos;
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ClientMetaService;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetAllMetaRegionLocationsRequest;
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.LocateMetaRegionRequest;
import org.apache.hadoop.hbase.shaded.protobuf.generated.ZooKeeperProtos;
@@ -298,8 +300,27 @@ class ZKConnectionRegistry implements ConnectionRegistry {
@Override
public CompletableFuture<List<HRegionLocation>>
getAllMetaRegionLocations(boolean excludeOfflinedSplitParents) {
- return ConnectionUtils.getAllMetaRegionLocations(excludeOfflinedSplitParents, getStub(),
- cachedStub, rpcControllerFactory, -1);
+ CompletableFuture<List<HRegionLocation>> future = new CompletableFuture<>();
+ addListener(getStub(), (stub, error) -> {
+ if (error != null) {
+ future.completeExceptionally(error);
+ return;
+ }
+ HBaseRpcController controller = rpcControllerFactory.newController();
+ stub.getAllMetaRegionLocations(controller, GetAllMetaRegionLocationsRequest.newBuilder()
+ .setExcludeOfflinedSplitParents(excludeOfflinedSplitParents).build(), resp -> {
+ if (controller.failed()) {
+ IOException ex = controller.getFailed();
+ tryClearMasterStubCache(ex, stub, cachedStub);
+ future.completeExceptionally(ex);
+ return;
+ }
+ List<HRegionLocation> locs = resp.getMetaLocationsList().stream()
+ .map(ProtobufUtil::toRegionLocation).collect(Collectors.toList());
+ future.complete(locs);
+ });
+ });
+ return future;
}
@Override
diff --git a/hbase-protocol-shaded/src/main/protobuf/server/master/Master.proto b/hbase-protocol-shaded/src/main/protobuf/server/master/Master.proto
index 01a8941..2bb35c2 100644
--- a/hbase-protocol-shaded/src/main/protobuf/server/master/Master.proto
+++ b/hbase-protocol-shaded/src/main/protobuf/server/master/Master.proto
@@ -1371,3 +1371,17 @@ service ClientMetaService {
rpc GetAllMetaRegionLocations(GetAllMetaRegionLocationsRequest)
returns(GetAllMetaRegionLocationsResponse);
}
+
+message SyncRootRequest {
+ required int64 lastSyncSeqId = 1;
+}
+
+message SyncRootResponse {
+ required int64 lastModifiedSeqId = 1;
+ repeated RegionLocation meta_locations = 2;
+}
+
+service RootSyncService {
+ rpc SyncRoot(SyncRootRequest)
+ returns(SyncRootResponse);
+}
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/client/AsyncClusterConnection.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/client/AsyncClusterConnection.java
index 8e64b4b..8b0f0a2 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/client/AsyncClusterConnection.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/client/AsyncClusterConnection.java
@@ -103,5 +103,6 @@ public interface AsyncClusterConnection extends AsyncConnection {
/**
* Fetch all meta region locations from active master, used by backup masters for caching.
*/
- CompletableFuture<List<HRegionLocation>> getAllMetaRegionLocations(int callTimeoutMs);
+ CompletableFuture<Pair<Long, List<HRegionLocation>>> syncRoot(long lastSyncSeqId,
+ int callTimeoutMs);
}
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/client/AsyncClusterConnectionImpl.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/client/AsyncClusterConnectionImpl.java
index cfe62db..8fdd439 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/client/AsyncClusterConnectionImpl.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/client/AsyncClusterConnectionImpl.java
@@ -17,17 +17,23 @@
*/
package org.apache.hadoop.hbase.client;
+import static org.apache.hadoop.hbase.client.ConnectionUtils.tryClearMasterStubCache;
+import static org.apache.hadoop.hbase.util.FutureUtils.addListener;
+
+import java.io.IOException;
import java.net.SocketAddress;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionLocation;
import org.apache.hadoop.hbase.RegionLocations;
import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.ipc.HBaseRpcController;
import org.apache.hadoop.hbase.ipc.RpcClient;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.util.Pair;
@@ -46,7 +52,8 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.PrepareBul
import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.PrepareBulkLoadResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.RegionSpecifier;
import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.RegionSpecifier.RegionSpecifierType;
-import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ClientMetaService;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.RootSyncService;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SyncRootRequest;
/**
* The implementation of AsyncClusterConnection.
@@ -54,11 +61,11 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ClientMeta
@InterfaceAudience.Private
class AsyncClusterConnectionImpl extends AsyncConnectionImpl implements AsyncClusterConnection {
- private final AtomicReference<ClientMetaService.Interface> cachedClientMetaStub =
+ private final AtomicReference<RootSyncService.Interface> cachedRootSyncStub =
new AtomicReference<>();
- private final AtomicReference<CompletableFuture<ClientMetaService.Interface>>
- clientMetaStubMakeFuture = new AtomicReference<>();
+ private final AtomicReference<CompletableFuture<RootSyncService.Interface>>
+ rootSyncStubMakeFuture = new AtomicReference<>();
public AsyncClusterConnectionImpl(Configuration conf, ConnectionRegistry registry,
String clusterId, SocketAddress localAddress, User user) {
@@ -143,15 +150,38 @@ class AsyncClusterConnectionImpl extends AsyncConnectionImpl implements AsyncClu
.call();
}
- private CompletableFuture<ClientMetaService.Interface> getClientMetaStub() {
- return ConnectionUtils.getMasterStub(registry, cachedClientMetaStub, clientMetaStubMakeFuture,
- rpcClient, user, rpcTimeout, TimeUnit.MILLISECONDS, ClientMetaService::newStub,
- "ClientMetaService");
+ private CompletableFuture<RootSyncService.Interface> getRootSyncStub() {
+ return ConnectionUtils.getMasterStub(registry, cachedRootSyncStub, rootSyncStubMakeFuture,
+ rpcClient, user, rpcTimeout, TimeUnit.MILLISECONDS, RootSyncService::newStub,
+ "RootSyncService");
}
@Override
- public CompletableFuture<List<HRegionLocation>> getAllMetaRegionLocations(int callTimeoutMs) {
- return ConnectionUtils.getAllMetaRegionLocations(false, getClientMetaStub(),
- cachedClientMetaStub, rpcControllerFactory, callTimeoutMs);
+ public CompletableFuture<Pair<Long, List<HRegionLocation>>> syncRoot(long lastSyncSeqId,
+ int callTimeoutMs) {
+ CompletableFuture<Pair<Long, List<HRegionLocation>>> future = new CompletableFuture<>();
+ addListener(getRootSyncStub(), (stub, error) -> {
+ if (error != null) {
+ future.completeExceptionally(error);
+ return;
+ }
+ HBaseRpcController controller = rpcControllerFactory.newController();
+ if (callTimeoutMs > 0) {
+ controller.setCallTimeout(callTimeoutMs);
+ }
+ stub.syncRoot(controller,
+ SyncRootRequest.newBuilder().setLastSyncSeqId(lastSyncSeqId).build(), resp -> {
+ if (controller.failed()) {
+ IOException ex = controller.getFailed();
+ tryClearMasterStubCache(ex, stub, cachedRootSyncStub);
+ future.completeExceptionally(ex);
+ return;
+ }
+ List<HRegionLocation> locs = resp.getMetaLocationsList().stream()
+ .map(ProtobufUtil::toRegionLocation).collect(Collectors.toList());
+ future.complete(Pair.newPair(resp.getLastModifiedSeqId(), locs));
+ });
+ });
+ return future;
}
}
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java
index 8ca8972..e6197ba 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java
@@ -1824,4 +1824,24 @@ public interface MasterObserver {
default void postGetAllMetaRegionLocations(ObserverContext<MasterCoprocessorEnvironment> ctx,
boolean excludeOfflinedSplitParents, List<HRegionLocation> locs) {
}
+
+ /**
+ * Called before syncing root
+ * @param ctx ctx the coprocessor instance's environment
+ * @param lastSyncSeqId the sequence id when we call sync root last time
+ */
+ default void preSyncRoot(ObserverContext<MasterCoprocessorEnvironment> ctx, long lastSyncSeqId) {
+ }
+
+ /**
+ * Called before syncing root
+ * @param ctx ctx the coprocessor instance's environment
+ * @param lastSyncSeqId the sequence id when we call sync root last time
+ * @param lastModifiedSeqId the sequence id for this sync operation, it could be less than or
+ * equal to {@code lastSyncSeqId}, then it usually means we do not sync anything.
+ * @param locs the locations of all meta regions, including meta replicas if any.
+ */
+ default void postSyncRoot(ObserverContext<MasterCoprocessorEnvironment> ctx, long lastSyncSeqId,
+ long lastModifiedSeqId, List<HRegionLocation> locs) {
+ }
}
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
index 18a1597..a82b6d6 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
@@ -97,6 +97,7 @@ import org.apache.hadoop.hbase.client.RegionLocateType;
import org.apache.hadoop.hbase.client.RegionReplicaUtil;
import org.apache.hadoop.hbase.client.RegionStatesCount;
import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.TableDescriptor;
import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
@@ -148,6 +149,7 @@ import org.apache.hadoop.hbase.master.procedure.ServerCrashProcedure;
import org.apache.hadoop.hbase.master.procedure.TruncateTableProcedure;
import org.apache.hadoop.hbase.master.region.MasterRegion;
import org.apache.hadoop.hbase.master.region.MasterRegionFactory;
+import org.apache.hadoop.hbase.master.region.RootStore;
import org.apache.hadoop.hbase.master.replication.AbstractPeerProcedure;
import org.apache.hadoop.hbase.master.replication.AddPeerProcedure;
import org.apache.hadoop.hbase.master.replication.DisablePeerProcedure;
@@ -460,7 +462,11 @@ public class HMaster extends HRegionServer implements MasterServices {
private ProcedureStore procedureStore;
// the master local storage to store procedure data, root table, etc.
- private MasterRegion masterRegion;
+ @VisibleForTesting
+ MasterRegion masterRegion;
+
+ // a wrapper of MasterRegion to provide root table storage
+ private RootStore rootStore;
// handle table states
private TableStateManager tableStateManager;
@@ -882,8 +888,8 @@ public class HMaster extends HRegionServer implements MasterServices {
// Will be overriden in test to inject customized AssignmentManager
@VisibleForTesting
protected AssignmentManager createAssignmentManager(MasterServices master,
- MasterRegion masterRegion) {
- return new AssignmentManager(master, masterRegion);
+ RootStore rootStore) {
+ return new AssignmentManager(master, rootStore);
}
/**
@@ -1046,6 +1052,7 @@ public class HMaster extends HRegionServer implements MasterServices {
// initialize master local region
masterRegion = MasterRegionFactory.create(this);
+ rootStore = new RootStore(masterRegion);
tryMigrateRootTableFromZooKeeper();
@@ -1059,7 +1066,7 @@ public class HMaster extends HRegionServer implements MasterServices {
.collect(Collectors.groupingBy(p -> p.getClass()));
// Create Assignment Manager
- this.assignmentManager = createAssignmentManager(this, masterRegion);
+ this.assignmentManager = createAssignmentManager(this, rootStore);
this.assignmentManager.start();
// TODO: TRSP can perform as the sub procedure for other procedures, so even if it is marked as
// completed, it could still be in the procedure list. This is a bit strange but is another
@@ -3965,16 +3972,12 @@ public class HMaster extends HRegionServer implements MasterServices {
}
Scan scan =
CatalogFamilyFormat.createRegionLocateScan(TableName.META_TABLE_NAME, row, locateType, 1);
- try (RegionScanner scanner = masterRegion.getScanner(scan)) {
- boolean moreRows;
- List<Cell> cells = new ArrayList<>();
- do {
- moreRows = scanner.next(cells);
- if (cells.isEmpty()) {
- continue;
+ try (ResultScanner scanner = rootStore.getScanner(scan)) {
+ for (;;) {
+ Result result = scanner.next();
+ if (result == null) {
+ break;
}
- Result result = Result.create(cells);
- cells.clear();
RegionLocations locs = CatalogFamilyFormat.getRegionLocations(result);
if (locs == null || locs.getDefaultRegionLocation() == null) {
LOG.warn("No location found when locating meta region with row='{}', locateType={}",
@@ -3992,7 +3995,7 @@ public class HMaster extends HRegionServer implements MasterServices {
continue;
}
return locs;
- } while (moreRows);
+ }
LOG.warn("No location available when locating meta region with row='{}', locateType={}",
Bytes.toStringBinary(row), locateType);
return null;
@@ -4001,39 +4004,10 @@ public class HMaster extends HRegionServer implements MasterServices {
public List<RegionLocations> getAllMetaRegionLocations(boolean excludeOfflinedSplitParents)
throws IOException {
- Scan scan = new Scan().addFamily(HConstants.CATALOG_FAMILY);
- List<RegionLocations> list = new ArrayList<>();
- try (RegionScanner scanner = masterRegion.getScanner(scan)) {
- boolean moreRows;
- List<Cell> cells = new ArrayList<>();
- do {
- moreRows = scanner.next(cells);
- if (cells.isEmpty()) {
- continue;
- }
- Result result = Result.create(cells);
- cells.clear();
- RegionLocations locs = CatalogFamilyFormat.getRegionLocations(result);
- if (locs == null) {
- LOG.warn("No locations in {}", result);
- continue;
- }
- HRegionLocation loc = locs.getRegionLocation();
- if (loc == null) {
- LOG.warn("No non null location in {}", result);
- continue;
- }
- RegionInfo info = loc.getRegion();
- if (info == null) {
- LOG.warn("No serialized RegionInfo in {}", result);
- continue;
- }
- if (excludeOfflinedSplitParents && info.isSplitParent()) {
- continue;
- }
- list.add(locs);
- } while (moreRows);
- }
- return list;
+ return rootStore.getAllMetaRegionLocations(excludeOfflinedSplitParents);
+ }
+
+ public Pair<Long, List<RegionLocations>> syncRoot(long lastSyncSeqId) throws IOException {
+ return rootStore.sync(lastSyncSeqId);
}
}
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java
index 728da5c..3289c9d 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java
@@ -2078,4 +2078,23 @@ public class MasterCoprocessorHost
}
});
}
+
+ public void preSyncRoot(long lastSyncSeqId) throws IOException {
+ execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
+ @Override
+ public void call(MasterObserver observer) throws IOException {
+ observer.preSyncRoot(this, lastSyncSeqId);
+ }
+ });
+ }
+
+ public void postSyncRoot(long lastSyncSeqId, long lastModifiedSeqId, List<HRegionLocation> locs)
+ throws IOException {
+ execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
+ @Override
+ public void call(MasterObserver observer) throws IOException {
+ observer.postSyncRoot(this, lastSyncSeqId, lastModifiedSeqId, locs);
+ }
+ });
+ }
}
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java
index 1b93e86..99f928c 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java
@@ -293,6 +293,7 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.Recommissi
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.RegionSpecifierAndState;
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.RestoreSnapshotRequest;
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.RestoreSnapshotResponse;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.RootSyncService;
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.RunCatalogScanRequest;
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.RunCatalogScanResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.RunCleanerChoreRequest;
@@ -328,6 +329,8 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SwitchExce
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SwitchExceedThrottleQuotaResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SwitchRpcThrottleRequest;
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SwitchRpcThrottleResponse;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SyncRootRequest;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SyncRootResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.TruncateTableRequest;
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.TruncateTableResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.UnassignRegionRequest;
@@ -410,9 +413,10 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.VisibilityLabelsProtos.
*/
@InterfaceAudience.Private
@SuppressWarnings("deprecation")
-public class MasterRpcServices extends RSRpcServices implements MasterService.BlockingInterface,
- RegionServerStatusService.BlockingInterface, LockService.BlockingInterface,
- HbckService.BlockingInterface, ClientMetaService.BlockingInterface {
+public class MasterRpcServices extends RSRpcServices
+ implements MasterService.BlockingInterface, RegionServerStatusService.BlockingInterface,
+ LockService.BlockingInterface, HbckService.BlockingInterface, ClientMetaService.BlockingInterface,
+ RootSyncService.BlockingInterface {
private static final Logger LOG = LoggerFactory.getLogger(MasterRpcServices.class.getName());
private static final Logger AUDITLOG =
@@ -546,7 +550,7 @@ public class MasterRpcServices extends RSRpcServices implements MasterService.Bl
*/
@Override
protected List<BlockingServiceAndInterface> getServices() {
- List<BlockingServiceAndInterface> bssi = new ArrayList<>(5);
+ List<BlockingServiceAndInterface> bssi = new ArrayList<>();
bssi.add(new BlockingServiceAndInterface(MasterService.newReflectiveBlockingService(this),
MasterService.BlockingInterface.class));
bssi.add(
@@ -558,6 +562,8 @@ public class MasterRpcServices extends RSRpcServices implements MasterService.Bl
HbckService.BlockingInterface.class));
bssi.add(new BlockingServiceAndInterface(ClientMetaService.newReflectiveBlockingService(this),
ClientMetaService.BlockingInterface.class));
+ bssi.add(new BlockingServiceAndInterface(RootSyncService.newReflectiveBlockingService(this),
+ RootSyncService.BlockingInterface.class));
bssi.addAll(super.getServices());
return bssi;
}
@@ -3423,6 +3429,18 @@ public class MasterRpcServices extends RSRpcServices implements MasterService.Bl
}
}
+ private static List<HRegionLocation> locs2Loc(List<RegionLocations> locs) {
+ List<HRegionLocation> list = new ArrayList<>();
+ for (RegionLocations ls : locs) {
+ for (HRegionLocation loc : ls) {
+ if (loc != null) {
+ list.add(loc);
+ }
+ }
+ }
+ return list;
+ }
+
@Override
public GetAllMetaRegionLocationsResponse getAllMetaRegionLocations(RpcController controller,
GetAllMetaRegionLocationsRequest request) throws ServiceException {
@@ -3437,16 +3455,7 @@ public class MasterRpcServices extends RSRpcServices implements MasterService.Bl
list = cache.getAllMetaRegionLocations(excludeOfflinedSplitParents);
} else {
List<RegionLocations> locs = master.getAllMetaRegionLocations(excludeOfflinedSplitParents);
- list = new ArrayList<>();
- if (locs != null) {
- for (RegionLocations ls : locs) {
- for (HRegionLocation loc : ls) {
- if (loc != null) {
- list.add(loc);
- }
- }
- }
- }
+ list = locs2Loc(locs);
}
GetAllMetaRegionLocationsResponse.Builder builder =
GetAllMetaRegionLocationsResponse.newBuilder();
@@ -3462,4 +3471,29 @@ public class MasterRpcServices extends RSRpcServices implements MasterService.Bl
throw new ServiceException(e);
}
}
+
+ @Override
+ public SyncRootResponse syncRoot(RpcController controller, SyncRootRequest request)
+ throws ServiceException {
+ long lastSyncSeqId = request.getLastSyncSeqId();
+ try {
+ master.checkServiceStarted();
+ if (master.getMasterCoprocessorHost() != null) {
+ master.getMasterCoprocessorHost().preSyncRoot(lastSyncSeqId);
+ }
+ Pair<Long, List<RegionLocations>> pair = master.syncRoot(lastSyncSeqId);
+ List<HRegionLocation> locs = locs2Loc(pair.getSecond());
+ SyncRootResponse.Builder builder = SyncRootResponse.newBuilder();
+ builder.setLastModifiedSeqId(pair.getFirst());
+ for (HRegionLocation loc : locs) {
+ builder.addMetaLocations(ProtobufUtil.toRegionLocation(loc));
+ }
+ if (master.getMasterCoprocessorHost() != null) {
+ master.getMasterCoprocessorHost().postSyncRoot(lastSyncSeqId, pair.getFirst(), locs);
+ }
+ return builder.build();
+ } catch (IOException e) {
+ throw new ServiceException(e);
+ }
+ }
}
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MetaLocationCache.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MetaLocationCache.java
index 0f5cf11..cc234f6 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MetaLocationCache.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MetaLocationCache.java
@@ -30,7 +30,9 @@ import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
+import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionLocation;
import org.apache.hadoop.hbase.MetaCellComparator;
import org.apache.hadoop.hbase.RegionLocations;
@@ -50,7 +52,7 @@ import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesti
* A cache of meta region locations.
*/
@InterfaceAudience.Private
-class MetaLocationCache implements Stoppable {
+public class MetaLocationCache implements Stoppable {
private static final Logger LOG = LoggerFactory.getLogger(MetaLocationCache.class);
@@ -68,13 +70,17 @@ class MetaLocationCache implements Stoppable {
// default timeout 1 second
private static final int DEFAULT_FETCH_TIMEOUT_MS = 1000;
- private static final class CacheHolder {
+ @VisibleForTesting
+ static final class CacheHolder {
+
+ final long lastSyncSeqId;
final NavigableMap<byte[], RegionLocations> cache;
final List<HRegionLocation> all;
- CacheHolder(List<HRegionLocation> all) {
+ CacheHolder(long lastSyncSeqId, List<HRegionLocation> all) {
+ this.lastSyncSeqId = lastSyncSeqId;
this.all = Collections.unmodifiableList(all);
NavigableMap<byte[], SortedSet<HRegionLocation>> startKeyToLocs =
new TreeMap<>(MetaCellComparator.ROW_COMPARATOR);
@@ -93,7 +99,10 @@ class MetaLocationCache implements Stoppable {
}
}
- private volatile CacheHolder holder;
+ @VisibleForTesting
+ final AtomicReference<CacheHolder> holder = new AtomicReference<>();
+
+ private final ScheduledChore refreshChore;
private volatile boolean stopped = false;
@@ -102,34 +111,43 @@ class MetaLocationCache implements Stoppable {
master.getConfiguration().getInt(SYNC_INTERVAL_SECONDS, DEFAULT_SYNC_INTERVAL_SECONDS);
int fetchTimeoutMs =
master.getConfiguration().getInt(FETCH_TIMEOUT_MS, DEFAULT_FETCH_TIMEOUT_MS);
- master.getChoreService().scheduleChore(new ScheduledChore(
- getClass().getSimpleName() + "-Sync-Chore", this, syncIntervalSeconds, 0, TimeUnit.SECONDS) {
+ refreshChore = new ScheduledChore(getClass().getSimpleName() + "-Sync-Chore", this,
+ syncIntervalSeconds, 0, TimeUnit.SECONDS) {
@Override
protected void chore() {
AsyncClusterConnection conn = master.getAsyncClusterConnection();
if (conn != null) {
- addListener(conn.getAllMetaRegionLocations(fetchTimeoutMs), (locs, error) -> {
+ final CacheHolder ch = holder.get();
+ long lastSyncSeqId = ch != null ? ch.lastSyncSeqId : HConstants.NO_SEQNUM;
+ addListener(conn.syncRoot(lastSyncSeqId, fetchTimeoutMs), (resp, error) -> {
if (error != null) {
- LOG.warn("Failed to fetch all meta region locations from active master", error);
+ LOG.warn("Failed to sync root data from active master", error);
return;
}
- holder = new CacheHolder(locs);
+ long lastModifiedSeqId = resp.getFirst().longValue();
+ if (ch == null || lastModifiedSeqId > ch.lastSyncSeqId && holder.get() == ch) {
+ // since we may trigger cache refresh when locating, here we use CAS to avoid race
+ holder.compareAndSet(ch, new CacheHolder(lastModifiedSeqId, resp.getSecond()));
+ }
});
}
}
- });
+ };
+ master.getChoreService().scheduleChore(refreshChore);
}
- RegionLocations locateMeta(byte[] row, RegionLocateType locateType) {
+ @VisibleForTesting
+ public RegionLocations locateMeta(byte[] row, RegionLocateType locateType) {
if (locateType == RegionLocateType.AFTER) {
// as we know the exact row after us, so we can just create the new row, and use the same
// algorithm to locate it.
row = Arrays.copyOf(row, row.length + 1);
locateType = RegionLocateType.CURRENT;
}
- CacheHolder holder = this.holder;
+ CacheHolder holder = this.holder.get();
if (holder == null) {
+ refreshChore.triggerNow();
return null;
}
return locateType.equals(RegionLocateType.BEFORE) ?
@@ -138,8 +156,9 @@ class MetaLocationCache implements Stoppable {
}
List<HRegionLocation> getAllMetaRegionLocations(boolean excludeOfflinedSplitParents) {
- CacheHolder holder = this.holder;
+ CacheHolder holder = this.holder.get();
if (holder == null) {
+ refreshChore.triggerNow();
return Collections.emptyList();
}
if (!excludeOfflinedSplitParents) {
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/AssignmentManager.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/AssignmentManager.java
index 15712e6..92e1b52 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/AssignmentManager.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/AssignmentManager.java
@@ -34,7 +34,6 @@ import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.CatalogFamilyFormat;
-import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.DoNotRetryIOException;
import org.apache.hadoop.hbase.HBaseIOException;
import org.apache.hadoop.hbase.HConstants;
@@ -47,6 +46,7 @@ import org.apache.hadoop.hbase.client.MasterSwitchType;
import org.apache.hadoop.hbase.client.RegionInfo;
import org.apache.hadoop.hbase.client.RegionStatesCount;
import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.TableDescriptor;
import org.apache.hadoop.hbase.client.TableState;
@@ -67,13 +67,12 @@ import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;
import org.apache.hadoop.hbase.master.procedure.MasterProcedureScheduler;
import org.apache.hadoop.hbase.master.procedure.ProcedureSyncWait;
import org.apache.hadoop.hbase.master.procedure.ServerCrashProcedure;
-import org.apache.hadoop.hbase.master.region.MasterRegion;
+import org.apache.hadoop.hbase.master.region.RootStore;
import org.apache.hadoop.hbase.procedure2.Procedure;
import org.apache.hadoop.hbase.procedure2.ProcedureEvent;
import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
import org.apache.hadoop.hbase.procedure2.ProcedureInMemoryChore;
import org.apache.hadoop.hbase.procedure2.util.StringUtils;
-import org.apache.hadoop.hbase.regionserver.RegionScanner;
import org.apache.hadoop.hbase.regionserver.SequenceId;
import org.apache.hadoop.hbase.rsgroup.RSGroupBasedLoadBalancer;
import org.apache.hadoop.hbase.util.Bytes;
@@ -172,22 +171,22 @@ public class AssignmentManager {
private final int assignMaxAttempts;
private final int assignRetryImmediatelyMaxAttempts;
- private final MasterRegion masterRegion;
+ private final RootStore rootStore;
private final Object checkIfShouldMoveSystemRegionLock = new Object();
private Thread assignThread;
- public AssignmentManager(MasterServices master, MasterRegion masterRegion) {
- this(master, masterRegion, new RegionStateStore(master, masterRegion));
+ public AssignmentManager(MasterServices master, RootStore rootStore) {
+ this(master, rootStore, new RegionStateStore(master, rootStore));
}
@VisibleForTesting
- AssignmentManager(MasterServices master, MasterRegion masterRegion, RegionStateStore stateStore) {
+ AssignmentManager(MasterServices master, RootStore rootStore, RegionStateStore stateStore) {
this.master = master;
this.regionStateStore = stateStore;
this.metrics = new MetricsAssignmentManager();
- this.masterRegion = masterRegion;
+ this.rootStore = rootStore;
final Configuration conf = master.getConfiguration();
@@ -228,17 +227,13 @@ public class AssignmentManager {
// Start the Assignment Thread
startAssignmentThread();
// load meta region states.
- try (RegionScanner scanner =
- masterRegion.getScanner(new Scan().addFamily(HConstants.CATALOG_FAMILY))) {
- List<Cell> cells = new ArrayList<>();
- boolean moreRows;
- do {
- moreRows = scanner.next(cells);
- if (cells.isEmpty()) {
- continue;
+ try (ResultScanner scanner =
+ rootStore.getScanner(new Scan().addFamily(HConstants.CATALOG_FAMILY))) {
+ for(;;) {
+ Result result = scanner.next();
+ if (result == null) {
+ break;
}
- Result result = Result.create(cells);
- cells.clear();
RegionStateStore
.visitMetaEntry((r, regionInfo, state, regionLocation, lastHost, openSeqNum) -> {
RegionStateNode regionNode = regionStates.getOrCreateRegionStateNode(regionInfo);
@@ -263,7 +258,7 @@ public class AssignmentManager {
}
LOG.debug("Loaded hbase:meta {}", regionNode);
}, result);
- } while (moreRows);
+ }
}
}
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/RegionStateStore.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/RegionStateStore.java
index 3a693c5..a57b63b 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/RegionStateStore.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/RegionStateStore.java
@@ -56,16 +56,17 @@ import org.apache.hadoop.hbase.master.MasterFileSystem;
import org.apache.hadoop.hbase.master.MasterServices;
import org.apache.hadoop.hbase.master.RegionState;
import org.apache.hadoop.hbase.master.RegionState.State;
-import org.apache.hadoop.hbase.master.region.MasterRegion;
+import org.apache.hadoop.hbase.master.region.RootStore;
import org.apache.hadoop.hbase.procedure2.Procedure;
import org.apache.hadoop.hbase.procedure2.util.StringUtils;
-import org.apache.hadoop.hbase.regionserver.RegionScanner;
import org.apache.hadoop.hbase.replication.ReplicationBarrierFamilyFormat;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
import org.apache.hadoop.hbase.util.FutureUtils;
import org.apache.hadoop.hbase.wal.WALSplitUtil;
import org.apache.hadoop.hbase.zookeeper.MetaTableLocator;
+import org.apache.hadoop.hbase.zookeeper.ZKUtil;
+import org.apache.hadoop.hbase.zookeeper.ZKWatcher;
import org.apache.yetus.audience.InterfaceAudience;
import org.apache.zookeeper.KeeperException;
import org.slf4j.Logger;
@@ -93,11 +94,11 @@ public class RegionStateStore {
private final MasterServices master;
- private final MasterRegion masterRegion;
+ private final RootStore rootStore;
- public RegionStateStore(MasterServices master, MasterRegion masterRegion) {
+ public RegionStateStore(MasterServices master, RootStore rootStore) {
this.master = master;
- this.masterRegion = masterRegion;
+ this.rootStore = rootStore;
}
@FunctionalInterface
@@ -231,21 +232,9 @@ public class RegionStateStore {
// scan meta first
MetaTableAccessor.fullScanRegions(master.getConnection(), visitor);
// scan root
- try (RegionScanner scanner =
- masterRegion.getScanner(new Scan().addFamily(HConstants.CATALOG_FAMILY))) {
- boolean moreRows;
- List<Cell> cells = new ArrayList<>();
- do {
- moreRows = scanner.next(cells);
- if (cells.isEmpty()) {
- continue;
- }
- Result result = Result.create(cells);
- cells.clear();
- if (!visitor.visit(result)) {
- break;
- }
- } while (moreRows);
+ try (ResultScanner scanner =
+ rootStore.getScanner(new Scan().addFamily(HConstants.CATALOG_FAMILY))) {
+ ClientMetaTableAccessor.visit(scanner, visitor, -1);
}
}
@@ -263,7 +252,7 @@ public class RegionStateStore {
throws IOException {
try {
if (regionInfo.isMetaRegion()) {
- masterRegion.update(r -> r.put(put));
+ rootStore.put(put);
} else {
try (Table table = master.getConnection().getTable(TableName.META_TABLE_NAME)) {
table.put(put);
@@ -294,11 +283,7 @@ public class RegionStateStore {
private void multiMutate(RegionInfo ri, List<Mutation> mutations) throws IOException {
debugLogMutations(mutations);
if (ri.isMetaRegion()) {
- masterRegion.update(region -> {
- List<byte[]> rowsToLock =
- mutations.stream().map(Mutation::getRow).collect(Collectors.toList());
- region.mutateRowsWithLocks(mutations, rowsToLock, HConstants.NO_NONCE, HConstants.NO_NONCE);
- });
+ rootStore.multiMutate(mutations);
} else {
byte[] row =
Bytes.toBytes(RegionReplicaUtil.getRegionInfoForDefaultReplica(ri).getRegionNameAsString() +
@@ -335,7 +320,7 @@ public class RegionStateStore {
Get get =
new Get(CatalogFamilyFormat.getMetaKeyForRegion(region)).addFamily(HConstants.CATALOG_FAMILY);
if (region.isMetaRegion()) {
- return masterRegion.get(get);
+ return rootStore.get(get);
} else {
try (Table table = getMetaTable()) {
return table.get(get);
@@ -497,7 +482,7 @@ public class RegionStateStore {
}
debugLogMutation(delete);
if (mergeRegion.isMetaRegion()) {
- masterRegion.update(r -> r.delete(delete));
+ rootStore.delete(delete);
} else {
try (Table table = getMetaTable()) {
table.delete(delete);
@@ -568,9 +553,7 @@ public class RegionStateStore {
if (!metaRegions.isEmpty()) {
List<Delete> deletes = makeDeleteRegionInfos(metaRegions, ts);
debugLogMutations(deletes);
- for (Delete d : deletes) {
- masterRegion.update(r -> r.delete(d));
- }
+ rootStore.delete(deletes);
LOG.info("Deleted {} regions from ROOT", metaRegions.size());
LOG.debug("Deleted regions: {}", metaRegions);
}
@@ -613,64 +596,57 @@ public class RegionStateStore {
.addColumn(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER);
}
- private Delete deleteRegionReplicas(Result result, int oldReplicaCount, int newReplicaCount,
- long now) {
- RegionInfo primaryRegionInfo = CatalogFamilyFormat.getRegionInfo(result);
- if (primaryRegionInfo == null || primaryRegionInfo.isSplitParent()) {
- return null;
- }
- Delete delete = new Delete(result.getRow());
- for (int i = newReplicaCount; i < oldReplicaCount; i++) {
- delete.addColumns(HConstants.CATALOG_FAMILY, CatalogFamilyFormat.getServerColumn(i), now);
- delete.addColumns(HConstants.CATALOG_FAMILY, CatalogFamilyFormat.getSeqNumColumn(i), now);
- delete.addColumns(HConstants.CATALOG_FAMILY, CatalogFamilyFormat.getStartCodeColumn(i), now);
- delete.addColumns(HConstants.CATALOG_FAMILY, CatalogFamilyFormat.getServerNameColumn(i), now);
- delete.addColumns(HConstants.CATALOG_FAMILY, CatalogFamilyFormat.getRegionStateColumn(i),
- now);
+ private List<Delete> deleteRegionReplicas(ResultScanner scanner, int oldReplicaCount,
+ int newReplicaCount, long now) throws IOException {
+ List<Delete> deletes = new ArrayList<>();
+ for (;;) {
+ Result result = scanner.next();
+ if (result == null) {
+ break;
+ }
+ RegionInfo primaryRegionInfo = CatalogFamilyFormat.getRegionInfo(result);
+ if (primaryRegionInfo == null || primaryRegionInfo.isSplitParent()) {
+ continue;
+ }
+ Delete delete = new Delete(result.getRow());
+ for (int i = newReplicaCount; i < oldReplicaCount; i++) {
+ delete.addColumns(HConstants.CATALOG_FAMILY, CatalogFamilyFormat.getServerColumn(i), now);
+ delete.addColumns(HConstants.CATALOG_FAMILY, CatalogFamilyFormat.getSeqNumColumn(i), now);
+ delete.addColumns(HConstants.CATALOG_FAMILY, CatalogFamilyFormat.getStartCodeColumn(i),
+ now);
+ delete.addColumns(HConstants.CATALOG_FAMILY, CatalogFamilyFormat.getServerNameColumn(i),
+ now);
+ delete.addColumns(HConstants.CATALOG_FAMILY, CatalogFamilyFormat.getRegionStateColumn(i),
+ now);
+ }
+ deletes.add(delete);
}
- return delete;
+ return deletes;
}
public void removeRegionReplicas(TableName tableName, int oldReplicaCount, int newReplicaCount)
throws IOException {
Scan scan = getScanForUpdateRegionReplicas(tableName);
- List<Delete> deletes = new ArrayList<>();
long now = EnvironmentEdgeManager.currentTime();
if (TableName.isMetaTableName(tableName)) {
- try (RegionScanner scanner = masterRegion.getScanner(scan)) {
- List<Cell> cells = new ArrayList<>();
- boolean moreRows;
- do {
- cells.clear();
- moreRows = scanner.next(cells);
- if (cells.isEmpty()) {
- continue;
- }
- Result result = Result.create(cells);
- Delete delete = deleteRegionReplicas(result, oldReplicaCount, newReplicaCount, now);
- if (delete != null) {
- deletes.add(delete);
- }
- } while (moreRows);
+ List<Delete> deletes;
+ try (ResultScanner scanner = rootStore.getScanner(scan)) {
+ deletes = deleteRegionReplicas(scanner, oldReplicaCount, newReplicaCount, now);
}
debugLogMutations(deletes);
- masterRegion.update(r -> {
- for (Delete d : deletes) {
- r.delete(d);
+ rootStore.delete(deletes);
+ // also delete the mirrored location on zk
+ ZKWatcher zk = master.getZooKeeper();
+ try {
+ for (int i = newReplicaCount; i < oldReplicaCount; i++) {
+ ZKUtil.deleteNode(zk, zk.getZNodePaths().getZNodeForReplica(i));
}
- });
+ } catch (KeeperException e) {
+ throw new IOException(e);
+ }
} else {
try (Table metaTable = getMetaTable(); ResultScanner scanner = metaTable.getScanner(scan)) {
- for (;;) {
- Result result = scanner.next();
- if (result == null) {
- break;
- }
- Delete delete = deleteRegionReplicas(result, oldReplicaCount, newReplicaCount, now);
- if (delete != null) {
- deletes.add(delete);
- }
- }
+ List<Delete> deletes = deleteRegionReplicas(scanner, oldReplicaCount, newReplicaCount, now);
debugLogMutations(deletes);
metaTable.delete(deletes);
}
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/region/MasterRegion.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/region/MasterRegion.java
index 5b948b5..3e015f8 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/region/MasterRegion.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/region/MasterRegion.java
@@ -142,6 +142,15 @@ public final class MasterRegion {
return region.getScanner(scan);
}
+ WAL getWAL() {
+ return region.getWAL();
+ }
+
+ @VisibleForTesting
+ public long getReadPoint() {
+ return region.getMVCC().getReadPoint();
+ }
+
@VisibleForTesting
public FlushResult flush(boolean force) throws IOException {
return region.flush(force);
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/region/RegionScannerAsResultScanner.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/region/RegionScannerAsResultScanner.java
new file mode 100644
index 0000000..f7ac315
--- /dev/null
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/region/RegionScannerAsResultScanner.java
@@ -0,0 +1,88 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.master.region;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.hadoop.hbase.Cell;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.ResultScanner;
+import org.apache.hadoop.hbase.client.metrics.ScanMetrics;
+import org.apache.hadoop.hbase.regionserver.RegionScanner;
+import org.apache.yetus.audience.InterfaceAudience;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Wrap a {@link RegionScanner} as a {@link ResultScanner}.
+ */
+@InterfaceAudience.Private
+class RegionScannerAsResultScanner implements ResultScanner {
+
+ private static final Logger LOG = LoggerFactory.getLogger(RootStore.class);
+
+ private final RegionScanner scanner;
+
+ private boolean moreRows = true;
+
+ private final List<Cell> cells = new ArrayList<>();
+
+ public RegionScannerAsResultScanner(RegionScanner scanner) {
+ this.scanner = scanner;
+ }
+
+ @Override
+ public boolean renewLease() {
+ return true;
+ }
+
+ @Override
+ public Result next() throws IOException {
+ if (!moreRows) {
+ return null;
+ }
+ for (;;) {
+ moreRows = scanner.next(cells);
+ if (cells.isEmpty()) {
+ if (!moreRows) {
+ return null;
+ } else {
+ continue;
+ }
+ }
+ Result result = Result.create(cells);
+ cells.clear();
+ return result;
+ }
+ }
+
+ @Override
+ public ScanMetrics getScanMetrics() {
+ return null;
+ }
+
+ @Override
+ public void close() {
+ try {
+ scanner.close();
+ } catch (IOException e) {
+ LOG.warn("Failed to close scanner", e);
+ }
+ }
+}
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/region/RootStore.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/region/RootStore.java
new file mode 100644
index 0000000..0607f9e
--- /dev/null
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/region/RootStore.java
@@ -0,0 +1,153 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.master.region;
+
+import static org.apache.hadoop.hbase.HConstants.NO_NONCE;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.stream.Collectors;
+import org.apache.hadoop.hbase.CatalogFamilyFormat;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.HRegionLocation;
+import org.apache.hadoop.hbase.RegionLocations;
+import org.apache.hadoop.hbase.client.Delete;
+import org.apache.hadoop.hbase.client.Get;
+import org.apache.hadoop.hbase.client.Mutation;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.client.RegionInfo;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.ResultScanner;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.regionserver.wal.WALActionsListener;
+import org.apache.hadoop.hbase.util.AtomicUtils;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.Pair;
+import org.apache.hadoop.hbase.wal.WALEdit;
+import org.apache.hadoop.hbase.wal.WALKey;
+import org.apache.yetus.audience.InterfaceAudience;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A wrapper of {@link MasterRegion} to support root table storage.
+ */
+@InterfaceAudience.Private
+public class RootStore {
+
+ private static final Logger LOG = LoggerFactory.getLogger(RootStore.class);
+
+ private final MasterRegion region;
+
+ private final AtomicLong lastModifiedSeqId = new AtomicLong(HConstants.NO_SEQNUM);
+
+ public RootStore(MasterRegion region) {
+ this.region = region;
+ lastModifiedSeqId.set(region.getReadPoint());
+ region.getWAL().registerWALActionsListener(new WALActionsListener() {
+
+ @Override
+ public void postAppend(long entryLen, long elapsedTimeMillis, WALKey logKey, WALEdit logEdit)
+ throws IOException {
+ for (byte[] family : logEdit.getFamilies()) {
+ // we only care about catalog family
+ if (!Bytes.equals(family, HConstants.CATALOG_FAMILY)) {
+ return;
+ }
+ }
+ AtomicUtils.updateMax(lastModifiedSeqId, logKey.getSequenceId());
+ }
+ });
+ }
+
+ public ResultScanner getScanner(Scan scan) throws IOException {
+ return new RegionScannerAsResultScanner(region.getScanner(scan));
+ }
+
+ public Result get(Get get) throws IOException {
+ return region.get(get);
+ }
+
+ public void put(Put put) throws IOException {
+ region.update(r -> r.put(put));
+ }
+
+ public void delete(Delete delete) throws IOException {
+ region.update(r -> r.delete(delete));
+ }
+
+ public void delete(List<Delete> deletes) throws IOException {
+ region.update(r -> {
+ for (Delete delete : deletes) {
+ r.delete(delete);
+ }
+ });
+ }
+
+ public void multiMutate(List<Mutation> mutations) throws IOException {
+ region.update(r -> {
+ List<byte[]> rowsToLock =
+ mutations.stream().map(Mutation::getRow).collect(Collectors.toList());
+ r.mutateRowsWithLocks(mutations, rowsToLock, NO_NONCE, NO_NONCE);
+ });
+ }
+
+ public List<RegionLocations> getAllMetaRegionLocations(boolean excludeOfflinedSplitParents)
+ throws IOException {
+ List<RegionLocations> list = new ArrayList<>();
+ try (ResultScanner scanner = getScanner(new Scan().addFamily(HConstants.CATALOG_FAMILY))) {
+ for (;;) {
+ Result result = scanner.next();
+ if (result == null) {
+ break;
+ }
+ RegionLocations locs = CatalogFamilyFormat.getRegionLocations(result);
+ if (locs == null) {
+ LOG.warn("No locations in {}", result);
+ continue;
+ }
+ HRegionLocation loc = locs.getRegionLocation();
+ if (loc == null) {
+ LOG.warn("No non null location in {}", result);
+ continue;
+ }
+ RegionInfo info = loc.getRegion();
+ if (info == null) {
+ LOG.warn("No serialized RegionInfo in {}", result);
+ continue;
+ }
+ if (excludeOfflinedSplitParents && info.isSplitParent()) {
+ continue;
+ }
+ list.add(locs);
+ }
+ }
+ return list;
+ }
+
+ public Pair<Long, List<RegionLocations>> sync(long lastSyncSeqId) throws IOException {
+ long lastModSeqId = Math.min(lastModifiedSeqId.get(), region.getReadPoint());
+ if (lastModSeqId <= lastSyncSeqId) {
+ return Pair.newPair(lastSyncSeqId, Collections.emptyList());
+ }
+ return Pair.newPair(lastModSeqId, getAllMetaRegionLocations(false));
+ }
+}
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java
index a8c06c0..7c5e782 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java
@@ -1518,7 +1518,6 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
}
}
- @VisibleForTesting
public MultiVersionConcurrencyControl getMVCC() {
return mvcc;
}
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/DummyAsyncClusterConnection.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/DummyAsyncClusterConnection.java
index 4385a5a..93e8aa5 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/DummyAsyncClusterConnection.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/DummyAsyncClusterConnection.java
@@ -155,12 +155,13 @@ public class DummyAsyncClusterConnection implements AsyncClusterConnection {
}
@Override
- public Connection toConnection() {
+ public CompletableFuture<Pair<Long, List<HRegionLocation>>> syncRoot(long lastSyncSeqId,
+ int callTimeoutMs) {
return null;
}
@Override
- public CompletableFuture<List<HRegionLocation>> getAllMetaRegionLocations(int callTimeoutMs) {
+ public Connection toConnection() {
return null;
}
}
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncAdminBase.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncAdminBase.java
index 70cffd8..e895f16 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncAdminBase.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncAdminBase.java
@@ -26,7 +26,6 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ForkJoinPool;
import java.util.function.Supplier;
import java.util.regex.Pattern;
-import org.apache.commons.io.IOUtils;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.StartMiniClusterOption;
@@ -43,6 +42,8 @@ import org.junit.runners.Parameterized.Parameters;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
+
/**
* Class to test AsyncAdmin.
*/
@@ -92,7 +93,7 @@ public abstract class TestAsyncAdminBase extends AbstractTestUpdateConfiguration
@AfterClass
public static void tearDownAfterClass() throws Exception {
- IOUtils.closeQuietly(ASYNC_CONN);
+ Closeables.close(ASYNC_CONN, true);
TEST_UTIL.shutdownMiniCluster();
}
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFailedMetaReplicaAssigment.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFailedMetaReplicaAssigment.java
index a374fea..e8031c7 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFailedMetaReplicaAssigment.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFailedMetaReplicaAssigment.java
@@ -37,7 +37,7 @@ import org.apache.hadoop.hbase.master.assignment.AssignmentManager;
import org.apache.hadoop.hbase.master.assignment.RegionStateNode;
import org.apache.hadoop.hbase.master.assignment.TransitRegionStateProcedure;
import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;
-import org.apache.hadoop.hbase.master.region.MasterRegion;
+import org.apache.hadoop.hbase.master.region.RootStore;
import org.apache.hadoop.hbase.procedure2.Procedure;
import org.apache.hadoop.hbase.procedure2.ProcedureSuspendedException;
import org.apache.hadoop.hbase.procedure2.ProcedureYieldException;
@@ -130,8 +130,8 @@ public class TestFailedMetaReplicaAssigment {
@Override
public AssignmentManager createAssignmentManager(MasterServices master,
- MasterRegion masterRegion) {
- return new BrokenMasterMetaAssignmentManager(master, masterRegion);
+ RootStore rootStore) {
+ return new BrokenMasterMetaAssignmentManager(master, rootStore);
}
}
@@ -139,8 +139,8 @@ public class TestFailedMetaReplicaAssigment {
MasterServices master;
public BrokenMasterMetaAssignmentManager(final MasterServices master,
- MasterRegion masterRegion) {
- super(master, masterRegion);
+ RootStore rootStore) {
+ super(master, rootStore);
this.master = master;
}
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestBackupMasterSyncRoot.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestBackupMasterSyncRoot.java
new file mode 100644
index 0000000..be85bd8
--- /dev/null
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestBackupMasterSyncRoot.java
@@ -0,0 +1,113 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.master;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import org.apache.hadoop.hbase.HBaseClassTestRule;
+import org.apache.hadoop.hbase.HBaseTestingUtility;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.RegionLocations;
+import org.apache.hadoop.hbase.ServerName;
+import org.apache.hadoop.hbase.StartMiniClusterOption;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.RegionInfo;
+import org.apache.hadoop.hbase.client.RegionLocateType;
+import org.apache.hadoop.hbase.master.MetaLocationCache.CacheHolder;
+import org.apache.hadoop.hbase.master.assignment.AssignmentManager;
+import org.apache.hadoop.hbase.testclassification.MasterTests;
+import org.apache.hadoop.hbase.testclassification.MediumTests;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+@Category({ MasterTests.class, MediumTests.class })
+public class TestBackupMasterSyncRoot {
+
+ @ClassRule
+ public static final HBaseClassTestRule CLASS_RULE =
+ HBaseClassTestRule.forClass(TestBackupMasterSyncRoot.class);
+
+ private static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ UTIL.getConfiguration().setInt(MetaLocationCache.SYNC_INTERVAL_SECONDS, 1);
+ StartMiniClusterOption option =
+ StartMiniClusterOption.builder().numMasters(2).numRegionServers(3).build();
+ UTIL.startMiniCluster(option);
+ UTIL.getAdmin().balancerSwitch(false, true);
+ }
+
+ @AfterClass
+ public static void tearDown() throws IOException {
+ UTIL.shutdownMiniCluster();
+ }
+
+ @Test
+ public void testSync() throws Exception {
+ HMaster active = UTIL.getHBaseCluster().getMaster();
+ AssignmentManager activeAM = active.getAssignmentManager();
+ RegionInfo meta =
+ activeAM.getRegionStates().getRegionsOfTable(TableName.META_TABLE_NAME).get(0);
+ ServerName expected = activeAM.getRegionStates().getRegionStateNode(meta).getRegionLocation();
+ HMaster backup = UTIL.getHBaseCluster().getMasterThreads().stream().map(t -> t.getMaster())
+ .filter(h -> h != active).findFirst().get();
+ MetaLocationCache cache = backup.getMetaLocationCache();
+ UTIL.waitFor(10000, () -> {
+ RegionLocations loc = cache.locateMeta(HConstants.EMPTY_START_ROW, RegionLocateType.CURRENT);
+ return loc != null && loc.getRegionLocation().getServerName().equals(expected);
+ });
+ CacheHolder currentHolder = cache.holder.get();
+ assertNotNull(currentHolder);
+ long lastSyncSeqId = currentHolder.lastSyncSeqId;
+ long currentMVCC = active.masterRegion.getReadPoint();
+ assertTrue(lastSyncSeqId <= currentMVCC);
+ TableName table = TableName.valueOf("test");
+ UTIL.createTable(table, Bytes.toBytes("f"));
+ UTIL.waitTableAvailable(table);
+ long newMVCC = active.masterRegion.getReadPoint();
+ // we have created several new procedures so the read point should be advanced
+ assertTrue(newMVCC > currentMVCC);
+ Thread.sleep(3000);
+ // should not change since the root family is not changed
+ assertSame(currentHolder, cache.holder.get());
+
+ ServerName newExpected =
+ UTIL.getAdmin().getRegionServers().stream().filter(s -> !s.equals(expected)).findAny().get();
+ active.getAssignmentManager().moveAsync(new RegionPlan(meta, expected, newExpected)).get();
+ assertEquals(newExpected,
+ activeAM.getRegionStates().getRegionStateNode(meta).getRegionLocation());
+ UTIL.waitFor(10000, () -> {
+ RegionLocations loc = cache.locateMeta(HConstants.EMPTY_START_ROW, RegionLocateType.CURRENT);
+ return loc != null && loc.getRegionLocation().getServerName().equals(newExpected);
+ });
+ CacheHolder newHolder = cache.holder.get();
+ // this time the cache should be changed
+ assertNotSame(currentHolder, newHolder);
+ assertTrue(newHolder.lastSyncSeqId > newMVCC);
+ }
+}
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestCloseAnOpeningRegion.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestCloseAnOpeningRegion.java
index ecc5796..957eba5 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestCloseAnOpeningRegion.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestCloseAnOpeningRegion.java
@@ -31,7 +31,7 @@ import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.RegionInfo;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.master.assignment.AssignmentManager;
-import org.apache.hadoop.hbase.master.region.MasterRegion;
+import org.apache.hadoop.hbase.master.region.RootStore;
import org.apache.hadoop.hbase.regionserver.HRegionServer;
import org.apache.hadoop.hbase.testclassification.MasterTests;
import org.apache.hadoop.hbase.testclassification.MediumTests;
@@ -71,8 +71,8 @@ public class TestCloseAnOpeningRegion {
@Override
protected AssignmentManager createAssignmentManager(MasterServices master,
- MasterRegion masterRegion) {
- return new AssignmentManager(master, masterRegion) {
+ RootStore rootStore) {
+ return new AssignmentManager(master, rootStore) {
@Override
public ReportRegionStateTransitionResponse reportRegionStateTransition(
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestClusterRestartFailover.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestClusterRestartFailover.java
index 7ec4c46..5f092e4 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestClusterRestartFailover.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestClusterRestartFailover.java
@@ -39,7 +39,7 @@ import org.apache.hadoop.hbase.master.assignment.AssignmentManager;
import org.apache.hadoop.hbase.master.assignment.ServerState;
import org.apache.hadoop.hbase.master.assignment.ServerStateNode;
import org.apache.hadoop.hbase.master.procedure.ServerCrashProcedure;
-import org.apache.hadoop.hbase.master.region.MasterRegion;
+import org.apache.hadoop.hbase.master.region.RootStore;
import org.apache.hadoop.hbase.procedure2.Procedure;
import org.apache.hadoop.hbase.test.MetricsAssertHelper;
import org.apache.hadoop.hbase.testclassification.LargeTests;
@@ -167,15 +167,15 @@ public class TestClusterRestartFailover extends AbstractTestRestartCluster {
@Override
protected AssignmentManager createAssignmentManager(MasterServices master,
- MasterRegion masterRegion) {
- return new AssignmentManagerForTest(master, masterRegion);
+ RootStore rootStore) {
+ return new AssignmentManagerForTest(master, rootStore);
}
}
private static final class AssignmentManagerForTest extends AssignmentManager {
- public AssignmentManagerForTest(MasterServices master, MasterRegion masterRegion) {
- super(master, masterRegion);
+ public AssignmentManagerForTest(MasterServices master, RootStore rootStore) {
+ super(master, rootStore);
}
@Override
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMetaLocationCache.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMetaLocationCache.java
index 306767e..2e4d3af 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMetaLocationCache.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMetaLocationCache.java
@@ -22,6 +22,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -45,6 +46,7 @@ import org.apache.hadoop.hbase.testclassification.MasterTests;
import org.apache.hadoop.hbase.testclassification.MediumTests;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.FutureUtils;
+import org.apache.hadoop.hbase.util.Pair;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
@@ -99,7 +101,7 @@ public class TestMetaLocationCache {
@Test
public void testError() throws InterruptedException {
AsyncClusterConnection conn = mock(AsyncClusterConnection.class);
- when(conn.getAllMetaRegionLocations(anyInt()))
+ when(conn.syncRoot(anyLong(), anyInt()))
.thenReturn(FutureUtils.failedFuture(new RuntimeException("inject error")));
when(master.getAsyncClusterConnection()).thenReturn(conn);
Thread.sleep(2000);
@@ -109,8 +111,8 @@ public class TestMetaLocationCache {
HRegionLocation loc =
new HRegionLocation(RegionInfoBuilder.newBuilder(TableName.META_TABLE_NAME).build(),
ServerName.valueOf("localhost", 12345, System.currentTimeMillis()));
- when(conn.getAllMetaRegionLocations(anyInt()))
- .thenReturn(CompletableFuture.completedFuture(Arrays.asList(loc)));
+ when(conn.syncRoot(anyLong(), anyInt()))
+ .thenReturn(CompletableFuture.completedFuture(Pair.newPair(1L, Arrays.asList(loc))));
Thread.sleep(2000);
List<HRegionLocation> list = cache.getAllMetaRegionLocations(false);
assertEquals(1, list.size());
@@ -131,8 +133,8 @@ public class TestMetaLocationCache {
ServerName.valueOf("127.0.0.2", 12345, System.currentTimeMillis()));
HRegionLocation daughter2Loc = new HRegionLocation(daughter2,
ServerName.valueOf("127.0.0.3", 12345, System.currentTimeMillis()));
- when(conn.getAllMetaRegionLocations(anyInt())).thenReturn(
- CompletableFuture.completedFuture(Arrays.asList(parentLoc, daughter1Loc, daughter2Loc)));
+ when(conn.syncRoot(anyLong(), anyInt())).thenReturn(CompletableFuture
+ .completedFuture(Pair.newPair(1L, Arrays.asList(parentLoc, daughter1Loc, daughter2Loc))));
when(master.getAsyncClusterConnection()).thenReturn(conn);
Thread.sleep(2000);
}
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/MockMasterServices.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/MockMasterServices.java
index b04990c..fda156c 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/MockMasterServices.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/MockMasterServices.java
@@ -52,6 +52,7 @@ import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;
import org.apache.hadoop.hbase.master.procedure.RSProcedureDispatcher;
import org.apache.hadoop.hbase.master.region.MasterRegion;
import org.apache.hadoop.hbase.master.region.MasterRegionFactory;
+import org.apache.hadoop.hbase.master.region.RootStore;
import org.apache.hadoop.hbase.procedure2.ProcedureEvent;
import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
import org.apache.hadoop.hbase.procedure2.ProcedureTestingUtility;
@@ -110,9 +111,10 @@ public class MockMasterServices extends MockNoopMasterServices {
conf.getBoolean(HBASE_SPLIT_WAL_COORDINATED_BY_ZK, DEFAULT_HBASE_SPLIT_COORDINATED_BY_ZK)?
null: new SplitWALManager(this);
this.masterRegion = MasterRegionFactory.create(this);
+ RootStore rootStore = new RootStore(masterRegion);
// Mock an AM.
this.assignmentManager =
- new AssignmentManager(this, masterRegion, new MockRegionStateStore(this, masterRegion));
+ new AssignmentManager(this, rootStore, new MockRegionStateStore(this, rootStore));
this.balancer = LoadBalancerFactory.getLoadBalancer(conf);
this.serverManager = new ServerManager(this);
this.tableStateManager = Mockito.mock(TableStateManager.class);
@@ -291,8 +293,8 @@ public class MockMasterServices extends MockNoopMasterServices {
}
private static class MockRegionStateStore extends RegionStateStore {
- public MockRegionStateStore(MasterServices master, MasterRegion masterRegion) {
- super(master, masterRegion);
+ public MockRegionStateStore(MasterServices master, RootStore rootStore) {
+ super(master, rootStore);
}
@Override
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestOpenRegionProcedureBackoff.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestOpenRegionProcedureBackoff.java
index 227872a..8f0a5a1 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestOpenRegionProcedureBackoff.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestOpenRegionProcedureBackoff.java
@@ -32,7 +32,7 @@ import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
import org.apache.hadoop.hbase.master.HMaster;
import org.apache.hadoop.hbase.master.MasterServices;
-import org.apache.hadoop.hbase.master.region.MasterRegion;
+import org.apache.hadoop.hbase.master.region.RootStore;
import org.apache.hadoop.hbase.testclassification.MasterTests;
import org.apache.hadoop.hbase.testclassification.MediumTests;
import org.apache.hadoop.hbase.util.Bytes;
@@ -56,8 +56,8 @@ public class TestOpenRegionProcedureBackoff {
private static final class AssignmentManagerForTest extends AssignmentManager {
- public AssignmentManagerForTest(MasterServices master, MasterRegion masterRegion) {
- super(master, masterRegion);
+ public AssignmentManagerForTest(MasterServices master, RootStore rootStore) {
+ super(master, rootStore);
}
@Override
@@ -77,8 +77,8 @@ public class TestOpenRegionProcedureBackoff {
@Override
protected AssignmentManager createAssignmentManager(MasterServices master,
- MasterRegion masterRegion) {
- return new AssignmentManagerForTest(master, masterRegion);
+ RootStore rootStore) {
+ return new AssignmentManagerForTest(master, rootStore);
}
}
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestOpenRegionProcedureHang.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestOpenRegionProcedureHang.java
index 57ce3a3..530f06e 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestOpenRegionProcedureHang.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestOpenRegionProcedureHang.java
@@ -32,7 +32,7 @@ import org.apache.hadoop.hbase.master.HMaster;
import org.apache.hadoop.hbase.master.MasterServices;
import org.apache.hadoop.hbase.master.RegionPlan;
import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;
-import org.apache.hadoop.hbase.master.region.MasterRegion;
+import org.apache.hadoop.hbase.master.region.RootStore;
import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
import org.apache.hadoop.hbase.regionserver.HRegionServer;
import org.apache.hadoop.hbase.testclassification.MasterTests;
@@ -75,8 +75,8 @@ public class TestOpenRegionProcedureHang {
private static final class AssignmentManagerForTest extends AssignmentManager {
- public AssignmentManagerForTest(MasterServices master,MasterRegion masterRegion) {
- super(master, masterRegion);
+ public AssignmentManagerForTest(MasterServices master, RootStore rootStore) {
+ super(master, rootStore);
}
@Override
@@ -112,8 +112,8 @@ public class TestOpenRegionProcedureHang {
@Override
protected AssignmentManager createAssignmentManager(MasterServices master,
- MasterRegion masterRegion) {
- return new AssignmentManagerForTest(master, masterRegion);
+ RootStore rootStore) {
+ return new AssignmentManagerForTest(master, rootStore);
}
@Override
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestRaceBetweenSCPAndDTP.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestRaceBetweenSCPAndDTP.java
index 6576eb7..107cf82 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestRaceBetweenSCPAndDTP.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestRaceBetweenSCPAndDTP.java
@@ -31,7 +31,7 @@ import org.apache.hadoop.hbase.master.HMaster;
import org.apache.hadoop.hbase.master.MasterServices;
import org.apache.hadoop.hbase.master.procedure.DisableTableProcedure;
import org.apache.hadoop.hbase.master.procedure.ServerCrashProcedure;
-import org.apache.hadoop.hbase.master.region.MasterRegion;
+import org.apache.hadoop.hbase.master.region.RootStore;
import org.apache.hadoop.hbase.procedure2.Procedure;
import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
import org.apache.hadoop.hbase.testclassification.MasterTests;
@@ -70,8 +70,8 @@ public class TestRaceBetweenSCPAndDTP {
private static final class AssignmentManagerForTest extends AssignmentManager {
- public AssignmentManagerForTest(MasterServices master, MasterRegion masterRegion) {
- super(master,masterRegion);
+ public AssignmentManagerForTest(MasterServices master, RootStore rootStore) {
+ super(master, rootStore);
}
@Override
@@ -97,8 +97,8 @@ public class TestRaceBetweenSCPAndDTP {
@Override
protected AssignmentManager createAssignmentManager(MasterServices master,
- MasterRegion masterRegion) {
- return new AssignmentManagerForTest(master, masterRegion);
+ RootStore rootStore) {
+ return new AssignmentManagerForTest(master, rootStore);
}
}
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestRaceBetweenSCPAndTRSP.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestRaceBetweenSCPAndTRSP.java
index 65cef99..42d0c34 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestRaceBetweenSCPAndTRSP.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestRaceBetweenSCPAndTRSP.java
@@ -32,7 +32,7 @@ import org.apache.hadoop.hbase.master.HMaster;
import org.apache.hadoop.hbase.master.MasterServices;
import org.apache.hadoop.hbase.master.RegionPlan;
import org.apache.hadoop.hbase.master.procedure.ServerCrashProcedure;
-import org.apache.hadoop.hbase.master.region.MasterRegion;
+import org.apache.hadoop.hbase.master.region.RootStore;
import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
import org.apache.hadoop.hbase.testclassification.LargeTests;
import org.apache.hadoop.hbase.testclassification.MasterTests;
@@ -70,8 +70,8 @@ public class TestRaceBetweenSCPAndTRSP {
private static final class AssignmentManagerForTest extends AssignmentManager {
- public AssignmentManagerForTest(MasterServices master, MasterRegion masterRegion) {
- super(master, masterRegion);
+ public AssignmentManagerForTest(MasterServices master, RootStore rootStore) {
+ super(master, rootStore);
}
@Override
@@ -110,8 +110,8 @@ public class TestRaceBetweenSCPAndTRSP {
@Override
protected AssignmentManager createAssignmentManager(MasterServices master,
- MasterRegion masterRegion) {
- return new AssignmentManagerForTest(master, masterRegion);
+ RootStore rootStore) {
+ return new AssignmentManagerForTest(master, rootStore);
}
}
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestRegionAssignedToMultipleRegionServers.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestRegionAssignedToMultipleRegionServers.java
index dac471e..56caeec 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestRegionAssignedToMultipleRegionServers.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestRegionAssignedToMultipleRegionServers.java
@@ -37,7 +37,7 @@ import org.apache.hadoop.hbase.master.HMaster;
import org.apache.hadoop.hbase.master.MasterServices;
import org.apache.hadoop.hbase.master.RegionPlan;
import org.apache.hadoop.hbase.master.ServerManager;
-import org.apache.hadoop.hbase.master.region.MasterRegion;
+import org.apache.hadoop.hbase.master.region.RootStore;
import org.apache.hadoop.hbase.regionserver.HRegionServer;
import org.apache.hadoop.hbase.testclassification.MasterTests;
import org.apache.hadoop.hbase.testclassification.MediumTests;
@@ -81,8 +81,8 @@ public class TestRegionAssignedToMultipleRegionServers {
private static final class AssignmentManagerForTest extends AssignmentManager {
- public AssignmentManagerForTest(MasterServices master, MasterRegion masterRegion) {
- super(master, masterRegion);
+ public AssignmentManagerForTest(MasterServices master, RootStore rootStore) {
+ super(master, rootStore);
}
@Override
@@ -116,8 +116,8 @@ public class TestRegionAssignedToMultipleRegionServers {
@Override
protected AssignmentManager createAssignmentManager(MasterServices master,
- MasterRegion masterRegion) {
- return new AssignmentManagerForTest(master, masterRegion);
+ RootStore rootStore) {
+ return new AssignmentManagerForTest(master, rootStore);
}
@Override
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestReportOnlineRegionsRace.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestReportOnlineRegionsRace.java
index 2d0128a..217bde6 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestReportOnlineRegionsRace.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestReportOnlineRegionsRace.java
@@ -39,7 +39,7 @@ import org.apache.hadoop.hbase.master.MasterServices;
import org.apache.hadoop.hbase.master.RegionPlan;
import org.apache.hadoop.hbase.master.RegionState;
import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;
-import org.apache.hadoop.hbase.master.region.MasterRegion;
+import org.apache.hadoop.hbase.master.region.RootStore;
import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
import org.apache.hadoop.hbase.testclassification.MasterTests;
import org.apache.hadoop.hbase.testclassification.MediumTests;
@@ -69,8 +69,8 @@ public class TestReportOnlineRegionsRace {
private static final class AssignmentManagerForTest extends AssignmentManager {
- public AssignmentManagerForTest(MasterServices master, MasterRegion masterRegion) {
- super(master, masterRegion);
+ public AssignmentManagerForTest(MasterServices master, RootStore rootStore) {
+ super(master, rootStore);
}
@Override
@@ -112,8 +112,8 @@ public class TestReportOnlineRegionsRace {
@Override
protected AssignmentManager createAssignmentManager(MasterServices master,
- MasterRegion masterRegion) {
- return new AssignmentManagerForTest(master, masterRegion);
+ RootStore rootStore) {
+ return new AssignmentManagerForTest(master, rootStore);
}
}
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestReportRegionStateTransitionFromDeadServer.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestReportRegionStateTransitionFromDeadServer.java
index 41e884d..db9f45f 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestReportRegionStateTransitionFromDeadServer.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestReportRegionStateTransitionFromDeadServer.java
@@ -40,7 +40,7 @@ import org.apache.hadoop.hbase.master.HMaster;
import org.apache.hadoop.hbase.master.MasterServices;
import org.apache.hadoop.hbase.master.RegionPlan;
import org.apache.hadoop.hbase.master.ServerManager;
-import org.apache.hadoop.hbase.master.region.MasterRegion;
+import org.apache.hadoop.hbase.master.region.RootStore;
import org.apache.hadoop.hbase.regionserver.HRegionServer;
import org.apache.hadoop.hbase.testclassification.MasterTests;
import org.apache.hadoop.hbase.testclassification.MediumTests;
@@ -83,8 +83,8 @@ public class TestReportRegionStateTransitionFromDeadServer {
private static final class AssignmentManagerForTest extends AssignmentManager {
- public AssignmentManagerForTest(MasterServices master, MasterRegion masterRegion) {
- super(master, masterRegion);
+ public AssignmentManagerForTest(MasterServices master, RootStore rootStore) {
+ super(master, rootStore);
}
@Override
@@ -123,8 +123,8 @@ public class TestReportRegionStateTransitionFromDeadServer {
@Override
protected AssignmentManager createAssignmentManager(MasterServices master,
- MasterRegion masterRegion) {
- return new AssignmentManagerForTest(master, masterRegion);
+ RootStore rootStore) {
+ return new AssignmentManagerForTest(master, rootStore);
}
@Override
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestReportRegionStateTransitionRetry.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestReportRegionStateTransitionRetry.java
index 0943298..632801e 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestReportRegionStateTransitionRetry.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestReportRegionStateTransitionRetry.java
@@ -36,7 +36,7 @@ import org.apache.hadoop.hbase.master.HMaster;
import org.apache.hadoop.hbase.master.MasterServices;
import org.apache.hadoop.hbase.master.RegionPlan;
import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;
-import org.apache.hadoop.hbase.master.region.MasterRegion;
+import org.apache.hadoop.hbase.master.region.RootStore;
import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
import org.apache.hadoop.hbase.testclassification.MasterTests;
import org.apache.hadoop.hbase.testclassification.MediumTests;
@@ -61,8 +61,8 @@ public class TestReportRegionStateTransitionRetry {
private static final class AssignmentManagerForTest extends AssignmentManager {
- public AssignmentManagerForTest(MasterServices master, MasterRegion masterRegion) {
- super(master, masterRegion);
+ public AssignmentManagerForTest(MasterServices master, RootStore rootStore) {
+ super(master, rootStore);
}
@Override
@@ -90,8 +90,8 @@ public class TestReportRegionStateTransitionRetry {
@Override
protected AssignmentManager createAssignmentManager(MasterServices master,
- MasterRegion masterRegion) {
- return new AssignmentManagerForTest(master, masterRegion);
+ RootStore rootStore) {
+ return new AssignmentManagerForTest(master, rootStore);
}
}
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestSCPGetRegionsRace.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestSCPGetRegionsRace.java
index ffca796..d4f1cf4 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestSCPGetRegionsRace.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestSCPGetRegionsRace.java
@@ -38,7 +38,7 @@ import org.apache.hadoop.hbase.master.MasterServices;
import org.apache.hadoop.hbase.master.RegionPlan;
import org.apache.hadoop.hbase.master.ServerManager;
import org.apache.hadoop.hbase.master.procedure.ServerCrashProcedure;
-import org.apache.hadoop.hbase.master.region.MasterRegion;
+import org.apache.hadoop.hbase.master.region.RootStore;
import org.apache.hadoop.hbase.regionserver.HRegionServer;
import org.apache.hadoop.hbase.testclassification.MasterTests;
import org.apache.hadoop.hbase.testclassification.MediumTests;
@@ -90,8 +90,8 @@ public class TestSCPGetRegionsRace {
private static final class AssignmentManagerForTest extends AssignmentManager {
- public AssignmentManagerForTest(MasterServices master, MasterRegion masterRegion) {
- super(master, masterRegion);
+ public AssignmentManagerForTest(MasterServices master, RootStore rootStore) {
+ super(master, rootStore);
}
@Override
@@ -136,8 +136,8 @@ public class TestSCPGetRegionsRace {
@Override
protected AssignmentManager createAssignmentManager(MasterServices master,
- MasterRegion masterRegion) {
- return new AssignmentManagerForTest(master, masterRegion);
+ RootStore rootStore) {
+ return new AssignmentManagerForTest(master, rootStore);
}
@Override
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestWakeUpUnexpectedProcedure.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestWakeUpUnexpectedProcedure.java
index fb0e460..943d51e 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestWakeUpUnexpectedProcedure.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestWakeUpUnexpectedProcedure.java
@@ -38,7 +38,7 @@ import org.apache.hadoop.hbase.master.MasterServices;
import org.apache.hadoop.hbase.master.RegionPlan;
import org.apache.hadoop.hbase.master.RegionState;
import org.apache.hadoop.hbase.master.ServerManager;
-import org.apache.hadoop.hbase.master.region.MasterRegion;
+import org.apache.hadoop.hbase.master.region.RootStore;
import org.apache.hadoop.hbase.regionserver.HRegionServer;
import org.apache.hadoop.hbase.regionserver.RSRpcServices;
import org.apache.hadoop.hbase.testclassification.LargeTests;
@@ -136,8 +136,8 @@ public class TestWakeUpUnexpectedProcedure {
private static final class AMForTest extends AssignmentManager {
- public AMForTest(MasterServices master, MasterRegion masterRegion) {
- super(master, masterRegion);
+ public AMForTest(MasterServices master, RootStore rootStore) {
+ super(master, rootStore);
}
@Override
@@ -204,8 +204,8 @@ public class TestWakeUpUnexpectedProcedure {
@Override
protected AssignmentManager createAssignmentManager(MasterServices master,
- MasterRegion masterRegion) {
- return new AMForTest(master, masterRegion);
+ RootStore rootStore) {
+ return new AMForTest(master, rootStore);
}
@Override
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestRegionMover2.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestRegionMover2.java
index 6007fd7..4092929 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestRegionMover2.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestRegionMover2.java
@@ -67,6 +67,11 @@ public class TestRegionMover2 {
private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
+ // when moving region, we first need to get the location of meta so it will call master inside the
+ // master rpc handler thread, which may cause dead lock if we have more than 3 threads here since
+ // we only have 3 rpc handlers for master in UT.
+ private static final int MAX_THREADS = 2;
+
@BeforeClass
public static void setUpBeforeClass() throws Exception {
TEST_UTIL.startMiniCluster(3);
@@ -116,7 +121,7 @@ public class TestRegionMover2 {
.collect(Collectors.toList());
RegionMover.RegionMoverBuilder rmBuilder =
new RegionMover.RegionMoverBuilder(rsName, TEST_UTIL.getConfiguration()).ack(true)
- .maxthreads(8);
+ .maxthreads(MAX_THREADS);
try (RegionMover rm = rmBuilder.build()) {
LOG.debug("Unloading {}", regionServer.getServerName());
rm.unload();
@@ -153,7 +158,7 @@ public class TestRegionMover2 {
RegionMover.RegionMoverBuilder rmBuilder =
new RegionMover.RegionMoverBuilder(rsName, TEST_UTIL.getConfiguration()).ack(true)
- .maxthreads(8);
+ .maxthreads(MAX_THREADS);
try (RegionMover rm = rmBuilder.build()) {
LOG.debug("Unloading {}", regionServer.getServerName());
rm.unload();
@@ -194,13 +199,13 @@ public class TestRegionMover2 {
admin.flush(tableName);
HRegionServer regionServer = cluster.getRegionServer(0);
String rsName = regionServer.getServerName().getAddress().toString();
- int numRegions = regionServer.getNumberOfOnlineRegions();
+ regionServer.getNumberOfOnlineRegions();
List<HRegion> hRegions = regionServer.getRegions().stream()
.filter(hRegion -> hRegion.getRegionInfo().getTable().equals(tableName))
.collect(Collectors.toList());
RegionMover.RegionMoverBuilder rmBuilder =
new RegionMover.RegionMoverBuilder(rsName, TEST_UTIL.getConfiguration()).ack(true)
- .maxthreads(8);
+ .maxthreads(MAX_THREADS);
try (RegionMover rm = rmBuilder.build()) {
LOG.debug("Unloading {}", regionServer.getServerName());
rm.unload();