You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by hu...@apache.org on 2020/12/17 23:21:57 UTC

[hbase] branch branch-2 updated: HBASE-25356 HBaseAdmin#getRegion() needs to filter out non-regionName and non-encodedRegionName (#2759)

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

huaxiangsun 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 22dd054  HBASE-25356 HBaseAdmin#getRegion() needs to filter out non-regionName and non-encodedRegionName (#2759)
22dd054 is described below

commit 22dd0545b9e9fd540e251984de373af30c2b94e8
Author: huaxiangsun <hu...@apache.org>
AuthorDate: Thu Dec 17 15:21:30 2020 -0800

    HBASE-25356 HBaseAdmin#getRegion() needs to filter out non-regionName and non-encodedRegionName (#2759)
    
    Signed-off-by: stack <st...@apache.org>
---
 .../org/apache/hadoop/hbase/MetaTableAccessor.java |  4 ++-
 .../org/apache/hadoop/hbase/client/HBaseAdmin.java |  9 +++++-
 .../org/apache/hadoop/hbase/client/RegionInfo.java | 14 ++++++++++
 .../org/apache/hadoop/hbase/client/TestAdmin1.java | 32 ++++++++++++++++++++++
 .../apache/hadoop/hbase/client/TestAdminBase.java  |  3 +-
 5 files changed, 59 insertions(+), 3 deletions(-)

diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java
index 235d120..c55086c 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java
@@ -279,7 +279,9 @@ public class MetaTableAccessor {
       parsedInfo = parseRegionInfoFromRegionName(regionName);
       row = getMetaKeyForRegion(parsedInfo);
     } catch (Exception parseEx) {
-      // Ignore. This is used with tableName passed as regionName.
+      // If it is not a valid regionName(i.e, tableName), it needs to return null here
+      // as querying meta table wont help.
+      return null;
     }
     Get get = new Get(row);
     get.addFamily(HConstants.CATALOG_FAMILY);
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java
index 9994baf..532481e 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java
@@ -1950,8 +1950,15 @@ public class HBaseAdmin implements Admin {
     }
     Pair<RegionInfo, ServerName> pair = MetaTableAccessor.getRegion(connection, regionName);
     if (pair == null) {
-      final AtomicReference<Pair<RegionInfo, ServerName>> result = new AtomicReference<>(null);
       final String encodedName = Bytes.toString(regionName);
+      // When it is not a valid regionName, it is possible that it could be an encoded regionName.
+      // To match the encoded regionName, it has to scan the meta table and compare entry by entry.
+      // Since it scans meta table, so it has to be the MD5 hash, it can filter out
+      // most of invalid cases.
+      if (!RegionInfo.isMD5Hash(encodedName)) {
+        return null;
+      }
+      final AtomicReference<Pair<RegionInfo, ServerName>> result = new AtomicReference<>(null);
       MetaTableAccessor.Visitor visitor = new MetaTableAccessor.Visitor() {
         @Override
         public boolean visit(Result data) throws IOException {
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RegionInfo.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RegionInfo.java
index d7460e9..0f51fed 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RegionInfo.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RegionInfo.java
@@ -424,6 +424,20 @@ public interface RegionInfo extends Comparable<RegionInfo> {
     }
   }
 
+  static boolean isMD5Hash(String encodedRegionName) {
+    if (encodedRegionName.length() != MD5_HEX_LENGTH) {
+      return false;
+    }
+
+    for (int i = 0; i < encodedRegionName.length(); i++) {
+      char c = encodedRegionName.charAt(i);
+      if (!((c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f') || (c >= '0' && c <= '9'))) {
+        return false;
+      }
+    }
+    return true;
+  }
+
   /**
    * Check whether two regions are adjacent; i.e. lies just before or just
    * after in a table.
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java
index 471a73f..fb3b4dd 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java
@@ -41,8 +41,10 @@ import org.apache.hadoop.hbase.master.HMaster;
 import org.apache.hadoop.hbase.master.janitor.CatalogJanitor;
 import org.apache.hadoop.hbase.regionserver.DisabledRegionSplitPolicy;
 import org.apache.hadoop.hbase.regionserver.HRegion;
+import org.apache.hadoop.hbase.regionserver.HRegionServer;
 import org.apache.hadoop.hbase.regionserver.HStore;
 import org.apache.hadoop.hbase.regionserver.HStoreFile;
+import org.apache.hadoop.hbase.regionserver.Region;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
 import org.apache.hadoop.hbase.util.Bytes;
@@ -71,6 +73,36 @@ public class TestAdmin1 extends TestAdminBase {
   private static final Logger LOG = LoggerFactory.getLogger(TestAdmin1.class);
 
   @Test
+  public void testCompactRegionWithTableName() throws Exception {
+    TableName tableName = TableName.valueOf(name.getMethodName());
+    try {
+      TableDescriptor htd = TableDescriptorBuilder.newBuilder(tableName).
+        setColumnFamily(ColumnFamilyDescriptorBuilder.of("fam1")).build();
+      ADMIN.createTable(htd);
+      Region metaRegion = null;
+      for (int i = 0; i < NB_SERVERS; i++) {
+        HRegionServer rs = TEST_UTIL.getMiniHBaseCluster().getRegionServer(i);
+        List<HRegion> onlineRegions = rs.getRegions(TableName.META_TABLE_NAME);
+        if (!onlineRegions.isEmpty()) {
+          metaRegion = onlineRegions.get(0);
+          break;
+        }
+      }
+
+      long metaReadCountBeforeCompact = metaRegion.getReadRequestsCount();
+      try {
+        ADMIN.majorCompactRegion(tableName.getName());
+      } catch (IllegalArgumentException iae) {
+        LOG.info("This is expected");
+      }
+      assertEquals(metaReadCountBeforeCompact, metaRegion.getReadRequestsCount());
+    } finally {
+      ADMIN.disableTable(tableName);
+      ADMIN.deleteTable(tableName);
+    }
+  }
+
+  @Test
   public void testSplitFlushCompactUnknownTable() throws InterruptedException {
     final TableName unknowntable = TableName.valueOf(name.getMethodName());
     Exception exception = null;
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdminBase.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdminBase.java
index c379775..d7a9107 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdminBase.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdminBase.java
@@ -33,6 +33,7 @@ import org.junit.rules.TestName;
 public class TestAdminBase {
 
   protected final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
+  protected final static int NB_SERVERS = 3;
   protected static Admin ADMIN;
 
   @Rule
@@ -47,7 +48,7 @@ public class TestAdminBase {
     TEST_UTIL.getConfiguration().setInt(HConstants.REGION_SERVER_HIGH_PRIORITY_HANDLER_COUNT, 30);
     TEST_UTIL.getConfiguration().setInt(HConstants.REGION_SERVER_HANDLER_COUNT, 30);
     TEST_UTIL.getConfiguration().setBoolean(HConstants.SLOW_LOG_BUFFER_ENABLED_KEY, true);
-    TEST_UTIL.startMiniCluster(3);
+    TEST_UTIL.startMiniCluster(NB_SERVERS);
     ADMIN = TEST_UTIL.getAdmin();
   }