This is an automated email from the ASF dual-hosted git repository.

andor pushed a commit to branch HBASE-29081
in repository https://gitbox.apache.org/repos/asf/hbase.git


The following commit(s) were added to refs/heads/HBASE-29081 by this push:
     new 1a0434dfa82 HBASE-29579: AssignmentManager is trying to pick up the 
other cluster's meta table after HbckChore run (#7304)
1a0434dfa82 is described below

commit 1a0434dfa825a347ce7c9ed6e26e1f28c978474e
Author: Kota-SH <shanmukhaharipr...@gmail.com>
AuthorDate: Fri Sep 19 11:39:59 2025 -0500

    HBASE-29579: AssignmentManager is trying to pick up the other cluster's 
meta table after HbckChore run (#7304)
---
 .../org/apache/hadoop/hbase/master/HMaster.java    |  7 ++++
 .../apache/hadoop/hbase/master/hbck/HbckChore.java |  3 +-
 .../hadoop/hbase/util/FSTableDescriptors.java      |  3 +-
 .../java/org/apache/hadoop/hbase/util/FSUtils.java | 19 ++++++++++
 .../hadoop/hbase/master/TestMasterMetrics.java     | 33 +++++++++++++++++
 .../hbase/master/assignment/TestHbckChore.java     | 43 ++++++++++++++++++++++
 .../hadoop/hbase/util/TestFSTableDescriptors.java  | 33 +++++++++++++++++
 7 files changed, 139 insertions(+), 2 deletions(-)

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 7a352b4c016..757699ccccb 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
@@ -3117,6 +3117,13 @@ public class HMaster extends 
HBaseServerBase<MasterRpcServices> implements Maste
               Map<String, TableDescriptor> tableDescriptorMap = 
getTableDescriptors().getAll();
               for (TableDescriptor tableDescriptor : 
tableDescriptorMap.values()) {
                 TableName tableName = tableDescriptor.getTableName();
+                if (
+                  tableName.isSystemTable() && 
tableName.getQualifierAsString().startsWith("meta")
+                    && !tableName.equals(TableName.META_TABLE_NAME)
+                ) {
+                  LOG.info("Skipping foreign meta table {} in cluster 
metrics", tableName);
+                  continue;
+                }
                 RegionStatesCount regionStatesCount =
                   assignmentManager.getRegionStatesCount(tableName);
                 tableRegionStatesCountMap.put(tableName, regionStatesCount);
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/hbck/HbckChore.java 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/hbck/HbckChore.java
index 75df2da5a71..34dc1ea81e2 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/hbck/HbckChore.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/hbck/HbckChore.java
@@ -261,7 +261,8 @@ public class HbckChore extends ScheduledChore {
     FileSystem fs = master.getMasterFileSystem().getFileSystem();
 
     int numRegions = 0;
-    List<Path> tableDirs = FSUtils.getTableDirs(fs, rootDir);
+    List<Path> tableDirs =
+      FSUtils.getTableDirs(fs, 
rootDir).stream().filter(FSUtils::isLocalMetaTable).toList();
     for (Path tableDir : tableDirs) {
       List<Path> regionDirs = FSUtils.getRegionDirs(fs, tableDir);
       for (Path regionDir : regionDirs) {
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSTableDescriptors.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSTableDescriptors.java
index b32fad50f0f..f34991279d2 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSTableDescriptors.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSTableDescriptors.java
@@ -270,7 +270,8 @@ public class FSTableDescriptors implements TableDescriptors 
{
       LOG.info("Fetching table descriptors from the filesystem.");
       final long startTime = EnvironmentEdgeManager.currentTime();
       AtomicBoolean allvisited = new AtomicBoolean(usecache);
-      List<Path> tableDirs = FSUtils.getTableDirs(fs, rootdir);
+      List<Path> tableDirs =
+        FSUtils.getTableDirs(fs, 
rootdir).stream().filter(FSUtils::isLocalMetaTable).toList();
       if (!tableDescriptorParallelLoadEnable) {
         for (Path dir : tableDirs) {
           internalGet(dir, tds, allvisited);
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSUtils.java 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSUtils.java
index 98e1afc4d97..06ea8a9d52b 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSUtils.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSUtils.java
@@ -1046,6 +1046,25 @@ public final class FSUtils {
     return tabledirs;
   }
 
+  /**
+   * A filter to exclude meta tables belonging to foreign clusters. This is 
essential in a
+   * read-replica setup where multiple clusters share the same fs.
+   * @param tablePath The Path to the table directory.
+   * @return {@code true} if the path is a regular table or the cluster's own 
meta table.
+   *         {@code false} if it is a meta table belonging to a different 
cluster.
+   */
+  public static boolean isLocalMetaTable(Path tablePath) {
+    if (tablePath == null) {
+      return false;
+    }
+    String dirName = tablePath.getName();
+    if (dirName.startsWith(TableName.META_TABLE_NAME.getQualifierAsString())) {
+      return 
TableName.valueOf(TableName.META_TABLE_NAME.getNamespaceAsString(), dirName)
+        .equals(TableName.META_TABLE_NAME);
+    }
+    return true;
+  }
+
   /**
    * Filter for all dirs that don't start with '.'
    */
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterMetrics.java
 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterMetrics.java
index 09618b3d899..07dacf6f35c 100644
--- 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterMetrics.java
+++ 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterMetrics.java
@@ -17,10 +17,16 @@
  */
 package org.apache.hadoop.hbase.master;
 
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
 import java.io.IOException;
 import java.io.UncheckedIOException;
+import java.util.EnumSet;
 import java.util.HashMap;
+import java.util.Map;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.ClusterMetrics;
 import org.apache.hadoop.hbase.CompatibilityFactory;
 import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
@@ -28,7 +34,12 @@ import org.apache.hadoop.hbase.ServerMetricsBuilder;
 import org.apache.hadoop.hbase.ServerName;
 import org.apache.hadoop.hbase.SingleProcessHBaseCluster;
 import org.apache.hadoop.hbase.StartTestingClusterOption;
+import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.YouAreDeadException;
+import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
+import org.apache.hadoop.hbase.client.RegionStatesCount;
+import org.apache.hadoop.hbase.client.TableDescriptor;
+import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
 import org.apache.hadoop.hbase.test.MetricsAssertHelper;
 import org.apache.hadoop.hbase.testclassification.MasterTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
@@ -192,4 +203,26 @@ public class TestMasterMetrics {
     MetricsMasterProcSource masterSource = 
master.getMasterMetrics().getMetricsProcSource();
     metricsHelper.assertGauge("numMasterWALs", master.getNumWALFiles(), 
masterSource);
   }
+
+  @Test
+  public void testClusterMetricsMetaTableSkipping() throws Exception {
+    TableName replicaMetaTable = TableName.valueOf("hbase", "meta_replica");
+    TableDescriptor replicaMetaDescriptor = 
TableDescriptorBuilder.newBuilder(replicaMetaTable)
+      .setColumnFamily(ColumnFamilyDescriptorBuilder.of("info")).build();
+    master.getTableDescriptors().update(replicaMetaDescriptor, true);
+    try {
+      ClusterMetrics metrics = master.getClusterMetricsWithoutCoprocessor(
+        EnumSet.of(ClusterMetrics.Option.TABLE_TO_REGIONS_COUNT));
+      Map<TableName, RegionStatesCount> tableRegionStatesCount =
+        metrics.getTableRegionStatesCount();
+
+      assertFalse("Foreign meta table should not be present",
+        tableRegionStatesCount.containsKey(replicaMetaTable));
+      assertTrue("Local meta should be present",
+        tableRegionStatesCount.containsKey(TableName.META_TABLE_NAME));
+
+    } finally {
+      master.getTableDescriptors().remove(replicaMetaTable);
+    }
+  }
 }
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 70afeae4c6e..4282f4e38f2 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
@@ -31,20 +31,28 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.Future;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hbase.HBaseClassTestRule;
+import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.ServerName;
 import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
 import org.apache.hadoop.hbase.client.RegionInfo;
 import org.apache.hadoop.hbase.client.RegionInfoBuilder;
+import org.apache.hadoop.hbase.client.TableDescriptor;
+import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
 import org.apache.hadoop.hbase.client.TableState;
 import org.apache.hadoop.hbase.master.TableStateManager;
 import org.apache.hadoop.hbase.master.hbck.HbckChore;
 import org.apache.hadoop.hbase.master.hbck.HbckReport;
+import org.apache.hadoop.hbase.regionserver.BloomType;
 import org.apache.hadoop.hbase.regionserver.HRegion;
 import org.apache.hadoop.hbase.testclassification.MasterTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.CommonFSUtils;
+import org.apache.hadoop.hbase.util.FSTableDescriptors;
 import org.apache.hadoop.hbase.util.FSUtils;
 import org.apache.hadoop.hbase.util.Pair;
 import org.junit.Before;
@@ -247,4 +255,39 @@ public class TestHbckChore extends 
TestAssignmentManagerBase {
     hbckChoreWithChangedConf.choreForTesting();
     assertNull(hbckChoreWithChangedConf.getLastReport());
   }
+
+  @Test
+  public void testChoreSkipsForeignMetaTables() throws Exception {
+    FileSystem fs = master.getMasterFileSystem().getFileSystem();
+    Path rootDir = master.getMasterFileSystem().getRootDir();
+    String[] metaTables = { "meta_replica1", "meta" };
+    Path hbaseNamespaceDir = new Path(rootDir, HConstants.BASE_NAMESPACE_DIR + 
"/hbase");
+    fs.mkdirs(hbaseNamespaceDir);
+
+    for (String metaTable : metaTables) {
+      TableName tableName = TableName.valueOf("hbase", metaTable);
+      Path metaTableDir = new Path(hbaseNamespaceDir, metaTable);
+      fs.mkdirs(metaTableDir);
+      fs.mkdirs(new Path(metaTableDir, FSTableDescriptors.TABLEINFO_DIR));
+      fs.mkdirs(new Path(metaTableDir, "abcdef0123456789"));
+
+      TableDescriptor tableDescriptor = 
TableDescriptorBuilder.newBuilder(tableName)
+        
.setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(HConstants.CATALOG_FAMILY)
+          
.setMaxVersions(HConstants.DEFAULT_HBASE_META_VERSIONS).setInMemory(true)
+          .setBlocksize(HConstants.DEFAULT_HBASE_META_BLOCK_SIZE)
+          .setBloomFilterType(BloomType.ROWCOL).build())
+        .build();
+
+      Path tableDir = CommonFSUtils.getTableDir(rootDir, tableName);
+      FSTableDescriptors.createTableDescriptorForTableDirectory(fs, tableDir, 
tableDescriptor,
+        false);
+    }
+
+    assertTrue("HbckChore should run successfully", hbckChore.runChore());
+    HbckReport report = hbckChore.getLastReport();
+    assertNotNull("HbckReport should not be null", report);
+    boolean hasForeignMetaOrphan = 
report.getOrphanRegionsOnFS().values().stream()
+      .anyMatch(path -> path.toString().contains("meta_replica1"));
+    assertFalse("HbckChore should not report foreign meta tables as orphans", 
hasForeignMetaOrphan);
+  }
 }
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestFSTableDescriptors.java
 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestFSTableDescriptors.java
index 5e2b4b52950..6cf83fba8a0 100644
--- 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestFSTableDescriptors.java
+++ 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestFSTableDescriptors.java
@@ -41,6 +41,7 @@ import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
 import org.apache.hadoop.hbase.client.TableDescriptor;
 import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
+import org.apache.hadoop.hbase.regionserver.BloomType;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.testclassification.MiscTests;
 import org.junit.AfterClass;
@@ -483,6 +484,38 @@ public class TestFSTableDescriptors {
     assertFalse(fs.exists(brokenFile));
   }
 
+  @Test
+  public void testFSTableDescriptorsSkipsForeignMetaTables() throws Exception {
+    FileSystem fs = FileSystem.get(UTIL.getConfiguration());
+    String[] metaTables = { "meta_replica1", "meta" };
+    Path hbaseNamespaceDir = new Path(testDir, HConstants.BASE_NAMESPACE_DIR + 
"/hbase");
+    fs.mkdirs(hbaseNamespaceDir);
+
+    for (String metaTable : metaTables) {
+      TableName tableName = TableName.valueOf("hbase", metaTable);
+      Path metaTableDir = new Path(hbaseNamespaceDir, metaTable);
+      fs.mkdirs(metaTableDir);
+      fs.mkdirs(new Path(metaTableDir, FSTableDescriptors.TABLEINFO_DIR));
+      fs.mkdirs(new Path(metaTableDir, "abcdef0123456789"));
+
+      TableDescriptor tableDescriptor = 
TableDescriptorBuilder.newBuilder(tableName)
+        
.setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(HConstants.CATALOG_FAMILY)
+          
.setMaxVersions(HConstants.DEFAULT_HBASE_META_VERSIONS).setInMemory(true)
+          .setBlocksize(HConstants.DEFAULT_HBASE_META_BLOCK_SIZE)
+          .setBloomFilterType(BloomType.ROWCOL).build())
+        .build();
+
+      Path tableDir = CommonFSUtils.getTableDir(testDir, tableName);
+      FSTableDescriptors.createTableDescriptorForTableDirectory(fs, tableDir, 
tableDescriptor,
+        false);
+    }
+    FSTableDescriptors tableDescriptors = new FSTableDescriptors(fs, testDir);
+    Map<String, TableDescriptor> allTables = tableDescriptors.getAll();
+
+    assertFalse("Should not contain meta_replica1", 
allTables.containsKey("hbase:meta_replica1"));
+    assertTrue("Should include the local hbase:meta", 
allTables.containsKey("hbase:meta"));
+  }
+
   private static class FSTableDescriptorsTest extends FSTableDescriptors {
 
     public FSTableDescriptorsTest(FileSystem fs, Path rootdir) {

Reply via email to