HBASE-25255 Master fails to initialize when creating rs group table (#2638)

Signed-off-by: Guanghao Zhang <zghao@apache.org>
This commit is contained in:
Duo Zhang 2020-11-13 14:28:31 +08:00 committed by GitHub
parent 035c192eb6
commit f89faf3ac8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 19 deletions

View File

@ -964,6 +964,9 @@ public class HMaster extends HRegionServer implements MasterServices {
} }
this.assignmentManager.joinCluster(); this.assignmentManager.joinCluster();
// The below depends on hbase:meta being online. // The below depends on hbase:meta being online.
this.assignmentManager.processOfflineRegions();
// this must be called after the above processOfflineRegions to prevent race
this.assignmentManager.wakeMetaLoadedEvent();
// for migrating from a version without HBASE-25099, and also for honoring the configuration // for migrating from a version without HBASE-25099, and also for honoring the configuration
// first. // first.
@ -997,7 +1000,6 @@ public class HMaster extends HRegionServer implements MasterServices {
} }
} }
} }
this.assignmentManager.processOfflineRegions();
// Initialize after meta is up as below scans meta // Initialize after meta is up as below scans meta
if (getFavoredNodesManager() != null && !maintenanceMode) { if (getFavoredNodesManager() != null && !maintenanceMode) {
SnapshotOfRegionAssignmentFromMeta snapshotOfRegionAssignment = SnapshotOfRegionAssignmentFromMeta snapshotOfRegionAssignment =

View File

@ -505,8 +505,16 @@ public class AssignmentManager {
return metaLoadEvent.suspendIfNotReady(proc); return metaLoadEvent.suspendIfNotReady(proc);
} }
/**
* This method will be called in master initialization method after calling
* {@link #processOfflineRegions()}, as in processOfflineRegions we will generate assign
* procedures for offline regions, which may be conflict with creating table.
* <p/>
* This is a bit dirty, should be reconsidered after we decide whether to keep the
* {@link #processOfflineRegions()} method.
*/
@VisibleForTesting @VisibleForTesting
void wakeMetaLoadedEvent() { public void wakeMetaLoadedEvent() {
metaLoadEvent.wake(getProcedureScheduler()); metaLoadEvent.wake(getProcedureScheduler());
assert isMetaLoaded() : "expected meta to be loaded"; assert isMetaLoaded() : "expected meta to be loaded";
} }
@ -1505,12 +1513,23 @@ public class AssignmentManager {
// Public so can be run by the Master as part of the startup. Needs hbase:meta to be online. // Public so can be run by the Master as part of the startup. Needs hbase:meta to be online.
// Needs to be done after the table state manager has been started. // Needs to be done after the table state manager has been started.
public void processOfflineRegions() { public void processOfflineRegions() {
List<RegionInfo> offlineRegions = regionStates.getRegionStates().stream() TransitRegionStateProcedure[] procs =
.filter(RegionState::isOffline).filter(s -> isTableEnabled(s.getRegion().getTable())) regionStates.getRegionStateNodes().stream().filter(rsn -> rsn.isInState(State.OFFLINE))
.map(RegionState::getRegion).collect(Collectors.toList()); .filter(rsn -> isTableEnabled(rsn.getRegionInfo().getTable())).map(rsn -> {
if (!offlineRegions.isEmpty()) { rsn.lock();
master.getMasterProcedureExecutor().submitProcedures( try {
master.getAssignmentManager().createRoundRobinAssignProcedures(offlineRegions)); if (rsn.getProcedure() != null) {
return null;
} else {
return rsn.setProcedure(TransitRegionStateProcedure.assign(getProcedureEnvironment(),
rsn.getRegionInfo(), null));
}
} finally {
rsn.unlock();
}
}).filter(p -> p != null).toArray(TransitRegionStateProcedure[]::new);
if (procs.length > 0) {
master.getMasterProcedureExecutor().submitProcedures(procs);
} }
} }
@ -1590,8 +1609,6 @@ public class AssignmentManager {
private void loadMeta() throws IOException { private void loadMeta() throws IOException {
// TODO: use a thread pool // TODO: use a thread pool
regionStateStore.visitMeta(new RegionMetaLoadingVisitor()); regionStateStore.visitMeta(new RegionMetaLoadingVisitor());
// every assignment is blocked until meta is loaded.
wakeMetaLoadedEvent();
} }
/** /**

View File

@ -234,15 +234,6 @@ public class CreateTableProcedure
} }
} }
@Override
protected boolean waitInitialized(MasterProcedureEnv env) {
if (getTableName().isSystemTable()) {
// Creating system table is part of the initialization, so do not wait here.
return false;
}
return super.waitInitialized(env);
}
private boolean prepareCreate(final MasterProcedureEnv env) throws IOException { private boolean prepareCreate(final MasterProcedureEnv env) throws IOException {
final TableName tableName = getTableName(); final TableName tableName = getTableName();
if (env.getMasterServices().getTableDescriptors().exists(tableName)) { if (env.getMasterServices().getTableDescriptors().exists(tableName)) {

View File

@ -116,6 +116,7 @@ public class MasterProcedureTestingUtility {
AssignmentManager am = env.getAssignmentManager(); AssignmentManager am = env.getAssignmentManager();
try { try {
am.joinCluster(); am.joinCluster();
am.wakeMetaLoadedEvent();
master.setInitialized(true); master.setInitialized(true);
} catch (Exception e) { } catch (Exception e) {
LOG.warn("Failed to load meta", e); LOG.warn("Failed to load meta", e);