/** * At cluster clean re/start, mark all user regions closed except those of tables that are * excluded, such as disabled/disabling/enabling tables. All user regions and their previous * locations are returned. */ synchronized Map<HRegionInfo, ServerName> closeAllUserRegions(Set<TableName> excludedTables) { boolean noExcludeTables = excludedTables == null || excludedTables.isEmpty(); Set<HRegionInfo> toBeClosed = new HashSet<HRegionInfo>(regionStates.size()); for (RegionState state : regionStates.values()) { HRegionInfo hri = state.getRegion(); if (state.isSplit() || hri.isSplit()) { continue; } TableName tableName = hri.getTable(); if (!TableName.META_TABLE_NAME.equals(tableName) && (noExcludeTables || !excludedTables.contains(tableName))) { toBeClosed.add(hri); } } Map<HRegionInfo, ServerName> allUserRegions = new HashMap<HRegionInfo, ServerName>(toBeClosed.size()); for (HRegionInfo hri : toBeClosed) { RegionState regionState = updateRegionState(hri, State.CLOSED); allUserRegions.put(hri, regionState.getServerName()); } return allUserRegions; }
/** A server is offline, all regions on it are dead. */ public List<HRegionInfo> serverOffline(final ServerName sn) { // Offline all regions on this server not already in transition. List<HRegionInfo> rits = new ArrayList<HRegionInfo>(); Set<HRegionInfo> regionsToCleanIfNoMetaEntry = new HashSet<HRegionInfo>(); // Offline regions outside the loop and synchronized block to avoid // ConcurrentModificationException and deadlock in case of meta anassigned, // but RegionState a blocked. Set<HRegionInfo> regionsToOffline = new HashSet<HRegionInfo>(); synchronized (this) { Set<HRegionInfo> assignedRegions = serverHoldings.get(sn); if (assignedRegions == null) { assignedRegions = new HashSet<HRegionInfo>(); } for (HRegionInfo region : assignedRegions) { // Offline open regions, no need to offline if SPLIT/MERGED/OFFLINE if (isRegionOnline(region)) { regionsToOffline.add(region); } else if (isRegionInState(region, State.SPLITTING, State.MERGING)) { LOG.debug("Offline splitting/merging region " + getRegionState(region)); regionsToOffline.add(region); } } for (RegionState state : regionsInTransition.values()) { HRegionInfo hri = state.getRegion(); if (assignedRegions.contains(hri)) { // Region is open on this region server, but in transition. // This region must be moving away from this server, or splitting/merging. // SSH will handle it, either skip assigning, or re-assign. LOG.info("Transitioning " + state + " will be handled by ServerCrashProcedure for " + sn); } else if (sn.equals(state.getServerName())) { // Region is in transition on this region server, and this // region is not open on this server. So the region must be // moving to this server from another one (i.e. opening or // pending open on this server, was open on another one. // Offline state is also kind of pending open if the region is in // transition. The region could be in failed_close state too if we have // tried several times to open it while this region server is not reachable) if (isOneOfStates( state, State.OPENING, State.PENDING_OPEN, State.FAILED_OPEN, State.FAILED_CLOSE, State.OFFLINE)) { LOG.info( "Found region in " + state + " to be reassigned by ServerCrashProcedure for " + sn); rits.add(hri); } else if (isOneOfStates(state, State.SPLITTING_NEW)) { regionsToCleanIfNoMetaEntry.add(state.getRegion()); } else { LOG.warn("THIS SHOULD NOT HAPPEN: unexpected " + state); } } } this.notifyAll(); } for (HRegionInfo hri : regionsToOffline) { regionOffline(hri); } cleanIfNoMetaEntry(regionsToCleanIfNoMetaEntry); return rits; }
/** Update a region state. It will be put in transition if not already there. */ public RegionState updateRegionState(final HRegionInfo hri, final State state) { RegionState regionState = getRegionState(hri.getEncodedName()); return updateRegionState(hri, state, regionState == null ? null : regionState.getServerName()); }