diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/RegionStates.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/RegionStates.java index 5b81e0d..d1fffbe 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/RegionStates.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/RegionStates.java @@ -576,14 +576,16 @@ public class RegionStates { // Offline all regions on this server not already in transition. List rits = new ArrayList(); Set regionsToCleanIfNoMetaEntry = new HashSet(); + // Offline regions outside the loop and synchronized block to avoid + // ConcurrentModificationException and deadlock in case of meta anassigned, + // but RegionState a blocked. + Set regionsToOffline = new HashSet(); synchronized (this) { Set assignedRegions = serverHoldings.get(sn); if (assignedRegions == null) { assignedRegions = new HashSet(); } - // Offline regions outside the loop to avoid ConcurrentModificationException - Set regionsToOffline = new HashSet(); for (HRegionInfo region : assignedRegions) { // Offline open regions, no need to offline if SPLIT/MERGED/OFFLINE if (isRegionOnline(region)) { @@ -620,13 +622,13 @@ public class RegionStates { } } } - - for (HRegionInfo hri : regionsToOffline) { - regionOffline(hri); - } - this.notifyAll(); } + + for (HRegionInfo hri : regionsToOffline) { + regionOffline(hri); + } + cleanIfNoMetaEntry(regionsToCleanIfNoMetaEntry); return rits; }