Return-Path: X-Original-To: apmail-hbase-commits-archive@www.apache.org Delivered-To: apmail-hbase-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id D82911755A for ; Thu, 5 Feb 2015 16:43:34 +0000 (UTC) Received: (qmail 77016 invoked by uid 500); 5 Feb 2015 16:43:34 -0000 Delivered-To: apmail-hbase-commits-archive@hbase.apache.org Received: (qmail 76968 invoked by uid 500); 5 Feb 2015 16:43:34 -0000 Mailing-List: contact commits-help@hbase.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@hbase.apache.org Delivered-To: mailing list commits@hbase.apache.org Received: (qmail 76953 invoked by uid 99); 5 Feb 2015 16:43:34 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 05 Feb 2015 16:43:34 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 64E7EE028F; Thu, 5 Feb 2015 16:43:34 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: stack@apache.org To: commits@hbase.apache.org Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: hbase git commit: HBASE-12958 SSH doing hbase:meta get but hbase:meta not assigned Date: Thu, 5 Feb 2015 16:43:34 +0000 (UTC) Repository: hbase Updated Branches: refs/heads/0.98 63050b45b -> 7565a3bb1 HBASE-12958 SSH doing hbase:meta get but hbase:meta not assigned Project: http://git-wip-us.apache.org/repos/asf/hbase/repo Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/7565a3bb Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/7565a3bb Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/7565a3bb Branch: refs/heads/0.98 Commit: 7565a3bb17e288c97ec85e655dcfeef5165abbae Parents: 63050b4 Author: stack Authored: Thu Feb 5 08:43:26 2015 -0800 Committer: stack Committed: Thu Feb 5 08:43:26 2015 -0800 ---------------------------------------------------------------------- .../hadoop/hbase/master/RegionStates.java | 134 +++++++++++-------- 1 file changed, 76 insertions(+), 58 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hbase/blob/7565a3bb/hbase-server/src/main/java/org/apache/hadoop/hbase/master/RegionStates.java ---------------------------------------------------------------------- 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 68f3c18..0f91352 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 @@ -321,7 +321,7 @@ public class RegionStates { return updateRegionState(regionInfo, state, transition.getServerName()); } - + /** * Transition a region state to OPEN from OPENING/PENDING_OPEN */ @@ -477,78 +477,95 @@ public class RegionStates { /** * A server is offline, all regions on it are dead. */ - public synchronized List serverOffline( - final ZooKeeperWatcher watcher, final ServerName sn) { + public List serverOffline(final ZooKeeperWatcher watcher, final ServerName sn) { // Offline all regions on this server not already in transition. List rits = new ArrayList(); - Set assignedRegions = serverHoldings.get(sn); - if (assignedRegions == null) { - assignedRegions = new HashSet(); - } + Set regionsToCleanIfNoMetaEntry = 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)) { - regionsToOffline.add(region); - } else { - if (isRegionInState(region, State.SPLITTING, State.MERGING)) { - LOG.debug("Offline splitting/merging region " + getRegionState(region)); - try { - // Delete the ZNode if exists - ZKAssign.deleteNodeFailSilent(watcher, region); - regionsToOffline.add(region); - } catch (KeeperException ke) { - server.abort("Unexpected ZK exception deleting node " + region, ke); + // 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)) { + regionsToOffline.add(region); + } else { + if (isRegionInState(region, State.SPLITTING, State.MERGING)) { + LOG.debug("Offline splitting/merging region " + getRegionState(region)); + try { + // Delete the ZNode if exists + ZKAssign.deleteNodeFailSilent(watcher, region); + regionsToOffline.add(region); + } catch (KeeperException ke) { + server.abort("Unexpected ZK exception deleting node " + region, ke); + } } } } - } - 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 SSH 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 (state.isPendingOpenOrOpening() || state.isFailedClose() || state.isOffline()) { - LOG.info("Found region in " + state + " to be reassigned by SSH for " + sn); - rits.add(hri); - } else if(state.isSplittingNew()) { - try { - if (MetaReader.getRegion(server.getCatalogTracker(), state.getRegion().getRegionName()) == null) { - regionsToOffline.add(state.getRegion()); - FSUtils.deleteRegionDir(server.getConfiguration(), state.getRegion()); - } - } catch (IOException e) { - LOG.warn("Got exception while deleting " + state.getRegion() - + " directories from file system.", e); + 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 SSH 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 (state.isPendingOpenOrOpening() || state.isFailedClose() || state.isOffline()) { + LOG.info("Found region in " + state + " to be reassigned by SSH for " + sn); + rits.add(hri); + } else if(state.isSplittingNew()) { + regionsToCleanIfNoMetaEntry.add(state.getRegion()); + } else { + LOG.warn("THIS SHOULD NOT HAPPEN: unexpected " + state); } - } else { - LOG.warn("THIS SHOULD NOT HAPPEN: unexpected " + state); } } - } - for (HRegionInfo hri : regionsToOffline) { - regionOffline(hri); - } + for (HRegionInfo hri : regionsToOffline) { + regionOffline(hri); + } - this.notifyAll(); + this.notifyAll(); + } + cleanIfNoMetaEntry(regionsToCleanIfNoMetaEntry); return rits; } /** + * This method does an RPC to hbase:meta. Do not call this method with a lock/synchronize held. + * @param hris The hris to check if empty in hbase:meta and if so, clean them up. + */ + private void cleanIfNoMetaEntry(Set hris) { + if (hris.isEmpty()) return; + for (HRegionInfo hri: hris) { + try { + // This is RPC to meta table. It is done while we have a synchronize on + // regionstates. No progress will be made if meta is not available at this time. + // This is a cleanup task. Not critical. + if (MetaTableAccessor.getRegion(server.getConnection(), hri.getEncodedNameAsBytes()) == + null) { + regionOffline(hri); + FSUtils.deleteRegionDir(server.getConfiguration(), hri); + } + } catch (IOException e) { + LOG.warn("Got exception while deleting " + hri + " directories from file system.", e); + } + } + } + + /** * Gets the online regions of the specified table. * This method looks at the in-memory state. It does not go to hbase:meta. * Only returns online regions. If a region on this table has been @@ -774,7 +791,8 @@ public class RegionStates { } /** - * Get the HRegionInfo from cache, if not there, from the hbase:meta table + * Get the HRegionInfo from cache, if not there, from the hbase:meta table. + * Be careful. Does RPC. Do not hold a lock or synchronize when you call this method. * @param regionName * @return HRegionInfo for the region */