diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HbckChore.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HbckChore.java index e2c4008b70c..64da15d1e88 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HbckChore.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HbckChore.java @@ -99,14 +99,26 @@ public class HbckChore extends ScheduledChore { private volatile long checkingStartTimestamp = 0; private volatile long checkingEndTimestamp = 0; + private boolean disabled = false; + public HbckChore(MasterServices master) { super("HbckChore-", master, master.getConfiguration().getInt(HBCK_CHORE_INTERVAL, DEFAULT_HBCK_CHORE_INTERVAL)); this.master = master; + int interval = + master.getConfiguration().getInt(HBCK_CHORE_INTERVAL, DEFAULT_HBCK_CHORE_INTERVAL); + if (interval <= 0) { + LOG.warn(HBCK_CHORE_INTERVAL + " is <=0 hence disabling hbck chore"); + disableChore(); + } } @Override protected synchronized void chore() { + if (isDisabled() || isRunning()) { + LOG.warn("hbckChore is either disabled or is already running. Can't run the chore"); + return; + } running = true; regionInfoMap.clear(); orphanRegionsOnRS.clear(); @@ -124,6 +136,29 @@ public class HbckChore extends ScheduledChore { running = false; } + // This function does the sanity checks of making sure the chore is not run when it is + // disabled or when it's already running. It returns whether the chore was actually run or not. + protected boolean runChore() { + if (isDisabled() || isRunning()) { + if (isDisabled()) { + LOG.warn("hbck chore is disabled! Set " + HBCK_CHORE_INTERVAL + " > 0 to enable it."); + } else { + LOG.warn("hbck chore already running. Can't run till it finishes."); + } + return false; + } + chore(); + return true; + } + + private void disableChore() { + this.disabled = true; + } + + public boolean isDisabled() { + return this.disabled; + } + private void saveCheckResultToSnapshot() { // Need synchronized here, as this "snapshot" may be access by web ui. rwLock.writeLock().lock(); diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java index 4c2b7cf1258..ed64a3b6feb 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java @@ -2342,11 +2342,7 @@ public class MasterRpcServices extends RSRpcServices rpcPreCheck("runHbckChore"); LOG.info("{} request HBCK chore to run", master.getClientIdAuditPrefix()); HbckChore hbckChore = master.getHbckChore(); - boolean ran = false; - if (!hbckChore.isRunning()) { - hbckChore.chore(); - ran = true; - } + boolean ran = hbckChore.runChore(); return RunHbckChoreResponse.newBuilder().setRan(ran).build(); } diff --git a/hbase-server/src/main/resources/hbase-webapps/master/hbck.jsp b/hbase-server/src/main/resources/hbase-webapps/master/hbck.jsp index 183740bb4e2..1da84ac815b 100644 --- a/hbase-server/src/main/resources/hbase-webapps/master/hbck.jsp +++ b/hbase-server/src/main/resources/hbase-webapps/master/hbck.jsp @@ -80,7 +80,11 @@ diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestHbckChore.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestHbckChore.java index 756e60ac29d..19bd7a5c975 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestHbckChore.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestHbckChore.java @@ -198,4 +198,22 @@ public class TestHbckChore extends TestAssignmentManagerBase { hbckChore.choreForTesting(); assertEquals(0, hbckChore.getOrphanRegionsOnFS().size()); } + + @Test + public void testChoreDisable() { + // The way to disable to chore is to set hbase.master.hbck.chore.interval <= 0 + // When the interval is > 0, the chore should run. + long lastRunTime = hbckChore.getCheckingEndTimestamp(); + hbckChore.choreForTesting(); + boolean ran = lastRunTime != hbckChore.getCheckingEndTimestamp(); + assertTrue(ran); + + // When the interval <= 0, the chore shouldn't run + master.getConfiguration().setInt("hbase.master.hbck.chore.interval", 0); + HbckChore hbckChoreWithChangedConf = new HbckChore(master); + lastRunTime = hbckChoreWithChangedConf.getCheckingEndTimestamp(); + hbckChoreWithChangedConf.choreForTesting(); + ran = lastRunTime != hbckChoreWithChangedConf.getCheckingEndTimestamp(); + assertFalse(ran); + } } \ No newline at end of file