From 2d214ccc52d7fd321c4ced1960d11d719b53b4e5 Mon Sep 17 00:00:00 2001 From: Michael Stack Date: Fri, 30 Jul 2010 04:57:44 +0000 Subject: [PATCH] HBASE-2755 Duplicate assignment of a region after region server recovery git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@980649 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES.txt | 2 ++ .../hadoop/hbase/master/BaseScanner.java | 36 ++++++++++++++----- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index e21f620c68a..e8475f7aff2 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -461,6 +461,8 @@ Release 0.21.0 - Unreleased HBASE-2884 TestHFileOutputFormat flaky when map tasks generate identical data HBASE-2890 Initialize RPC JMX metrics on startup (Gary Helmling via Stack) + HBASE-2755 Duplicate assignment of a region after region server recovery + (Kannan Muthukkaruppan via Stack) IMPROVEMENTS HBASE-1760 Cleanup TODOs in HTable diff --git a/src/main/java/org/apache/hadoop/hbase/master/BaseScanner.java b/src/main/java/org/apache/hadoop/hbase/master/BaseScanner.java index 29abe356438..69eab39aa3d 100644 --- a/src/main/java/org/apache/hadoop/hbase/master/BaseScanner.java +++ b/src/main/java/org/apache/hadoop/hbase/master/BaseScanner.java @@ -194,7 +194,7 @@ abstract class BaseScanner extends Chore { long startCode = getStartCode(values); // Note Region has been assigned. - checkAssigned(regionServer, region, info, serverAddress, startCode); + checkAssigned(regionServer, region, info, serverAddress, startCode, true); if (isSplitParent(info)) { splitParents.put(info, values); } @@ -533,12 +533,15 @@ abstract class BaseScanner extends Chore { * @param info * @param hostnameAndPort hostname ':' port as it comes out of .META. * @param startCode + * @param checkTwice should we check twice before adding a region + * to unassigned pool. * @throws IOException */ protected void checkAssigned(final HRegionInterface regionServer, final MetaRegion meta, final HRegionInfo info, - final String hostnameAndPort, final long startCode) + final String hostnameAndPort, final long startCode, boolean checkTwice) throws IOException { + boolean tryAgain = false; String serverName = null; String sa = hostnameAndPort; long sc = startCode; @@ -575,16 +578,31 @@ abstract class BaseScanner extends Chore { // If we can't find the HServerInfo, then add it to the list of // unassigned regions. if (storedInfo == null) { - // The current assignment is invalid - if (LOG.isDebugEnabled()) { - LOG.debug("Current assignment of " + info.getRegionNameAsString() + - " is not valid; " + " serverAddress=" + sa + - ", startCode=" + sc + " unknown."); + if (checkTwice) { + tryAgain = true; + } else { + if (LOG.isDebugEnabled()) { + LOG.debug("Current assignment of " + info.getRegionNameAsString() + + " is not valid; " + " serverAddress=" + sa + + ", startCode=" + sc + " unknown."); + } + // Now get the region assigned + this.master.getRegionManager().setUnassigned(info, true); } - // Now get the region assigned - this.master.getRegionManager().setUnassigned(info, true); } } + if (tryAgain) { + // The current assignment is invalid. But we need to try again. + if (LOG.isDebugEnabled()) { + LOG.debug("Current assignment of " + info.getRegionNameAsString() + + " is not valid; " + " serverAddress=" + sa + + ", startCode=" + sc + " unknown; checking once more!"); + } + // passing null for hostNameAndPort will force the function + // to reget the assignment from META and protect against + // double assignment race conditions (HBASE-2755). + checkAssigned(regionServer, meta, info, null, 0, false); + } } /**