Index: src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java (revision 1339966) +++ src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java (working copy) @@ -582,8 +582,10 @@ // So we will assign the ROOT and .META. region immediately. processOpeningState(regionInfo); break; - - } + } else if (wasOnDeadServer(sn, deadServers)){ + processOpeningState(regionInfo); + break; + } regionsInTransition.put(encodedRegionName, getRegionState(regionInfo, RegionState.State.OPENING, rt)); failoverProcessedRegions.put(encodedRegionName, regionInfo); @@ -621,6 +623,14 @@ } } + private boolean wasOnDeadServer(ServerName sn, + Map>> deadServers) { + if (deadServers.keySet().contains(sn)) { + return true; + } + return false; + } + /** * Put the region hri into an offline state up in zk. Index: src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java =================================================================== --- src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java (revision 1339966) +++ src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManager.java (working copy) @@ -469,6 +469,7 @@ am.regionsInTransition.isEmpty()); } } finally { + am.setEnabledTable(REGIONINFO.getTableNameAsString()); executor.shutdown(); am.shutdown(); // Clean up all znodes @@ -606,6 +607,35 @@ } /** + * Test the scenario when the master is in failover and trying to process a + * region which is in Opening state on a dead RS. Master should immediately + * assign the region and not wait for Timeout Monitor.(Hbase-5882). + */ + @Test + public void testRegionInOpeningStateOnDeadRSWhileMasterFailover() throws IOException, + KeeperException, ServiceException, InterruptedException { + AssignmentManagerWithExtrasForTesting am = setUpMockedAssignmentManager(this.server, + this.serverManager); + ZKAssign.createNodeOffline(this.watcher, REGIONINFO, SERVERNAME_A); + int version = ZKAssign.getVersion(this.watcher, REGIONINFO); + ZKAssign.transitionNode(this.watcher, REGIONINFO, SERVERNAME_A, EventType.M_ZK_REGION_OFFLINE, + EventType.RS_ZK_REGION_OPENING, version); + RegionTransition rt = RegionTransition.createRegionTransition(EventType.RS_ZK_REGION_OPENING, + REGIONINFO.getRegionName(), SERVERNAME_A, HConstants.EMPTY_BYTE_ARRAY); + Map>> deadServers = + new HashMap>>(); + deadServers.put(SERVERNAME_A, null); + version = ZKAssign.getVersion(this.watcher, REGIONINFO); + am.gate.set(false); + am.processRegionsInTransition(rt, REGIONINFO, deadServers, version); + // Waiting for the assignment to get completed. + while (!am.gate.get()) { + Thread.sleep(10); + } + assertTrue("The region should be assigned immediately.", null != am.regionPlans.get(REGIONINFO + .getEncodedName())); + } + /** * Creates a new ephemeral node in the SPLITTING state for the specified region. * Create it ephemeral in case regionserver dies mid-split. * @@ -740,7 +770,13 @@ while (this.gate.get()) Threads.sleep(1); super.processRegionsInTransition(rt, regionInfo, deadServers, expectedVersion); } - + + @Override + public void assign(HRegionInfo region, boolean setOfflineInZK, boolean forceNewPlan, + boolean hijack) { + super.assign(region, setOfflineInZK, forceNewPlan, hijack); + this.gate.set(true); + } /** reset the watcher */ void setWatcher(ZooKeeperWatcher watcher) { this.watcher = watcher;