Index: src/java/org/apache/hadoop/hbase/master/RegionManager.java =================================================================== --- src/java/org/apache/hadoop/hbase/master/RegionManager.java (revision 919661) +++ src/java/org/apache/hadoop/hbase/master/RegionManager.java (working copy) @@ -333,10 +333,13 @@ */ private void doRegionAssignment(final RegionState rs, final HServerInfo sinfo, final ArrayList returnMsgs) { - String regionName = rs.getRegionInfo().getRegionNameAsString(); - LOG.info("Assigning region " + regionName + " to " + sinfo.getServerName()); - rs.setPendingOpen(sinfo.getServerName()); - this.regionsInTransition.put(regionName, rs); + synchronized (this.regionsInTransition) { + String regionName = rs.getRegionInfo().getRegionNameAsString(); + LOG.info("Assigning region " + regionName + + " to " + sinfo.getServerName()); + rs.setPendingOpen(sinfo.getServerName()); + this.regionsInTransition.put(regionName, rs); + } returnMsgs.add(new HMsg(HMsg.Type.MSG_REGION_OPEN, rs.getRegionInfo())); } @@ -390,50 +393,55 @@ boolean isMetaServer = isMetaServer(addr); - // Handle if root is unassigned... only assign root if root is offline. - RegionState rootState = regionsInTransition.get(HRegionInfo.ROOT_REGIONINFO.getRegionNameAsString()); - if (rootState != null && rootState.isUnassigned()) { - // make sure root isnt assigned here first. - // if so return 'empty list' - // by definition there is no way this could be a ROOT region (since it's - // unassigned) so just make sure it isn't hosting META regions (unless - // it's the only server left). - if (!isMetaServer || isSingleServer) { - regionsToAssign.add(rootState); + synchronized (this.regionsInTransition) { + // Handle if root is unassigned... only assign root if root is offline. + RegionState rootState = regionsInTransition.get + (HRegionInfo.ROOT_REGIONINFO.getRegionNameAsString()); + + if (rootState != null && rootState.isUnassigned()) { + // make sure root isnt assigned here first. + // if so return 'empty list' + // by definition there is no way this could be a ROOT region (since it's + // unassigned) so just make sure it isn't hosting META regions (unless + // it's the only server left). + if (!isMetaServer || isSingleServer) { + regionsToAssign.add(rootState); + } + return regionsToAssign; } - return regionsToAssign; - } - // Look over the set of regions that aren't currently assigned to - // determine which we should assign to this server. - boolean reassigningMetas = numberOfMetaRegions.get() != onlineMetaRegions.size(); - boolean isMetaOrRoot = isMetaServer || isRootServer(addr); - if (reassigningMetas && isMetaOrRoot && !isSingleServer) { - return regionsToAssign; // dont assign anything to this server. - } + // Look over the set of regions that aren't currently assigned to + // determine which we should assign to this server. + boolean reassigningMetas = + numberOfMetaRegions.get() != onlineMetaRegions.size(); + boolean isMetaOrRoot = isMetaServer || isRootServer(addr); + if (reassigningMetas && isMetaOrRoot && !isSingleServer) { + return regionsToAssign; // dont assign anything to this server. + } - for (RegionState s: regionsInTransition.values()) { - HRegionInfo i = s.getRegionInfo(); - if (i == null) { - continue; + for (RegionState s: regionsInTransition.values()) { + HRegionInfo i = s.getRegionInfo(); + if (i == null) { + continue; + } + if (reassigningMetas && + !i.isMetaRegion()) { + // Can't assign user regions until all meta regions have been assigned + // and are on-line + continue; + } + if (!i.isMetaRegion() && + !master.getServerManager().canAssignUserRegions()) { + LOG.debug("user region " + i.getRegionNameAsString() + + " is in transition but not enough servers yet"); + continue; + } + if (s.isUnassigned()) { + regionsToAssign.add(s); + } } - if (reassigningMetas && - !i.isMetaRegion()) { - // Can't assign user regions until all meta regions have been assigned - // and are on-line - continue; - } - if (!i.isMetaRegion() && - !master.getServerManager().canAssignUserRegions()) { - LOG.debug("user region " + i.getRegionNameAsString() + - " is in transition but not enough servers yet"); - continue; - } - if (s.isUnassigned()) { - regionsToAssign.add(s); - } + return regionsToAssign; } - return regionsToAssign; } /* @@ -829,13 +837,15 @@ // This might be expensive, but we need to make sure we dont // get double assignment to the same regionserver. - for (RegionState s : regionsInTransition.values()) { - if (s.getRegionInfo().isMetaRegion() - && !s.isUnassigned() - && s.getServerName() != null - && s.getServerName().equals(server.toString())) { - // Has an outstanding meta region to be assigned. - return true; + synchronized (this.regionsInTransition) { + for (RegionState s : regionsInTransition.values()) { + if (s.getRegionInfo().isMetaRegion() + && !s.isUnassigned() + && s.getServerName() != null + && s.getServerName().equals(server.toString())) { + // Has an outstanding meta region to be assigned. + return true; + } } } return false; @@ -848,13 +858,15 @@ * @return true if server is transitioning the ROOT table */ public boolean isRootServerCandidate(final String server) { - for (RegionState s : regionsInTransition.values()) { - if (s.getRegionInfo().isRootRegion() - && !s.isUnassigned() - && s.getServerName() != null - && s.getServerName().equals(server)) { - // Has an outstanding root region to be assigned. - return true; + synchronized (this.regionsInTransition) { + for (RegionState s : regionsInTransition.values()) { + if (s.getRegionInfo().isRootRegion() + && !s.isUnassigned() + && s.getServerName() != null + && s.getServerName().equals(server)) { + // Has an outstanding root region to be assigned. + return true; + } } } return false; @@ -867,13 +879,15 @@ * @return if this server was transitioning a META table then a not null HRegionInfo pointing to it */ public HRegionInfo getMetaServerRegionInfo(final String server) { - for (RegionState s : regionsInTransition.values()) { - if (s.getRegionInfo().isMetaRegion() - && !s.isUnassigned() - && s.getServerName() != null - && s.getServerName().equals(server)) { - // Has an outstanding meta region to be assigned. - return s.getRegionInfo(); + synchronized (this.regionsInTransition) { + for (RegionState s : regionsInTransition.values()) { + if (s.getRegionInfo().isMetaRegion() + && !s.isUnassigned() + && s.getServerName() != null + && s.getServerName().equals(server)) { + // Has an outstanding meta region to be assigned. + return s.getRegionInfo(); + } } } return null; @@ -922,7 +936,9 @@ * @param info */ public void removeRegion(HRegionInfo info) { - this.regionsInTransition.remove(info.getRegionNameAsString()); + synchronized (this.regionsInTransition) { + this.regionsInTransition.remove(info.getRegionNameAsString()); + } } /** @@ -930,7 +946,9 @@ * @return true if the named region is in a transition state */ public boolean regionIsInTransition(String regionName) { - return regionsInTransition.containsKey(regionName); + synchronized (this.regionsInTransition) { + return regionsInTransition.containsKey(regionName); + } } /** @@ -938,11 +956,13 @@ * @return true if the region is unassigned, pendingOpen or open */ public boolean regionIsOpening(String regionName) { - RegionState state = regionsInTransition.get(regionName); - if (state != null) { - return state.isOpening(); + synchronized (this.regionsInTransition) { + RegionState state = regionsInTransition.get(regionName); + if (state != null) { + return state.isOpening(); + } + return false; } - return false; } /** @@ -1139,13 +1159,15 @@ */ public boolean inSafeMode() { if (safeMode) { - if(isInitialMetaScanComplete() && regionsInTransition.size() == 0 && - tellZooKeeperOutOfSafeMode()) { - master.connection.unsetRootRegionLocation(); - safeMode = false; - LOG.info("exiting safe mode"); - } else { - LOG.info("in safe mode"); + synchronized (this.regionsInTransition) { + if(isInitialMetaScanComplete() && regionsInTransition.size() == 0 && + tellZooKeeperOutOfSafeMode()) { + master.connection.unsetRootRegionLocation(); + safeMode = false; + LOG.info("exiting safe mode"); + } else { + LOG.info("in safe mode"); + } } } return safeMode;