Index: src/main/java/org/apache/hadoop/hbase/executor/EventHandler.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/executor/EventHandler.java (revision 1204339) +++ src/main/java/org/apache/hadoop/hbase/executor/EventHandler.java (working copy) @@ -103,7 +103,7 @@ public enum EventType { // Messages originating from RS (NOTE: there is NO direct communication from // RS to Master). These are a result of RS updates into ZK. - RS_ZK_REGION_CLOSING (1), // RS is in process of closing a region + RS_ZK_REGION_CLOSING (1), // Master adds this region as closing in ZK RS_ZK_REGION_CLOSED (2), // RS has finished closing a region RS_ZK_REGION_OPENING (3), // RS is in process of opening a region RS_ZK_REGION_OPENED (4), // RS has finished opening a region Index: src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java (revision 1204339) +++ src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java (working copy) @@ -1751,13 +1751,13 @@ } state = new RegionState(region, RegionState.State.PENDING_CLOSE); regionsInTransition.put(encodedName, state); - } else if (force && state.isPendingClose()) { - // JD 05/25/11 - // in my experience this is useless, when this happens it just spins - debugLog(region, "Attempting to unassign region " + - region.getRegionNameAsString() + " which is already pending close " - + "but forcing an additional close"); - state.update(RegionState.State.PENDING_CLOSE); + } else if (force && (state.isPendingClose() || state.isClosing())) { + debugLog(region, + "Attempting to unassign region " + region.getRegionNameAsString() + + " which is already " + + (state.isPendingClose() ? "pending close " : "closing ") + + "but forcing to send a CLOSE RPC again "); + state.update(state.getState()); } else { debugLog(region, "Attempting to unassign region " + region.getRegionNameAsString() + " but it is " + @@ -2527,26 +2527,13 @@ LOG.info("Region has been PENDING_CLOSE for too " + "long, running forced unassign again on region=" + regionInfo.getRegionNameAsString()); - try { - // If the server got the RPC, it will transition the node - // to CLOSING, so only do something here if no node exists - if (!ZKUtil.watchAndCheckExists(watcher, - ZKAssign.getNodeName(watcher, regionInfo.getEncodedName()))) { - // Queue running of an unassign -- do actual unassign - // outside of the regionsInTransition lock. - invokeUnassign(regionInfo); - } - } catch (NoNodeException e) { - LOG.debug("Node no longer existed so not forcing another " - + "unassignment"); - } catch (KeeperException e) { - LOG.warn("Unexpected ZK exception timing out a region close", e); - } + invokeUnassign(regionInfo); break; case CLOSING: LOG.info("Region has been CLOSING for too " + "long, this should eventually complete or the server will " + - "expire, doing nothing"); + "expire, send RPC again"); + invokeUnassign(regionInfo); break; } } Index: src/main/java/org/apache/hadoop/hbase/master/UnAssignCallable.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/master/UnAssignCallable.java (revision 1204339) +++ src/main/java/org/apache/hadoop/hbase/master/UnAssignCallable.java (working copy) @@ -40,7 +40,7 @@ @Override public Object call() throws Exception { - assignmentManager.unassign(hri); + assignmentManager.unassign(hri, true); return null; } } Index: src/test/java/org/apache/hadoop/hbase/master/TestMasterFailover.java =================================================================== --- src/test/java/org/apache/hadoop/hbase/master/TestMasterFailover.java (revision 1204339) +++ src/test/java/org/apache/hadoop/hbase/master/TestMasterFailover.java (working copy) @@ -378,11 +378,13 @@ // Let's just assign everything to first RS HRegionServer hrs = cluster.getRegionServer(0); ServerName serverName = hrs.getServerName(); - + HRegionInfo closingRegion = enabledRegions.remove(0); // we'll need some regions to already be assigned out properly on live RS List enabledAndAssignedRegions = new ArrayList(); enabledAndAssignedRegions.add(enabledRegions.remove(0)); enabledAndAssignedRegions.add(enabledRegions.remove(0)); + enabledAndAssignedRegions.add(closingRegion); + List disabledAndAssignedRegions = new ArrayList(); disabledAndAssignedRegions.add(disabledRegions.remove(0)); disabledAndAssignedRegions.add(disabledRegions.remove(0)); @@ -436,24 +438,9 @@ /* * ZK = CLOSING */ + regionsThatShouldBeOnline.add(closingRegion); + ZKAssign.createNodeClosing(zkw, closingRegion, serverName); -// Disabled test of CLOSING. This case is invalid after HBASE-3181. -// How can an RS stop a CLOSING w/o deleting the node? If it did ever fail -// and left the node in CLOSING, the RS would have aborted and we'd process -// these regions in server shutdown -// -// // Region of enabled table being closed but not complete -// // Region is already assigned, don't say anything to RS but set ZK closing -// region = enabledAndAssignedRegions.remove(0); -// regionsThatShouldBeOnline.add(region); -// ZKAssign.createNodeClosing(zkw, region, serverName); -// -// // Region of disabled table being closed but not complete -// // Region is already assigned, don't say anything to RS but set ZK closing -// region = disabledAndAssignedRegions.remove(0); -// regionsThatShouldBeOffline.add(region); -// ZKAssign.createNodeClosing(zkw, region, serverName); - /* * ZK = CLOSED */