diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java
index 40db1c1ac044..f4fd14a12429 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java
@@ -903,7 +903,7 @@ default boolean normalize() throws IOException {
/**
* Ask for a scan of the catalog table.
*
- * @return the number of entries cleaned
+ * @return the number of entries cleaned. Returns -1 if previous run is in progress.
* @throws IOException if a remote or network exception occurs
*/
int runCatalogJanitor() throws IOException;
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/CatalogJanitor.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/CatalogJanitor.java
index 9e9a00fe0027..b860d643c7a3 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/CatalogJanitor.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/CatalogJanitor.java
@@ -162,6 +162,7 @@ private static boolean isRIT(AssignmentManager am) {
* Run janitorial scan of catalog hbase:meta
table looking for
* garbage to collect.
* @return How many items gc'd whether for merge or split.
+ * Returns -1 if previous scan is in progress.
*/
@VisibleForTesting
public int scan() throws IOException {
@@ -169,7 +170,8 @@ public int scan() throws IOException {
try {
if (!alreadyRunning.compareAndSet(false, true)) {
LOG.debug("CatalogJanitor already running");
- return gcs;
+ // -1 indicates previous scan is in progress
+ return -1;
}
this.lastReport = scanForReport();
if (!this.lastReport.isEmpty()) {
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestCatalogJanitor.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestCatalogJanitor.java
index 2e668f3389f6..695b8b904513 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestCatalogJanitor.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestCatalogJanitor.java
@@ -25,6 +25,8 @@
import static org.mockito.Mockito.spy;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import java.util.NavigableMap;
import java.util.Objects;
@@ -551,6 +553,29 @@ public void testDuplicateHFileResolution() throws Exception {
assertArchiveEqualToOriginal(storeFiles, archivedStoreFiles, fs, true);
}
+ @Test
+ public void testAlreadyRunningStatus() throws Exception {
+ int numberOfThreads = 2;
+ List gcValues = new ArrayList<>();
+ Thread[] threads = new Thread[numberOfThreads];
+ for (int i = 0; i < numberOfThreads; i++) {
+ threads[i] = new Thread(() -> {
+ try {
+ gcValues.add(janitor.scan());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ }
+ for (int i = 0; i < numberOfThreads; i++) {
+ threads[i].start();
+ }
+ for (int i = 0; i < numberOfThreads; i++) {
+ threads[i].join();
+ }
+ assertTrue("One janitor.scan() call should have returned -1", gcValues.contains(-1));
+ }
+
private FileStatus[] addMockStoreFiles(int count, MasterServices services, Path storedir)
throws IOException {
// get the existing store files