From c5ab5894eba0848d0c87d907b734f833959d0fd3 Mon Sep 17 00:00:00 2001 From: Abhishek Kothalikar Date: Fri, 24 Jan 2025 12:03:50 +0530 Subject: [PATCH] HBASE-29082: Support for custom meta table name suffix --- .../org/apache/hadoop/hbase/HConstants.java | 12 ++ .../org/apache/hadoop/hbase/TableName.java | 38 +++++- .../apache/hadoop/hbase/master/HMaster.java | 2 +- .../master/procedure/InitMetaProcedure.java | 10 +- .../hadoop/hbase/TestMetaTableForReplica.java | 111 ++++++++++++++++++ 5 files changed, 168 insertions(+), 5 deletions(-) create mode 100644 hbase-server/src/test/java/org/apache/hadoop/hbase/TestMetaTableForReplica.java diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java index c882e71e877a..9adc75114df1 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java @@ -1641,6 +1641,18 @@ public enum OperationStatusCode { */ public final static boolean REJECT_DECOMMISSIONED_HOSTS_DEFAULT = false; + /** + * Adds a suffix to the meta table name: value=’test’ -> ‘hbase:meta_test’ + * Added in HBASE-XXXXX to support having multiple hbase:meta tables (with distinct names )to + * enable storage sharing by more than one clusters. + */ + public final static String HBASE_META_TABLE_SUFFIX = "hbase.meta.table.suffix"; + + /** + * Default value of {@link #HBASE_META_TABLE_SUFFIX} + */ + public final static String HBASE_META_TABLE_SUFFIX_DEFAULT_VALUE = ""; + private HConstants() { // Can't be instantiated with this ctor. } diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/TableName.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/TableName.java index 83303a1c476c..36ccb5dcd77f 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/TableName.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/TableName.java @@ -17,7 +17,10 @@ */ package org.apache.hadoop.hbase; +import com.google.errorprone.annotations.RestrictedApi; import java.nio.ByteBuffer; +import java.util.concurrent.ScheduledExecutorService; +import org.apache.hadoop.conf.Configuration; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Set; @@ -27,6 +30,8 @@ import org.apache.yetus.audience.InterfaceAudience; import org.apache.hbase.thirdparty.com.google.common.base.Preconditions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Immutable POJO class for representing a table name. Which is of the form: <table @@ -44,6 +49,8 @@ */ @InterfaceAudience.Public public final class TableName implements Comparable { + private static final Logger LOG = LoggerFactory.getLogger(TableName.class); + /** See {@link #createTableNameIfNecessary(ByteBuffer, ByteBuffer)} */ private static final Set tableCache = new CopyOnWriteArraySet<>(); @@ -65,9 +72,34 @@ public final class TableName implements Comparable { public static final String VALID_USER_TABLE_REGEX = "(?:(?:(?:" + VALID_NAMESPACE_REGEX + "\\" + NAMESPACE_DELIM + ")?)" + "(?:" + VALID_TABLE_QUALIFIER_REGEX + "))"; - /** The hbase:meta table's name. */ - public static final TableName META_TABLE_NAME = - valueOf(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR, "meta"); + /** The name of hbase meta table could either be hbase:meta_xxx or 'hbase:meta' otherwise. + * Config hbase.meta.table.suffix will govern the decision of adding suffix to the habase:meta */ + public static final TableName META_TABLE_NAME; + static { + Configuration conf = HBaseConfiguration.create(); + META_TABLE_NAME = initializeHbaseMetaTableName(conf); + } + + /* Visible for testing only */ + @RestrictedApi(explanation = "Should only be called in tests", link = "", + allowedOnPath = ".*/src/test/.*") + public static TableName getDefaultNameOfMetaForReplica() { + return valueOf(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR, "meta"); + } + + public static TableName initializeHbaseMetaTableName(Configuration conf) { + String suffix_val = String.valueOf(conf.getStrings( + HConstants.HBASE_META_TABLE_SUFFIX, HConstants.HBASE_META_TABLE_SUFFIX_DEFAULT_VALUE)); + + if (suffix_val == null || suffix_val.isEmpty()) { + LOG.info("Meta table name: {}", META_TABLE_NAME); + return TableName.META_TABLE_NAME; + } + TableName META_TABLE = valueOf(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR, + "meta_" + suffix_val);; + LOG.info("Meta table name: {}", META_TABLE); + return META_TABLE; + } /** * The Namespace table's name. 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 969c3e953134..2663f966cc52 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 @@ -1094,7 +1094,7 @@ private void finishActiveMasterInitialization() throws IOException, InterruptedE .filter(p -> p instanceof InitMetaProcedure).map(o -> (InitMetaProcedure) o).findAny(); initMetaProc = optProc.orElseGet(() -> { // schedule an init meta procedure if meta has not been deployed yet - InitMetaProcedure temp = new InitMetaProcedure(); + InitMetaProcedure temp = new InitMetaProcedure(conf); procedureExecutor.submitProcedure(temp); return temp; }); diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/InitMetaProcedure.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/InitMetaProcedure.java index a23f11a2e875..a40ac18f6313 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/InitMetaProcedure.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/InitMetaProcedure.java @@ -19,6 +19,7 @@ import static org.apache.hadoop.hbase.NamespaceDescriptor.DEFAULT_NAMESPACE; import static org.apache.hadoop.hbase.NamespaceDescriptor.SYSTEM_NAMESPACE; +import static org.apache.hadoop.hbase.TableName.valueOf; import static org.apache.hadoop.hbase.master.TableNamespaceManager.insertNamespaceToMeta; import static org.apache.hadoop.hbase.master.procedure.AbstractStateMachineNamespaceProcedure.createDirectory; @@ -28,6 +29,8 @@ import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; +import org.apache.hadoop.hbase.HConstants; +import org.apache.hadoop.hbase.NamespaceDescriptor; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.client.RegionInfoBuilder; import org.apache.hadoop.hbase.client.TableDescriptor; @@ -61,9 +64,14 @@ public class InitMetaProcedure extends AbstractStateMachineTableProcedure pair = + MetaTableAccessor.getRegion(connection, Bytes.toBytes("nonexistent-region")); + assertNull(pair); + LOG.info("Finished " + name); + } + + @Test + public void testGetExistentRegionFromMetaFromReplica() throws IOException { + final TableName tableName = TableName.valueOf(name.getMethodName()); + LOG.info("Started " + tableName); + UTIL.createTable(tableName, HConstants.CATALOG_FAMILY); + assertEquals(1, MetaTableAccessor.getTableRegions(connection, tableName).size()); + } +}