diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java index ab62a08b28c..2beac775897 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java @@ -2160,6 +2160,11 @@ Server { this.activeMasterManager.clusterHasActiveMaster.notifyAll(); } } + // If no region server is online then master may stuck waiting on .META. to come on line. + // See HBASE-8422. + if (this.catalogTracker != null && this.serverManager.getOnlineServers().isEmpty()) { + this.catalogTracker.stop(); + } } @Override diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterShutdown.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterShutdown.java index 32d7e0d472e..0731eefacfa 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterShutdown.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterShutdown.java @@ -92,5 +92,46 @@ public class TestMasterShutdown { TEST_UTIL.shutdownMiniCluster(); } + @Test(timeout = 180000) + public void testMasterShutdownBeforeStartingAnyRegionServer() throws Exception { + + final int NUM_MASTERS = 1; + final int NUM_RS = 0; + + // Create config to use for this cluster + Configuration conf = HBaseConfiguration.create(); + + // Start the cluster + final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(conf); + TEST_UTIL.startMiniDFSCluster(3); + TEST_UTIL.startMiniZKCluster(); + TEST_UTIL.createRootDir(); + final LocalHBaseCluster cluster = + new LocalHBaseCluster(conf, NUM_MASTERS, NUM_RS, HMaster.class, + MiniHBaseCluster.MiniHBaseClusterRegionServer.class); + final MasterThread master = cluster.getMasters().get(0); + master.start(); + Thread shutdownThread = new Thread() { + public void run() { + try { + TEST_UTIL.getHBaseAdmin().shutdown(); + cluster.waitOnMaster(0); + } catch (Exception e) { + } + }; + }; + shutdownThread.start(); + master.join(); + shutdownThread.join(); + + List masterThreads = cluster.getMasters(); + // make sure all the masters properly shutdown + assertEquals(0, masterThreads.size()); + + TEST_UTIL.shutdownMiniZKCluster(); + TEST_UTIL.shutdownMiniDFSCluster(); + TEST_UTIL.cleanupTestDir(); + } + }