diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java index 9702837..d58c434 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java @@ -617,9 +617,14 @@ public class AssignmentManager extends ZooKeeperListener { // it in transition. Try to re-assign it, but it will fail most likely, // since we have not done log splitting for the dead server yet. LOG.debug("RIT " + encodedName + " in state=" + rt.getEventType() + - " was on deadserver; forcing offline"); + " was on deadserver; forcing offline"); ZKAssign.createOrForceNodeOffline(this.watcher, regionInfo, sn); regionStates.updateRegionState(regionInfo, State.OFFLINE, sn); + // We need to reset last assignment info for the region because + // 1) we force current RIT state to be offline which means the region isn't assigned anywhere. + // 2) Otherwise they may be skipped by regionStates.wasRegionOnDeadServer in SSH region + // assignment + regionStates.setLastRegionServerOfRegion(sn, regionInfo); invokeAssign(regionInfo); return false; } diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/master/RegionStates.java hbase-server/src/main/java/org/apache/hadoop/hbase/master/RegionStates.java index 11bddbb..819deb7 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/master/RegionStates.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/master/RegionStates.java @@ -623,9 +623,14 @@ public class RegionStates { synchronized void setLastRegionServerOfRegions( final ServerName serverName, final List regionInfos) { for (HRegionInfo hri: regionInfos) { - lastAssignments.put(hri.getEncodedName(), serverName); + setLastRegionServerOfRegion(serverName, hri); } } + + synchronized void setLastRegionServerOfRegion(final ServerName serverName, + final HRegionInfo hri) { + lastAssignments.put(hri.getEncodedName(), serverName); + } /** * Compute the average load across all region servers. diff --git hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManagerOnCluster.java hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManagerOnCluster.java index 34844ed..d9d6d7c 100644 --- hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManagerOnCluster.java +++ hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManagerOnCluster.java @@ -62,6 +62,7 @@ import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; import org.apache.hadoop.hbase.util.FSUtils; import org.apache.hadoop.hbase.zookeeper.ZKAssign; +import org.apache.hadoop.hbase.zookeeper.ZKUtil; import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.data.Stat; @@ -803,6 +804,8 @@ public class TestAssignmentManagerOnCluster { + " and dst server=" + dstName); // start HBase cluster + ZKUtil.deleteChildrenRecursively(zkw, zkw.getMasterAddressZNode()); + ZKUtil.deleteChildrenRecursively(zkw, zkw.rsZNode); TEST_UTIL.startMiniHBaseCluster(1, 4, MyMaster.class, null); // wait for the region is re-assigned.