Index: hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java (revision 1552491) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java (working copy) @@ -1864,12 +1864,9 @@ } else { if (region.isMetaRegion()) { try { - if (i != maximumAttempts) { - Thread.sleep(this.sleepTimeBeforeRetryingMetaAssignment); - continue; - } - // TODO : Ensure HBCK fixes this - LOG.error("Unable to determine a plan to assign hbase:meta even after repeated attempts. Run HBCK to fix this"); + Thread.sleep(this.sleepTimeBeforeRetryingMetaAssignment); + if (i == maximumAttempts) i = 1; + continue; } catch (InterruptedException e) { LOG.error("Got exception while waiting for hbase:meta assignment"); Thread.currentThread().interrupt(); Index: hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java (revision 1552491) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java (working copy) @@ -411,11 +411,7 @@ // get regions according to what is online on each RegionServer loadDeployedRegions(); // check whether hbase:meta is deployed and online - if (!recordMetaRegion()) { - // Will remove later if we can fix it - errors.reportError("Fatal error: unable to get hbase:meta region location. Exiting..."); - return -2; - } + recordMetaRegion(); // Check if hbase:meta is found only once and in the right place if (!checkMetaRegion()) { String errorMsg = "hbase:meta table is not consistent. "; @@ -2577,8 +2573,12 @@ // There will be always one entry in regionInfoMap corresponding to hbase:meta // Check the deployed servers. It should be exactly one server. - HbckInfo metaHbckInfo = metaRegions.get(0); - List servers = metaHbckInfo.deployedOn; + List servers = new ArrayList(); + HbckInfo metaHbckInfo = null; + if (!metaRegions.isEmpty()) { + metaHbckInfo = metaRegions.get(0); + servers = metaHbckInfo.deployedOn; + } if (servers.size() != 1) { if (servers.size() == 0) { errors.reportError(ERROR_CODE.NO_META_REGION, "hbase:meta is not found on any region."); @@ -2586,8 +2586,8 @@ errors.print("Trying to fix a problem with hbase:meta.."); setShouldRerun(); // try to fix it (treat it as unassigned region) - HBaseFsckRepair.fixUnassigned(admin, metaHbckInfo.metaEntry); - HBaseFsckRepair.waitUntilAssigned(admin, metaHbckInfo.metaEntry); + HBaseFsckRepair.fixUnassigned(admin, HRegionInfo.FIRST_META_REGIONINFO); + HBaseFsckRepair.waitUntilAssigned(admin, HRegionInfo.FIRST_META_REGIONINFO); } } else if (servers.size() > 1) { errors Index: hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java =================================================================== --- hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java (revision 1552491) +++ hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java (working copy) @@ -93,6 +93,7 @@ import org.apache.hadoop.hbase.util.HBaseFsck.TableInfo; import org.apache.hadoop.hbase.util.hbck.HFileCorruptionChecker; import org.apache.hadoop.hbase.util.hbck.HbckTestingUtil; +import org.apache.hadoop.hbase.zookeeper.MetaRegionTracker; import org.apache.zookeeper.KeeperException; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -210,6 +211,28 @@ meta.close(); } + @Test(timeout=180000) + public void testFixAssignmentsWhenMETAinTransition() throws Exception { + MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster(); + HBaseAdmin admin = null; + try { + admin = new HBaseAdmin(TEST_UTIL.getConfiguration()); + admin.closeRegion(cluster.getServerHoldingMeta(), + HRegionInfo.FIRST_META_REGIONINFO); + } finally { + if (admin != null) { + admin.close(); + } + } + regionStates.regionOffline(HRegionInfo.FIRST_META_REGIONINFO); + MetaRegionTracker.deleteMetaLocation(cluster.getMaster().getZooKeeper()); + assertFalse(regionStates.isRegionOnline(HRegionInfo.FIRST_META_REGIONINFO)); + HBaseFsck hbck = doFsck(conf, true); + assertErrors(hbck, new ERROR_CODE[] { ERROR_CODE.UNKNOWN, ERROR_CODE.NO_META_REGION, + ERROR_CODE.NULL_META_REGION }); + assertNoErrors(doFsck(conf, false)); + } + /** * Create a new region in META. */