HBASE-25356 HBaseAdmin#getRegion() needs to filter out non-regionName and non-encodedRegionName (#2759) (#2789)

Signed-off-by: stack <stack@apache.org>
This commit is contained in:
huaxiangsun 2020-12-18 13:16:03 -08:00 committed by GitHub
parent 1932a58a62
commit baf3122ad8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 59 additions and 3 deletions

View File

@ -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);

View File

@ -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 {

View File

@ -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.

View File

@ -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;
@ -70,6 +72,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());

View File

@ -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();
}