Skip to content

Commit 55999f7

Browse files
kabhishek4anmolnar
authored andcommitted
HBASE-29082: Support for custom meta table name suffix (#6632)
(cherry picked from commit 7ab9d52)
1 parent 9130913 commit 55999f7

File tree

3 files changed

+160
-3
lines changed

3 files changed

+160
-3
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
@@ -1659,6 +1659,18 @@ public enum OperationStatusCode {
16591659
*/
16601660
public final static boolean REJECT_DECOMMISSIONED_HOSTS_DEFAULT = false;
16611661

1662+
/**
1663+
* Adds a suffix to the meta table name: value=’test’ -> ‘hbase:meta_test’ Added in HBASE-XXXXX to
1664+
* support having multiple hbase:meta tables (with distinct names )to enable storage sharing by
1665+
* more than one clusters.
1666+
*/
1667+
public final static String HBASE_META_TABLE_SUFFIX = "hbase.meta.table.suffix";
1668+
1669+
/**
1670+
* Default value of {@link #HBASE_META_TABLE_SUFFIX}
1671+
*/
1672+
public final static String HBASE_META_TABLE_SUFFIX_DEFAULT_VALUE = "";
1673+
16621674
private HConstants() {
16631675
// Can't be instantiated with this ctor.
16641676
}

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

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

20+
import com.google.errorprone.annotations.RestrictedApi;
2021
import java.nio.ByteBuffer;
2122
import java.nio.charset.StandardCharsets;
2223
import java.util.Arrays;
2324
import java.util.Set;
2425
import java.util.concurrent.CopyOnWriteArraySet;
2526
import org.apache.commons.lang3.ArrayUtils;
27+
import org.apache.hadoop.conf.Configuration;
2628
import org.apache.hadoop.hbase.util.Bytes;
2729
import org.apache.yetus.audience.InterfaceAudience;
30+
import org.slf4j.Logger;
31+
import org.slf4j.LoggerFactory;
2832

2933
import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;
34+
import org.apache.hbase.thirdparty.com.google.common.base.Strings;
3035

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

4854
/** See {@link #createTableNameIfNecessary(ByteBuffer, ByteBuffer)} */
4955
private static final Set<TableName> tableCache = new CopyOnWriteArraySet<>();
@@ -65,9 +71,34 @@ public final class TableName implements Comparable<TableName> {
6571
public static final String VALID_USER_TABLE_REGEX = "(?:(?:(?:" + VALID_NAMESPACE_REGEX + "\\"
6672
+ NAMESPACE_DELIM + ")?)" + "(?:" + VALID_TABLE_QUALIFIER_REGEX + "))";
6773

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

72103
/**
73104
* The Namespace table's name.
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
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 = UTIL.getConfiguration();
65+
// quicker heartbeat interval for faster DN death notification
66+
c.setInt("hbase.ipc.client.connect.max.retries", 1);
67+
c.setInt(HConstants.ZK_SESSION_TIMEOUT, 1000);
68+
// Start cluster having non-default hbase meta table name
69+
c.setStrings(HConstants.HBASE_META_TABLE_SUFFIX, "test");
70+
UTIL.startMiniCluster(3);
71+
connection = ConnectionFactory.createConnection(c);
72+
}
73+
74+
@AfterClass
75+
public static void afterClass() throws Exception {
76+
connection.close();
77+
UTIL.shutdownMiniCluster();
78+
}
79+
80+
@Test
81+
public void testStateOfMetaForReplica() {
82+
HMaster m = UTIL.getMiniHBaseCluster().getMaster();
83+
assertTrue(m.waitForMetaOnline());
84+
}
85+
86+
@Test
87+
public void testNameOfMetaForReplica() {
88+
// Check the correctness of the meta table for replica
89+
String metaTableName = TableName.META_TABLE_NAME.getNameWithNamespaceInclAsString();
90+
assertNotNull(metaTableName);
91+
92+
// Check if name of the meta table for replica is not same as default table
93+
assertEquals(0,
94+
TableName.META_TABLE_NAME.compareTo(TableName.getDefaultNameOfMetaForReplica()));
95+
}
96+
97+
@Test
98+
public void testGetNonExistentRegionFromMetaFromReplica() throws IOException {
99+
final String name = this.name.getMethodName();
100+
LOG.info("Started " + name);
101+
Pair<RegionInfo, ServerName> pair =
102+
MetaTableAccessor.getRegion(connection, Bytes.toBytes("nonexistent-region"));
103+
assertNull(pair);
104+
LOG.info("Finished " + name);
105+
}
106+
107+
@Test
108+
public void testGetExistentRegionFromMetaFromReplica() throws IOException {
109+
final TableName tableName = TableName.valueOf(name.getMethodName());
110+
LOG.info("Started " + tableName);
111+
UTIL.createTable(tableName, HConstants.CATALOG_FAMILY);
112+
assertEquals(1, MetaTableAccessor.getTableRegions(connection, tableName).size());
113+
}
114+
}

0 commit comments

Comments
 (0)