Skip to content

Comments

HBASE-29691: Change TableName.META_TABLE_NAME from being a global static#7730

Open
Kota-SH wants to merge 1 commit intoapache:masterfrom
Kota-SH:HBASE-29691-new
Open

HBASE-29691: Change TableName.META_TABLE_NAME from being a global static#7730
Kota-SH wants to merge 1 commit intoapache:masterfrom
Kota-SH:HBASE-29691-new

Conversation

@Kota-SH
Copy link
Contributor

@Kota-SH Kota-SH commented Feb 10, 2026

HBASE-29691: Change TableName.META_TABLE_NAME from being a global static

Change TableName.META_TABLE_NAME from a global static constant to a dynamically discovered value from ConnectionRegistry.

Please refer to earlier discussion on the PR #7558 for further details.

Key changes:

  • Add ConnectionRegistry.getMetaTableName() method for dynamic discovery
  • Add MetaTableNameStore for persisting meta table name in master region
  • Update TableName to support dynamic meta table name
  • Update HMaster to integrate with MetaTableNameStore
  • Update all client and server code to use dynamic meta table name
  • Add protobuf changes for meta table name in Registry.proto

Refactoring for the test classes to be handled separately.

Change TableName.META_TABLE_NAME from a global static constant to a
dynamically discovered value from ConnectionRegistry.

Key changes:
- Add ConnectionRegistry.getMetaTableName() method for dynamic discovery
- Add MetaTableNameStore for persisting meta table name in master region
- Update TableName to support dynamic meta table name
- Update HMaster to integrate with MetaTableNameStore
- Update all client and server code to use dynamic meta table name
- Add protobuf changes for meta table name in Registry.proto

Refactoring for the test classes to be handled separately.
Copy link
Contributor

@anmolnar anmolnar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm. What are the build failures?

Copy link
Contributor

@kgeisz kgeisz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM overall. I have some nit comments below. Also, I see PR #7558 is still open. Should that PR be closed?

// TODO: How come Meta regions still do not have encoded region names? Fix.
// hbase:meta,,1.1588230740 should be the hbase:meta first region name.
// TODO: For now, hardcode to default. Future: lazy initialization based on config or make it use
// conenction
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
// conenction
// connection

@@ -787,8 +787,13 @@ public static CellComparator getCellComparator(TableName tableName) {
*/
public static CellComparator getCellComparator(byte[] tableName) {
// FYI, TableName.toBytes does not create an array; just returns existing array pointer.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Is this comment still applicable?

if (!createMetaEntriesFailures.isEmpty()) {
LOG.warn(
"Failed to create entries in hbase:meta for {}/{} RegionInfo descriptors. First"
"Failed to create entries in {}} for {}/{} RegionInfo descriptors. First"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit

Suggested change
"Failed to create entries in {}} for {}/{} RegionInfo descriptors. First"
"Failed to create entries in {} for {}/{} RegionInfo descriptors. First"

if (!cfs.contains(family)) {
throw new HBaseIOException(
"Delete of hbase:meta column family " + Bytes.toString(family));
"Delete of " + env.getMetaTableName() + " column family " + Bytes.toString(family));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: IMO this could be a little more clear

Suggested change
"Delete of " + env.getMetaTableName() + " column family " + Bytes.toString(family));
"Invalid deletion of " + env.getMetaTableName() + " column family: " + Bytes.toString(family));

LOG.debug("Loaded meta table name from Master Local Region: {}", cachedMetaTableName);
return cachedMetaTableName;
}
LOG.info("No stored meta table name found in Master Local Region: {}", cachedMetaTableName);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit

Suggested change
LOG.info("No stored meta table name found in Master Local Region: {}", cachedMetaTableName);
LOG.info("No stored meta table name found in Master Local Region: {}", cachedMetaTableName);

startEndKeys.get(idx + 1).getFirst()) == 0)
) {
throw new IOException("The endkey of one region for table " + tableName
+ " is not equal to the startkey of the next region in hbase:meta."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here

Comment on lines +2024 to +2028
LOG.warn(
"Unable to close region " + hi.getRegionNameAsString()
+ " because {} had invalid or missing " + HConstants.CATALOG_FAMILY_STR + ":"
+ Bytes.toString(HConstants.REGIONINFO_QUALIFIER) + " qualifier value.",
connection.getMetaTableName());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I see a mixture of using string concatenation as well as {} in the LOG.warn() method. IMO is should consistently use the {} convention.

Comment on lines +2205 to +2206
LOG.info("Patching {} with .regioninfo: " + hbi.getHdfsHRI(),
connection.getMetaTableName());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Mixture of string concatenation and {} in log method

Comment on lines +2234 to +2235
LOG.info("Patching {} with with .regioninfo: " + hbi.getHdfsHRI(),
connection.getMetaTableName());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Mixture of string concatenation and {} in log method

+ hbi.getMetaEntry().regionServer + " but is multiply assigned to region servers "
+ Joiner.on(", ").join(hbi.getDeployedOn()));
"Region " + descriptiveName + " is listed in " + connection.getMetaTableName()
+ " on region server " + hbi.getMetaEntry().regionServer + " but is multiply assigned"
Copy link
Contributor

@kgeisz kgeisz Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Do you have any idea what they mean by "multiply assigned"? Like "multi-assigned"?

@Apache9
Copy link
Contributor

Apache9 commented Feb 23, 2026

Just came back from vacation...
This is a big change, please give me more time for reviewing...
Thanks.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request implements HBASE-29691, which changes TableName.META_TABLE_NAME from a global static constant to a dynamically discovered value. The change enables support for cluster-specific meta table names, particularly for read replica clusters and other specialized configurations.

Changes:

  • Adds ConnectionRegistry.getMetaTableName() method for dynamic meta table name discovery
  • Introduces MetaTableNameStore class to persist the meta table name in the Master Local Region
  • Updates Connection, AsyncConnection, and MasterServices interfaces to expose getMetaTableName() method
  • Modifies TableName.isMetaTableName() to support both default "hbase:meta" and variant table names with suffixes
  • Updates all client and server code paths to use the dynamic meta table name instead of the static constant
  • Adds new RPC endpoint GetMetaTableName in Registry.proto for retrieving the meta table name from the master

Reviewed changes

Copilot reviewed 98 out of 98 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
hbase-protocol-shaded/src/main/protobuf/server/Registry.proto Adds GetMetaTableName RPC request/response messages
hbase-server/src/main/java/org/apache/hadoop/hbase/master/MetaTableNameStore.java New class to store/retrieve meta table name from Master Local Region
hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java Integrates MetaTableNameStore and overrides getMetaTableName()
hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java Implements getMetaTableName() to fetch from master via connection
hbase-client/src/main/java/org/apache/hadoop/hbase/client/Connection.java Adds getMetaTableName() and getMetaTable() helper methods
hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncConnection.java Adds getMetaTableName() and getMetaTable() helper methods
hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionRegistry.java Adds getMetaTableName() method for discovering meta table name
hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncConnectionImpl.java Stores and exposes meta table name fetched from registry
hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionFactory.java Fetches meta table name from registry during connection creation
hbase-common/src/main/java/org/apache/hadoop/hbase/TableName.java Updates isMetaTableName() to support meta table name variants, deprecates META_TABLE_NAME
hbase-common/src/main/java/org/apache/hadoop/hbase/CellComparatorImpl.java Updates comparator selection to support dynamic meta table names
hbase-server/src/main/java/org/apache/hadoop/hbase/HBaseServerBase.java Provides default getMetaTableName() implementation
hbase-server/src/main/java/org/apache/hadoop/hbase/HBaseRpcServicesBase.java Implements getMetaTableName() RPC handler
Multiple server-side utilities Updates HBaseFsck, RegionMover, MetaTableAccessor, and other utilities to use dynamic meta table name
Multiple test files Updates test infrastructure and mocks to support dynamic meta table name

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 1204 to +1208
LOG.info(
"The {} config is {} while the replica count in TableDescriptor is {}"
+ " for hbase:meta, altering...",
HConstants.META_REPLICAS_NUM, replicasNumInConf, metaDesc.getRegionReplication());
HConstants.META_REPLICAS_NUM, replicasNumInConf, metaDesc.getRegionReplication(),
getMetaTableName());
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The log format at line 1207 has incorrect parameter count. The format string has 3 placeholders ("The {} config is {} while the replica count in TableDescriptor is {} for hbase:meta, altering...") but 4 arguments are provided: HConstants.META_REPLICAS_NUM, replicasNumInConf, metaDesc.getRegionReplication(), and getMetaTableName(). This will cause a logging error. The fourth parameter getMetaTableName() should be part of the format string template, not an extra argument.

Copilot uses AI. Check for mistakes.
Comment on lines +1688 to +1691
} catch (IOException e) {
LOG.info("Exception loading/storing meta table name from master region");
throw new RuntimeException(e);
}
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message at line 1689 is missing important context. When logging an exception, it should describe what operation failed. The message "Exception loading/storing meta table name from master region" should be logged with the exception using LOG.error() or LOG.warn() with the exception as the second parameter, not LOG.info(). Also, rethrowing as RuntimeException loses the original exception message - consider using new RuntimeException("Exception loading/storing meta table name from master region", e) to preserve the exception chain.

Copilot uses AI. Check for mistakes.
}

static boolean isMetaTable(byte[] tableName) {
return Bytes.startsWith(tableName, TableName.META_TABLE_NAME.getName());
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation uses TableName.META_TABLE_NAME.getName() as a prefix check, but this could match unintended table names. For example, if someone creates a table "hbase:metadata", this check would incorrectly return true because it starts with "hbase:meta". The logic should verify exact match or use a more precise delimiter-based check. Consider checking if the bytes are exactly equal OR if they match the pattern with an underscore separator.

Suggested change
return Bytes.startsWith(tableName, TableName.META_TABLE_NAME.getName());
byte[] metaName = TableName.META_TABLE_NAME.getName();
// Match exactly "hbase:meta" or names starting with "hbase:meta_" (e.g., "hbase:meta_1").
if (Bytes.equals(tableName, metaName)) {
return true;
}
if (tableName == null || tableName.length <= metaName.length) {
return false;
}
if (!Bytes.startsWith(tableName, metaName)) {
return false;
}
// Require an underscore delimiter after "hbase:meta" to avoid matching names like "hbase:metadata".
return tableName[metaName.length] == (byte) '_';

Copilot uses AI. Check for mistakes.
// TODO: How come Meta regions still do not have encoded region names? Fix.
// hbase:meta,,1.1588230740 should be the hbase:meta first region name.
// TODO: For now, hardcode to default. Future: lazy initialization based on config or make it use
// conenction
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment on line 46 has a typo: "conenction" should be "connection".

Suggested change
// conenction
// connection

Copilot uses AI. Check for mistakes.
Comment on lines +146 to +148
private static TableName getMetaTableNameFromConf(Configuration conf) {
// TODO: Support replica-specific meta table names from masterRegion
return TableName.META_TABLE_NAME;
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TODO comment on line 147 mentions "Support replica-specific meta table names from masterRegion" but this contradicts the PR's design. The PR adds MetaTableNameStore which stores the meta table name in the master region. This method, however, is static and doesn't have access to the master region. The comment and implementation should be aligned - either this method should not exist (and callers should use the dynamic meta table name from the connection/master), or the TODO should explain how static methods will interact with the dynamic meta table name system.

Copilot uses AI. Check for mistakes.
Comment on lines +89 to +90
LOG.info("No stored meta table name found in Master Local Region: {}", cachedMetaTableName);
return cachedMetaTableName;
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The log message at line 89 is misleading. When no stored meta table name is found, cachedMetaTableName is still null, but the log message says "No stored meta table name found in Master Local Region: {}", cachedMetaTableName. This will log null, which is confusing. The message should be clearer that no value was found and null will be returned.

Copilot uses AI. Check for mistakes.
if (!createMetaEntriesFailures.isEmpty()) {
LOG.warn(
"Failed to create entries in hbase:meta for {}/{} RegionInfo descriptors. First"
"Failed to create entries in {}} for {}/{} RegionInfo descriptors. First"
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The log parameter format string has a typo - there's an extra closing brace. The format string shows "Failed to create entries in {}} for {}/{}" but should be "Failed to create entries in {} for {}/{}" with only one closing brace after the first placeholder.

Copilot uses AI. Check for mistakes.
Comment on lines +305 to +306
throw new IllegalArgumentException(OLD_META_STR + " no longer exists. The table has been "
+ "renamed to hbase:meta or hbase:meta_suffix in conf");
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message at line 305-306 references "hbase:meta or hbase:meta_suffix in conf" but this is confusing because the meta table name is not directly configured. The message should be updated to reflect that the meta table name is dynamically discovered, not configured. Consider: "The table has been renamed to hbase:meta (or a cluster-specific meta table name)"

Copilot uses AI. Check for mistakes.
Comment on lines +372 to +375
@Override
public TableName getMetaTableName() {
return toAsyncConnection().getMetaTableName();
}
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling toAsyncConnection().getMetaTableName() on line 374 will throw NotImplementedException because toAsyncConnection() on line 379 throws NotImplementedException. This creates a method that always throws an exception, which is a bug. The getMetaTableName() implementation should either throw NotImplementedException directly or have a proper implementation that doesn't depend on toAsyncConnection().

Copilot uses AI. Check for mistakes.
Comment on lines +3679 to +3689
public TableName getMetaTableName() {
if (asyncClusterConnection != null) {
try {
return asyncClusterConnection.getMetaTableName();
} catch (Exception e) {
LOG.warn("Failed to get meta table name from Master", e);
}
}
// Bootstrap
return super.getMetaTableName();
}
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The getMetaTableName() method in HRegionServer could return different values over time, which could cause inconsistencies. During bootstrap (before asyncClusterConnection is set), it returns the default meta table name from the parent class. After the connection is established, it returns the value from the connection. If there's any caching or state that depends on this value, changing it mid-execution could cause issues. Consider caching the value once it's successfully retrieved from the connection to ensure consistency.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants