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 adbc821bf33 HBASE-29082: Support for custom meta table name suffix
(#6632)
adbc821bf33 is described below
commit adbc821bf33389093d0c37e01fb044486be85226
Author: Abhishek Kothalikar <[email protected]>
AuthorDate: Tue Mar 11 20:03:25 2025 +0530
HBASE-29082: Support for custom meta table name suffix (#6632)
(cherry picked from commit 7ab9d52801fc5be72b742582d1732a8f5e602d86)
---
.../java/org/apache/hadoop/hbase/HConstants.java | 12 +++
.../java/org/apache/hadoop/hbase/TableName.java | 37 ++++++-
.../hadoop/hbase/TestMetaTableForReplica.java | 114 +++++++++++++++++++++
3 files changed, 160 insertions(+), 3 deletions(-)
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 c882e71e877..dd50d47bdf5 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 final class HConstants {
*/
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 83303a1c476..9628dc59b51 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,16 +17,21 @@
*/
package org.apache.hadoop.hbase;
+import com.google.errorprone.annotations.RestrictedApi;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import org.apache.commons.lang3.ArrayUtils;
+import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.yetus.audience.InterfaceAudience;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;
+import org.apache.hbase.thirdparty.com.google.common.base.Strings;
/**
* Immutable POJO class for representing a table name. Which is of the form:
<table
@@ -44,6 +49,7 @@ import
org.apache.hbase.thirdparty.com.google.common.base.Preconditions;
*/
@InterfaceAudience.Public
public final class TableName implements Comparable<TableName> {
+ private static final Logger LOG = LoggerFactory.getLogger(TableName.class);
/** See {@link #createTableNameIfNecessary(ByteBuffer, ByteBuffer)} */
private static final Set<TableName> tableCache = new CopyOnWriteArraySet<>();
@@ -65,9 +71,34 @@ public final class TableName implements
Comparable<TableName> {
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);
+ LOG.info("Meta table name: {}", META_TABLE_NAME);
+ }
+
+ /* 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 = conf.get(HConstants.HBASE_META_TABLE_SUFFIX,
+ HConstants.HBASE_META_TABLE_SUFFIX_DEFAULT_VALUE);
+ LOG.info("Meta table suffix value: {}", suffix_val);
+ if (Strings.isNullOrEmpty(suffix_val)) {
+ return valueOf(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR, "meta");
+ } else {
+ return valueOf(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR, "meta_" +
suffix_val);
+ }
+ }
/**
* The Namespace table's name.
diff --git
a/hbase-server/src/test/java/org/apache/hadoop/hbase/TestMetaTableForReplica.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/TestMetaTableForReplica.java
new file mode 100644
index 00000000000..d4e3d2c8ce0
--- /dev/null
+++
b/hbase-server/src/test/java/org/apache/hadoop/hbase/TestMetaTableForReplica.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.client.Connection;
+import org.apache.hadoop.hbase.client.ConnectionFactory;
+import org.apache.hadoop.hbase.client.RegionInfo;
+import org.apache.hadoop.hbase.master.HMaster;
+import org.apache.hadoop.hbase.testclassification.MediumTests;
+import org.apache.hadoop.hbase.testclassification.MiscTests;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.Pair;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TestName;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Test {@link org.apache.hadoop.hbase.TestMetaTableForReplica}.
+ */
+@Category({ MiscTests.class, MediumTests.class })
+@SuppressWarnings("deprecation")
+public class TestMetaTableForReplica {
+ @ClassRule
+ public static final HBaseClassTestRule CLASS_RULE =
+ HBaseClassTestRule.forClass(TestMetaTableForReplica.class);
+
+ private static final Logger LOG =
LoggerFactory.getLogger(TestMetaTableForReplica.class);
+ private static final HBaseTestingUtil UTIL = new HBaseTestingUtil();
+ private static Connection connection;
+
+ @Rule
+ public TestName name = new TestName();
+
+ @BeforeClass
+ public static void beforeClass() throws Exception {
+ Configuration c = UTIL.getConfiguration();
+ // quicker heartbeat interval for faster DN death notification
+ c.setInt("hbase.ipc.client.connect.max.retries", 1);
+ c.setInt(HConstants.ZK_SESSION_TIMEOUT, 1000);
+ // Start cluster having non-default hbase meta table name
+ c.setStrings(HConstants.HBASE_META_TABLE_SUFFIX, "test");
+ UTIL.startMiniCluster(3);
+ connection = ConnectionFactory.createConnection(c);
+ }
+
+ @AfterClass
+ public static void afterClass() throws Exception {
+ connection.close();
+ UTIL.shutdownMiniCluster();
+ }
+
+ @Test
+ public void testStateOfMetaForReplica() {
+ HMaster m = UTIL.getMiniHBaseCluster().getMaster();
+ assertTrue(m.waitForMetaOnline());
+ }
+
+ @Test
+ public void testNameOfMetaForReplica() {
+ // Check the correctness of the meta table for replica
+ String metaTableName =
TableName.META_TABLE_NAME.getNameWithNamespaceInclAsString();
+ assertNotNull(metaTableName);
+
+ // Check if name of the meta table for replica is not same as default table
+ assertEquals(0,
+
TableName.META_TABLE_NAME.compareTo(TableName.getDefaultNameOfMetaForReplica()));
+ }
+
+ @Test
+ public void testGetNonExistentRegionFromMetaFromReplica() throws IOException
{
+ final String name = this.name.getMethodName();
+ LOG.info("Started " + name);
+ Pair<RegionInfo, ServerName> 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());
+ }
+}