This is an automated email from the ASF dual-hosted git repository.

rmdmattingly pushed a commit to branch branch-2
in repository https://gitbox.apache.org/repos/asf/hbase.git


The following commit(s) were added to refs/heads/branch-2 by this push:
     new 84aafc28543 HBASE-30348 Throttles should work for system tables 
(excluding quotas, meta) (#8585) (#8591)
84aafc28543 is described below

commit 84aafc28543836c3f5d855c9f361355467879eb7
Author: Ray Mattingly <[email protected]>
AuthorDate: Mon Aug 31 13:36:44 2026 -0400

    HBASE-30348 Throttles should work for system tables (excluding quotas, 
meta) (#8585) (#8591)
    
    Signed-off-by: Charles Connell <[email protected]>
---
 .../org/apache/hadoop/hbase/quotas/QuotaCache.java |  2 +-
 .../org/apache/hadoop/hbase/quotas/QuotaUtil.java  | 14 +++++
 .../hbase/quotas/RegionServerRpcQuotaManager.java  |  2 +-
 .../apache/hadoop/hbase/quotas/TestQuotaUtil.java  | 65 ++++++++++++++++++++++
 4 files changed, 81 insertions(+), 2 deletions(-)

diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/QuotaCache.java 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/QuotaCache.java
index 34104752e81..2b8c81a415f 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/QuotaCache.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/QuotaCache.java
@@ -155,7 +155,7 @@ public class QuotaCache implements Stoppable {
    * @return the limiter associated to the specified user/table
    */
   public QuotaLimiter getUserLimiter(final UserGroupInformation ugi, final 
TableName table) {
-    if (table.isSystemTable()) {
+    if (QuotaUtil.isThrottleExempt(table)) {
       return NoopQuotaLimiter.get();
     }
     return getUserQuotaState(ugi).getTableLimiter(table);
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/QuotaUtil.java 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/QuotaUtil.java
index f7df09801e0..f32c9d10443 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/QuotaUtil.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/QuotaUtil.java
@@ -647,6 +647,20 @@ public class QuotaUtil extends QuotaTableUtil {
    * @param conn      connection to re-use
    * @param tableName table name which has moved into space quota violation
    */
+  /**
+   * Returns true if the given table must never be subject to RPC throttling.
+   * <p>
+   * Only {@code hbase:meta} and {@code hbase:quota} are exempt. Throttling 
either of those risks
+   * deadlock, because the throttling machinery itself depends on them: quotas 
are loaded from
+   * {@code hbase:quota}, and clients resolve region locations through {@code 
hbase:meta}, so
+   * delaying those requests could prevent a throttle from ever being lifted. 
Every other table may
+   * be throttled, including the remaining tables in the {@code hbase} 
namespace and the backup
+   * tables.
+   */
+  public static boolean isThrottleExempt(final TableName tableName) {
+    return TableName.META_TABLE_NAME.equals(tableName) || 
QUOTA_TABLE_NAME.equals(tableName);
+  }
+
   public static void disableTableIfNotDisabled(Connection conn, TableName 
tableName)
     throws IOException {
     try {
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/RegionServerRpcQuotaManager.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/RegionServerRpcQuotaManager.java
index 34fc57cb081..a7167c3821a 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/RegionServerRpcQuotaManager.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/RegionServerRpcQuotaManager.java
@@ -137,7 +137,7 @@ public class RegionServerRpcQuotaManager implements 
RpcQuotaManager, Configurati
    */
   public OperationQuota getQuota(final UserGroupInformation ugi, final 
TableName table,
     final int blockSizeBytes) {
-    if (isQuotaEnabled() && !table.isSystemTable() && isRpcThrottleEnabled()) {
+    if (isQuotaEnabled() && !QuotaUtil.isThrottleExempt(table) && 
isRpcThrottleEnabled()) {
       UserQuotaState userQuotaState = quotaCache.getUserQuotaState(ugi);
       QuotaLimiter userLimiter = userQuotaState.getTableLimiter(table);
 
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/quotas/TestQuotaUtil.java 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/quotas/TestQuotaUtil.java
new file mode 100644
index 00000000000..176f77d58ae
--- /dev/null
+++ 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/quotas/TestQuotaUtil.java
@@ -0,0 +1,65 @@
+/*
+ * 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.quotas;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.testclassification.RegionServerTests;
+import org.apache.hadoop.hbase.testclassification.SmallTests;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+
+@Tag(RegionServerTests.TAG)
+@Tag(SmallTests.TAG)
+public class TestQuotaUtil {
+
+  @Test
+  public void testMetaTableIsThrottleExempt() {
+    assertTrue(QuotaUtil.isThrottleExempt(TableName.META_TABLE_NAME));
+  }
+
+  @Test
+  public void testQuotaTableIsThrottleExempt() {
+    assertTrue(QuotaUtil.isThrottleExempt(QuotaTableUtil.QUOTA_TABLE_NAME));
+  }
+
+  @Test
+  public void testBackupTablesAreNotThrottleExempt() {
+    // Backup tables live in a system namespace, so they were previously 
exempt. They can
+    // accumulate very large cells, which makes them a meaningful source of IO 
pressure, so
+    // operators need to be able to throttle them.
+    
assertFalse(QuotaUtil.isThrottleExempt(TableName.valueOf("backup:system")));
+    
assertFalse(QuotaUtil.isThrottleExempt(TableName.valueOf("backup:system_bulk")));
+  }
+
+  @Test
+  public void testOtherSystemTablesAreNotThrottleExempt() {
+    
assertFalse(QuotaUtil.isThrottleExempt(TableName.valueOf("hbase:namespace")));
+    assertFalse(QuotaUtil.isThrottleExempt(TableName.valueOf("hbase:acl")));
+    assertFalse(QuotaUtil.isThrottleExempt(TableName.valueOf("hbase:labels")));
+    
assertFalse(QuotaUtil.isThrottleExempt(TableName.valueOf("hbase:rsgroup")));
+  }
+
+  @Test
+  public void testUserTablesAreNotThrottleExempt() {
+    assertFalse(QuotaUtil.isThrottleExempt(TableName.valueOf("my_table")));
+    
assertFalse(QuotaUtil.isThrottleExempt(TableName.valueOf("my_ns:my_table")));
+  }
+}

Reply via email to