Skip to content

Commit c5ab589

Browse files
committed
HBASE-29082: Support for custom meta table name suffix
1 parent 28f1b51 commit c5ab589

File tree

5 files changed

+168
-5
lines changed

5 files changed

+168
-5
lines changed

hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1641,6 +1641,18 @@ public enum OperationStatusCode {
16411641
*/
16421642
public final static boolean REJECT_DECOMMISSIONED_HOSTS_DEFAULT = false;
16431643

1644+
/**
1645+
* Adds a suffix to the meta table name: value=’test’ -> ‘hbase:meta_test’
1646+
* Added in HBASE-XXXXX to support having multiple hbase:meta tables (with distinct names )to
1647+
* enable storage sharing by more than one clusters.
1648+
*/
1649+
public final static String HBASE_META_TABLE_SUFFIX = "hbase.meta.table.suffix";
1650+
1651+
/**
1652+
* Default value of {@link #HBASE_META_TABLE_SUFFIX}
1653+
*/
1654+
public final static String HBASE_META_TABLE_SUFFIX_DEFAULT_VALUE = "";
1655+
16441656
private HConstants() {
16451657
// Can't be instantiated with this ctor.
16461658
}

hbase-common/src/main/java/org/apache/hadoop/hbase/TableName.java

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717
*/
1818
package org.apache.hadoop.hbase;
1919

20+
import com.google.errorprone.annotations.RestrictedApi;
2021
import java.nio.ByteBuffer;
22+
import java.util.concurrent.ScheduledExecutorService;
23+
import org.apache.hadoop.conf.Configuration;
2124
import java.nio.charset.StandardCharsets;
2225
import java.util.Arrays;
2326
import java.util.Set;
@@ -27,6 +30,8 @@
2730
import org.apache.yetus.audience.InterfaceAudience;
2831

2932
import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;
33+
import org.slf4j.Logger;
34+
import org.slf4j.LoggerFactory;
3035

3136
/**
3237
* Immutable POJO class for representing a table name. Which is of the form: <table
@@ -44,6 +49,8 @@
4449
*/
4550
@InterfaceAudience.Public
4651
public final class TableName implements Comparable<TableName> {
52+
private static final Logger LOG = LoggerFactory.getLogger(TableName.class);
53+
4754

4855
/** See {@link #createTableNameIfNecessary(ByteBuffer, ByteBuffer)} */
4956
private static final Set<TableName> tableCache = new CopyOnWriteArraySet<>();
@@ -65,9 +72,34 @@ public final class TableName implements Comparable<TableName> {
6572
public static final String VALID_USER_TABLE_REGEX = "(?:(?:(?:" + VALID_NAMESPACE_REGEX + "\\"
6673
+ NAMESPACE_DELIM + ")?)" + "(?:" + VALID_TABLE_QUALIFIER_REGEX + "))";
6774

68-
/** The hbase:meta table's name. */
69-
public static final TableName META_TABLE_NAME =
70-
valueOf(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR, "meta");
75+
/** The name of hbase meta table could either be hbase:meta_xxx or 'hbase:meta' otherwise.
76+
* Config hbase.meta.table.suffix will govern the decision of adding suffix to the habase:meta */
77+
public static final TableName META_TABLE_NAME;
78+
static {
79+
Configuration conf = HBaseConfiguration.create();
80+
META_TABLE_NAME = initializeHbaseMetaTableName(conf);
81+
}
82+
83+
/* Visible for testing only */
84+
@RestrictedApi(explanation = "Should only be called in tests", link = "",
85+
allowedOnPath = ".*/src/test/.*")
86+
public static TableName getDefaultNameOfMetaForReplica() {
87+
return valueOf(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR, "meta");
88+
}
89+
90+
public static TableName initializeHbaseMetaTableName(Configuration conf) {
91+
String suffix_val = String.valueOf(conf.getStrings(
92+
HConstants.HBASE_META_TABLE_SUFFIX, HConstants.HBASE_META_TABLE_SUFFIX_DEFAULT_VALUE));
93+
94+
if (suffix_val == null || suffix_val.isEmpty()) {
95+
LOG.info("Meta table name: {}", META_TABLE_NAME);
96+
return TableName.META_TABLE_NAME;
97+
}
98+
TableName META_TABLE = valueOf(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR,
99+
"meta_" + suffix_val);;
100+
LOG.info("Meta table name: {}", META_TABLE);
101+
return META_TABLE;
102+
}
71103

72104
/**
73105
* The Namespace table's name.

hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1094,7 +1094,7 @@ private void finishActiveMasterInitialization() throws IOException, InterruptedE
10941094
.filter(p -> p instanceof InitMetaProcedure).map(o -> (InitMetaProcedure) o).findAny();
10951095
initMetaProc = optProc.orElseGet(() -> {
10961096
// schedule an init meta procedure if meta has not been deployed yet
1097-
InitMetaProcedure temp = new InitMetaProcedure();
1097+
InitMetaProcedure temp = new InitMetaProcedure(conf);
10981098
procedureExecutor.submitProcedure(temp);
10991099
return temp;
11001100
});

hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/InitMetaProcedure.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import static org.apache.hadoop.hbase.NamespaceDescriptor.DEFAULT_NAMESPACE;
2121
import static org.apache.hadoop.hbase.NamespaceDescriptor.SYSTEM_NAMESPACE;
22+
import static org.apache.hadoop.hbase.TableName.valueOf;
2223
import static org.apache.hadoop.hbase.master.TableNamespaceManager.insertNamespaceToMeta;
2324
import static org.apache.hadoop.hbase.master.procedure.AbstractStateMachineNamespaceProcedure.createDirectory;
2425

@@ -28,6 +29,8 @@
2829
import org.apache.hadoop.conf.Configuration;
2930
import org.apache.hadoop.fs.FileSystem;
3031
import org.apache.hadoop.fs.Path;
32+
import org.apache.hadoop.hbase.HConstants;
33+
import org.apache.hadoop.hbase.NamespaceDescriptor;
3134
import org.apache.hadoop.hbase.TableName;
3235
import org.apache.hadoop.hbase.client.RegionInfoBuilder;
3336
import org.apache.hadoop.hbase.client.TableDescriptor;
@@ -61,9 +64,14 @@ public class InitMetaProcedure extends AbstractStateMachineTableProcedure<InitMe
6164

6265
private RetryCounter retryCounter;
6366

67+
protected final Configuration conf;
68+
public InitMetaProcedure(Configuration conf) {
69+
this.conf = conf;
70+
}
71+
6472
@Override
6573
public TableName getTableName() {
66-
return TableName.META_TABLE_NAME;
74+
return TableName.initializeHbaseMetaTableName(conf);
6775
}
6876

6977
@Override
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package org.apache.hadoop.hbase;
19+
20+
import static org.junit.Assert.assertEquals;
21+
import static org.junit.Assert.assertNotNull;
22+
import static org.junit.Assert.assertNull;
23+
import static org.junit.Assert.assertTrue;
24+
25+
import java.io.IOException;
26+
import org.apache.hadoop.conf.Configuration;
27+
import org.apache.hadoop.hbase.client.Connection;
28+
import org.apache.hadoop.hbase.client.ConnectionFactory;
29+
import org.apache.hadoop.hbase.client.RegionInfo;
30+
import org.apache.hadoop.hbase.master.HMaster;
31+
import org.apache.hadoop.hbase.testclassification.MediumTests;
32+
import org.apache.hadoop.hbase.testclassification.MiscTests;
33+
import org.apache.hadoop.hbase.util.Bytes;
34+
import org.apache.hadoop.hbase.util.Pair;
35+
import org.junit.AfterClass;
36+
import org.junit.BeforeClass;
37+
import org.junit.ClassRule;
38+
import org.junit.Rule;
39+
import org.junit.Test;
40+
import org.junit.experimental.categories.Category;
41+
import org.junit.rules.TestName;
42+
import org.slf4j.Logger;
43+
import org.slf4j.LoggerFactory;
44+
45+
/**
46+
* Test {@link org.apache.hadoop.hbase.TestMetaTableForReplica}.
47+
*/
48+
@Category({ MiscTests.class, MediumTests.class })
49+
@SuppressWarnings("deprecation")
50+
public class TestMetaTableForReplica {
51+
@ClassRule
52+
public static final HBaseClassTestRule CLASS_RULE =
53+
HBaseClassTestRule.forClass(TestMetaTableForReplica.class);
54+
55+
private static final Logger LOG = LoggerFactory.getLogger(TestMetaTableForReplica.class);
56+
private static final HBaseTestingUtil UTIL = new HBaseTestingUtil();
57+
private static Connection connection;
58+
59+
@Rule
60+
public TestName name = new TestName();
61+
62+
@BeforeClass
63+
public static void beforeClass() throws Exception {
64+
Configuration c = new Configuration(UTIL.getConfiguration());
65+
//Start cluster having non-default hbase meta table name
66+
c.setStrings(HConstants.HBASE_META_TABLE_SUFFIX,"test");
67+
UTIL.startMiniCluster(3);
68+
connection = ConnectionFactory.createConnection(c);
69+
}
70+
71+
@AfterClass
72+
public static void afterClass() throws Exception {
73+
connection.close();
74+
UTIL.shutdownMiniCluster();
75+
}
76+
77+
@Test
78+
public void testStateOfMetaForReplica() {
79+
HMaster m = UTIL.getMiniHBaseCluster().getMaster();
80+
assertTrue(m.waitForMetaOnline());
81+
}
82+
83+
@Test
84+
public void testNameOfMetaForReplica() {
85+
//Check the correctness of the meta table for replica
86+
String metaTableName = TableName.META_TABLE_NAME.getNameWithNamespaceInclAsString();
87+
assertNotNull(metaTableName);
88+
89+
//Check if name of the meta table for replica is not same as default table
90+
assertEquals(0, TableName.META_TABLE_NAME.compareTo(
91+
TableName.getDefaultNameOfMetaForReplica()));
92+
}
93+
94+
@Test
95+
public void testGetNonExistentRegionFromMetaFromReplica() throws IOException {
96+
final String name = this.name.getMethodName();
97+
LOG.info("Started " + name);
98+
Pair<RegionInfo, ServerName> pair =
99+
MetaTableAccessor.getRegion(connection, Bytes.toBytes("nonexistent-region"));
100+
assertNull(pair);
101+
LOG.info("Finished " + name);
102+
}
103+
104+
@Test
105+
public void testGetExistentRegionFromMetaFromReplica() throws IOException {
106+
final TableName tableName = TableName.valueOf(name.getMethodName());
107+
LOG.info("Started " + tableName);
108+
UTIL.createTable(tableName, HConstants.CATALOG_FAMILY);
109+
assertEquals(1, MetaTableAccessor.getTableRegions(connection, tableName).size());
110+
}
111+
}

0 commit comments

Comments
 (0)