diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java index b17561a..ab70eb9 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java @@ -1191,6 +1191,7 @@ public class AssignmentManager { RegionPlan randomPlan = null; boolean newPlan = false; + boolean needNewPlan = false; RegionPlan existingPlan; synchronized (this.regionPlans) { @@ -1206,19 +1207,40 @@ public class AssignmentManager { || existingPlan == null || existingPlan.getDestination() == null || !destServers.contains(existingPlan.getDestination())) { - newPlan = true; - randomPlan = new RegionPlan(region, null, - balancer.randomAssignment(region, destServers)); - if (!region.isMetaTable() && shouldAssignRegionsWithFavoredNodes) { - List regions = new ArrayList(1); - regions.add(region); - try { - processFavoredNodes(regions); - } catch (IOException ie) { - LOG.warn("Ignoring exception in processFavoredNodes " + ie); + needNewPlan = true; + } + } + if (needNewPlan) { + // obtain lock on RegionStates first to avoid deadlock + // see HBASE- + synchronized (getRegionStates()) { + synchronized (this.regionPlans) { + existingPlan = this.regionPlans.get(encodedName); + + if (existingPlan != null && existingPlan.getDestination() != null) { + LOG.debug("Found an existing plan for " + region.getRegionNameAsString() + + " destination server is " + existingPlan.getDestination() + + " accepted as a dest server = " +destServers.contains(existingPlan.getDestination())); + } + if (forceNewPlan + || existingPlan == null + || existingPlan.getDestination() == null + || !destServers.contains(existingPlan.getDestination())) { + newPlan = true; + randomPlan = new RegionPlan(region, null, + balancer.randomAssignment(region, destServers)); + if (!region.isMetaTable() && shouldAssignRegionsWithFavoredNodes) { + List regions = new ArrayList(1); + regions.add(region); + try { + processFavoredNodes(regions); + } catch (IOException ie) { + LOG.warn("Ignoring exception in processFavoredNodes " + ie); + } + } + this.regionPlans.put(encodedName, randomPlan); } } - this.regionPlans.put(encodedName, randomPlan); } }