Skip to content

Commit a6fa265

Browse files
HBASE-30169 change the place to check the isSplitOrMerged
1 parent 1e4f21c commit a6fa265

4 files changed

Lines changed: 34 additions & 20 deletions

File tree

hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/AssignmentManager.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1892,9 +1892,10 @@ public void visitRegionState(Result result, final RegionInfo regionInfo, final S
18921892
}
18931893
// add regions to RIT while visiting the meta
18941894
regionInTransitionTracker.handleRegionStateNodeOperation(regionNode);
1895-
// If region location of region belongs to a dead server mark the region crashed
1895+
// If region is supposed to be serve traffic (NOT split and merged) and location of region
1896+
// belongs to a dead server mark the region crashed
18961897
if (
1897-
regionNode.getRegionLocation() != null
1898+
regionNode.getRegionLocation() != null && !AssignmentManagerUtil.isSplitOrMerged(regionNode)
18981899
&& master.getServerManager().isServerDead(regionNode.getRegionLocation())
18991900
) {
19001901
long timeOfCrash = master.getServerManager().getDeadServers()

hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/AssignmentManagerUtil.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.apache.hadoop.hbase.client.RegionInfo;
3636
import org.apache.hadoop.hbase.client.RegionReplicaUtil;
3737
import org.apache.hadoop.hbase.favored.FavoredNodesManager;
38+
import org.apache.hadoop.hbase.master.RegionState;
3839
import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;
3940
import org.apache.hadoop.hbase.util.FutureUtils;
4041
import org.apache.hadoop.hbase.wal.WALSplitUtil;
@@ -298,4 +299,16 @@ static void checkClosedRegion(MasterProcedureEnv env, RegionInfo regionInfo) thr
298299
+ ", abort split/merge to prevent data loss");
299300
}
300301
}
302+
303+
/**
304+
* For splitting, need to test both region info and state, and will return true if either of the
305+
* test returns true. Please see the comments in
306+
* {@link AssignmentManager#markRegionAsSplit(RegionInfo, ServerName, RegionInfo, RegionInfo)} for
307+
* more details on why we need to test two conditions.
308+
*/
309+
static boolean isSplitOrMerged(RegionStateNode regionStateNode) {
310+
return regionStateNode.getState() == RegionState.State.SPLIT
311+
|| regionStateNode.getRegionInfo().isSplit()
312+
|| regionStateNode.getState() == RegionState.State.MERGED;
313+
}
301314
}

hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/RegionInTransitionTracker.java

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@ public class RegionInTransitionTracker {
4141

4242
private final List<RegionState.State> ENABLE_TABLE_REGION_STATE = List.of(RegionState.State.OPEN);
4343

44-
// DO NOT USE containsKey() on regionInTransition map as MutableRegionInfo.COMPARATOR considers
45-
// offline/split flags.
44+
// DO NOT USE containsKey()/remove() on regionInTransition with a different RegionInfo instance:
45+
// this map is ordered by RegionInfo.COMPARATOR, and that comparator includes the offline flag.
46+
// Lookups can therefore fail if the RegionInfo used as the key has a different offline value,
47+
// even when it refers to the same region. Offline value changes with splitting.
4648
private final ConcurrentSkipListMap<RegionInfo, RegionStateNode> regionInTransition =
4749
new ConcurrentSkipListMap<>(RegionInfo.COMPARATOR);
4850

@@ -54,7 +56,7 @@ public class RegionInTransitionTracker {
5456
* other servers.
5557
*/
5658
public void regionCrashed(RegionStateNode regionStateNode) {
57-
if (isReplica(regionStateNode) || isSplitOrMerged(regionStateNode)) {
59+
if (isReplica(regionStateNode)) {
5860
return;
5961
}
6062

@@ -84,7 +86,7 @@ public void handleRegionStateNodeOperation(RegionStateNode regionStateNode) {
8486
tableEnabled ? ENABLE_TABLE_REGION_STATE : DISABLE_TABLE_REGION_STATE;
8587

8688
// if region is merged or split it should not be in RIT list
87-
if (isSplitOrMerged(regionStateNode)) {
89+
if (AssignmentManagerUtil.isSplitOrMerged(regionStateNode)) {
8890
if (removeRegionInTransition(regionStateNode.getRegionInfo())) {
8991
LOG.debug("Removed {} from RIT list as it is split or merged",
9092
regionStateNode.getRegionInfo().getEncodedName());
@@ -102,12 +104,6 @@ public void handleRegionStateNodeOperation(RegionStateNode regionStateNode) {
102104
}
103105
}
104106

105-
private static boolean isSplitOrMerged(RegionStateNode regionStateNode) {
106-
return regionStateNode.getState() == RegionState.State.SPLIT
107-
|| regionStateNode.getState() == RegionState.State.MERGED
108-
|| regionStateNode.getRegionInfo().isSplit();
109-
}
110-
111107
private boolean isTableEnabled(TableName tableName) {
112108
if (tableStateManager != null) {
113109
return tableStateManager.isTableState(tableName, TableState.State.ENABLED,

hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestRegionSplit.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import static org.junit.jupiter.api.Assertions.assertEquals;
2222
import static org.junit.jupiter.api.Assertions.assertFalse;
2323
import static org.junit.jupiter.api.Assertions.assertNotNull;
24+
import static org.junit.jupiter.api.Assertions.assertTrue;
2425

2526
import java.util.List;
2627
import java.util.Map;
@@ -168,8 +169,8 @@ public void testRITWithSplitTableRegion() throws Exception {
168169

169170
assertNotNull(regions, "not able to find a splittable region");
170171
assertEquals(1, regions.length, "not able to find a splittable region");
171-
assertEquals(0,
172-
UTIL.getHBaseCluster().getMaster().getAssignmentManager().getRegionsInTransitionCount());
172+
assertFalse(AssignmentTestingUtil.isRegionInTransition(regions[0],
173+
UTIL.getHBaseCluster().getMaster().getAssignmentManager()));
173174

174175
ServerName targetRS = UTIL.getHBaseCluster().getMaster().getAssignmentManager()
175176
.getRegionStates().getRegionServerOfRegion(regions[0]);
@@ -181,22 +182,25 @@ public void testRITWithSplitTableRegion() throws Exception {
181182
ProcedureTestingUtility.assertProcNotFailed(procExec, procId);
182183

183184
assertEquals(2, UTIL.getHBaseCluster().getRegions(tableName).size(), "not able to split table");
184-
assertEquals(0,
185-
UTIL.getHBaseCluster().getMaster().getAssignmentManager().getRegionsInTransitionCount());
185+
assertFalse(AssignmentTestingUtil.isRegionInTransition(regions[0],
186+
UTIL.getHBaseCluster().getMaster().getAssignmentManager()));
186187
// As there are only 3 RS, start one more RS before expiring one
187188
UTIL.getHBaseCluster().startRegionServer();
188189

189-
// stop RS holding split parent
190+
// We don't want SCP to complete so kill PR it after store update
191+
ProcedureTestingUtility
192+
.toggleKillAfterStoreUpdate(UTIL.getHBaseCluster().getMaster().getMasterProcedureExecutor());
193+
// stop RS holding split parent to create SCP and add RS into deadServerList
190194
UTIL.getHBaseCluster().getMaster().getServerManager().expireServer(targetRS);
191195

192196
// stop master
193197
UTIL.getHBaseCluster().stopMaster(0);
194198
UTIL.getHBaseCluster().waitOnMaster(0);
195-
Thread.sleep(500);
196199

197200
// restart master
198-
JVMClusterUtil.MasterThread t = UTIL.getHBaseCluster().startMaster();
199-
UTIL.getHBaseCluster().waitForActiveAndReadyMaster(10000);
201+
UTIL.getHBaseCluster().startMaster();
202+
assertTrue(UTIL.getHBaseCluster().waitForActiveAndReadyMaster(30000),
203+
"Master failed to initialize in in 30 seconds");
200204
UTIL.invalidateConnection();
201205

202206
assertFalse(AssignmentTestingUtil.isRegionInTransition(regions[0],

0 commit comments

Comments
 (0)