From 07b0ac41612128676ec0c932fbdacf463c9e20dd Mon Sep 17 00:00:00 2001 From: Yi Liang Date: Wed, 8 Nov 2017 09:38:46 -0800 Subject: [PATCH] HBASE-19127: Set State.SPLITTING, MERGING, MERGING_NEW, SPLITTING_NEW properly in RegionStatesNode Signed-off-by: Michael Stack --- .../src/main/protobuf/MasterProcedure.proto | 18 +++---- .../master/assignment/AssignmentManager.java | 5 ++ .../MergeTableRegionsProcedure.java | 29 ++++++----- .../hbase/master/assignment/RegionStates.java | 2 +- .../assignment/SplitTableRegionProcedure.java | 52 +++++++++++-------- 5 files changed, 60 insertions(+), 46 deletions(-) diff --git a/hbase-protocol-shaded/src/main/protobuf/MasterProcedure.proto b/hbase-protocol-shaded/src/main/protobuf/MasterProcedure.proto index 635beaf91b0..f9b8807abab 100644 --- a/hbase-protocol-shaded/src/main/protobuf/MasterProcedure.proto +++ b/hbase-protocol-shaded/src/main/protobuf/MasterProcedure.proto @@ -256,16 +256,14 @@ message SplitTableRegionStateData { enum MergeTableRegionsState { MERGE_TABLE_REGIONS_PREPARE = 1; MERGE_TABLE_REGIONS_PRE_OPERATION = 2; - MERGE_TABLE_REGIONS_MOVE_REGION_TO_SAME_RS = 3; - MERGE_TABLE_REGIONS_PRE_MERGE_OPERATION = 4; - MERGE_TABLE_REGIONS_SET_MERGING_TABLE_STATE = 5; - MERGE_TABLE_REGIONS_CLOSE_REGIONS = 6; - MERGE_TABLE_REGIONS_CREATE_MERGED_REGION = 7; - MERGE_TABLE_REGIONS_PRE_MERGE_COMMIT_OPERATION = 8; - MERGE_TABLE_REGIONS_UPDATE_META = 9; - MERGE_TABLE_REGIONS_POST_MERGE_COMMIT_OPERATION = 10; - MERGE_TABLE_REGIONS_OPEN_MERGED_REGION = 11; - MERGE_TABLE_REGIONS_POST_OPERATION = 12; + MERGE_TABLE_REGIONS_PRE_MERGE_OPERATION = 3; + MERGE_TABLE_REGIONS_CLOSE_REGIONS = 4; + MERGE_TABLE_REGIONS_CREATE_MERGED_REGION = 5; + MERGE_TABLE_REGIONS_PRE_MERGE_COMMIT_OPERATION = 6; + MERGE_TABLE_REGIONS_UPDATE_META = 7; + MERGE_TABLE_REGIONS_POST_MERGE_COMMIT_OPERATION = 8; + MERGE_TABLE_REGIONS_OPEN_MERGED_REGION = 9; + MERGE_TABLE_REGIONS_POST_OPERATION = 10; } message MergeTableRegionsStateData { 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 f4a3ca87f78..1c193f9853c 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 @@ -1532,6 +1532,11 @@ public class AssignmentManager implements ServerListener { // regionStates#getRegionsOfTable final RegionStateNode node = regionStates.getOrCreateRegionNode(parent); node.setState(State.SPLIT); + final RegionStateNode nodeA = regionStates.getOrCreateRegionNode(daughterA); + nodeA.setState(State.SPLITTING_NEW); + final RegionStateNode nodeB = regionStates.getOrCreateRegionNode(daughterB); + nodeB.setState(State.SPLITTING_NEW); + regionStateStore.splitRegion(parent, daughterA, daughterB, serverName); if (shouldAssignFavoredNodes(parent)) { List onlineServers = this.master.getServerManager().getOnlineServersList(); diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/MergeTableRegionsProcedure.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/MergeTableRegionsProcedure.java index 642bb0d1305..6663d7ca383 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/MergeTableRegionsProcedure.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/MergeTableRegionsProcedure.java @@ -47,6 +47,7 @@ import org.apache.hadoop.hbase.master.CatalogJanitor; import org.apache.hadoop.hbase.master.MasterCoprocessorHost; import org.apache.hadoop.hbase.master.MasterFileSystem; import org.apache.hadoop.hbase.master.RegionState; +import org.apache.hadoop.hbase.master.RegionState.State; import org.apache.hadoop.hbase.master.normalizer.NormalizationPlan; import org.apache.hadoop.hbase.master.procedure.AbstractStateMachineTableProcedure; import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv; @@ -222,10 +223,6 @@ public class MergeTableRegionsProcedure break; case MERGE_TABLE_REGIONS_PRE_MERGE_OPERATION: preMergeRegions(env); - setNextState(MergeTableRegionsState.MERGE_TABLE_REGIONS_SET_MERGING_TABLE_STATE); - break; - case MERGE_TABLE_REGIONS_SET_MERGING_TABLE_STATE: - setRegionStateToMerging(env); setNextState(MergeTableRegionsState.MERGE_TABLE_REGIONS_CLOSE_REGIONS); break; case MERGE_TABLE_REGIONS_CLOSE_REGIONS: @@ -295,14 +292,9 @@ public class MergeTableRegionsProcedure case MERGE_TABLE_REGIONS_CLOSE_REGIONS: rollbackCloseRegionsForMerge(env); break; - case MERGE_TABLE_REGIONS_SET_MERGING_TABLE_STATE: - setRegionStateToRevertMerging(env); - break; case MERGE_TABLE_REGIONS_PRE_MERGE_OPERATION: postRollBackMergeRegions(env); break; - case MERGE_TABLE_REGIONS_MOVE_REGION_TO_SAME_RS: - break; // nothing to rollback case MERGE_TABLE_REGIONS_PREPARE: break; default: @@ -513,6 +505,8 @@ public class MergeTableRegionsProcedure return false; } + // Update region states to Merging + setRegionStateToMerging(env); return true; } @@ -560,16 +554,23 @@ public class MergeTableRegionsProcedure * @throws IOException */ public void setRegionStateToMerging(final MasterProcedureEnv env) throws IOException { - //transition.setTransitionCode(TransitionCode.READY_TO_MERGE); + // Set State.MERGING to regions to be merged + RegionStates regionStates = env.getAssignmentManager().getRegionStates(); + regionStates.getRegionNode(regionsToMerge[0]).setState(State.MERGING); + regionStates.getRegionNode(regionsToMerge[1]).setState(State.MERGING); } /** * Rollback the region state change + * Not used for now, since rollbackCloseRegionsForMerge() will mark regions as OPEN * @param env MasterProcedureEnv * @throws IOException */ - private void setRegionStateToRevertMerging(final MasterProcedureEnv env) throws IOException { - //transition.setTransitionCode(TransitionCode.MERGE_REVERTED); + private void setRegionStateBackToOpen(final MasterProcedureEnv env) throws IOException { + // revert region state to Open + RegionStates regionStates = env.getAssignmentManager().getRegionStates(); + regionStates.getRegionNode(regionsToMerge[0]).setState(State.OPEN); + regionStates.getRegionNode(regionsToMerge[1]).setState(State.OPEN); } /** @@ -591,6 +592,10 @@ public class MergeTableRegionsProcedure mergeStoreFiles(env, regionFs2, regionFs.getMergesDir()); regionFs.commitMergedRegion(mergedRegion); + + //Prepare to create merged regions + env.getAssignmentManager().getRegionStates(). + getOrCreateRegionNode(mergedRegion).setState(State.MERGING_NEW); } /** diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/RegionStates.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/RegionStates.java index f404abbc82b..682d529a946 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/RegionStates.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/RegionStates.java @@ -67,7 +67,7 @@ public class RegionStates { }; protected static final State[] STATES_EXPECTED_ON_CLOSE = new State[] { - State.SPLITTING, State.SPLIT, // ServerCrashProcedure + State.SPLITTING, State.SPLIT, State.MERGING, // ServerCrashProcedure State.OPEN, // enabled/open State.CLOSING // already in-progress (retrying) }; diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java index 201d0aef033..1eb00c9c056 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/SplitTableRegionProcedure.java @@ -42,6 +42,7 @@ import org.apache.hadoop.hbase.DoNotRetryIOException; import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.ServerName; import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.UnknownRegionException; import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor; import org.apache.hadoop.hbase.client.MasterSwitchType; import org.apache.hadoop.hbase.client.Mutation; @@ -406,31 +407,32 @@ public class SplitTableRegionProcedure public boolean prepareSplitRegion(final MasterProcedureEnv env) throws IOException { // Check whether the region is splittable RegionStateNode node = - env.getAssignmentManager().getRegionStates().getRegionNode(getParentRegion()); - RegionInfo parentHRI = null; - if (node != null) { - parentHRI = node.getRegionInfo(); + env.getAssignmentManager().getRegionStates().getRegionNode(getParentRegion()); - // Lookup the parent HRI state from the AM, which has the latest updated info. - // Protect against the case where concurrent SPLIT requests came in and succeeded - // just before us. - if (node.isInState(State.SPLIT)) { - LOG.info("Split of " + parentHRI + " skipped; state is already SPLIT"); - return false; - } - if (parentHRI.isSplit() || parentHRI.isOffline()) { - LOG.info("Split of " + parentHRI + " skipped because offline/split."); - return false; - } + if (node == null) { + throw new UnknownRegionException(getParentRegion().getRegionNameAsString()); + } - // expected parent to be online or closed - if (!node.isInState(EXPECTED_SPLIT_STATES)) { - // We may have SPLIT already? - setFailure(new IOException("Split " + parentHRI.getRegionNameAsString() + - " FAILED because state=" + node.getState() + "; expected " + - Arrays.toString(EXPECTED_SPLIT_STATES))); - return false; - } + RegionInfo parentHRI = node.getRegionInfo(); + // Lookup the parent HRI state from the AM, which has the latest updated info. + // Protect against the case where concurrent SPLIT requests came in and succeeded + // just before us. + if (node.isInState(State.SPLIT)) { + LOG.info("Split of " + parentHRI + " skipped; state is already SPLIT"); + return false; + } + if (parentHRI.isSplit() || parentHRI.isOffline()) { + LOG.info("Split of " + parentHRI + " skipped because offline/split."); + return false; + } + + // expected parent to be online or closed + if (!node.isInState(EXPECTED_SPLIT_STATES)) { + // We may have SPLIT already? + setFailure(new IOException("Split " + parentHRI.getRegionNameAsString() + + " FAILED because state=" + node.getState() + "; expected " + + Arrays.toString(EXPECTED_SPLIT_STATES))); + return false; } // Since we have the lock and the master is coordinating the operation @@ -442,6 +444,10 @@ public class SplitTableRegionProcedure " failed due to split switch off")); return false; } + + // set node state as SPLITTING + node.setState(State.SPLITTING); + return true; }