HBASE-14824 HBaseAdmin.mergeRegions should recognize both full region names and encoded region names (Eungsop Yoo)
This commit is contained in:
parent
d4d3b1954c
commit
a6e0ad636a
|
@ -148,6 +148,9 @@ public class HRegionInfo implements Comparable<HRegionInfo> {
|
||||||
|
|
||||||
private static final int MAX_REPLICA_ID = 0xFFFF;
|
private static final int MAX_REPLICA_ID = 0xFFFF;
|
||||||
public static final int DEFAULT_REPLICA_ID = 0;
|
public static final int DEFAULT_REPLICA_ID = 0;
|
||||||
|
|
||||||
|
public static final String INVALID_REGION_NAME_FORMAT_MESSAGE = "Invalid regionName format";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does region name contain its encoded name?
|
* Does region name contain its encoded name?
|
||||||
* @param regionName region name
|
* @param regionName region name
|
||||||
|
@ -575,7 +578,8 @@ public class HRegionInfo implements Comparable<HRegionInfo> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (offset == -1) {
|
if (offset == -1) {
|
||||||
throw new IOException("Invalid regionName format: " + Bytes.toStringBinary(regionName));
|
throw new IOException(INVALID_REGION_NAME_FORMAT_MESSAGE
|
||||||
|
+ ": " + Bytes.toStringBinary(regionName));
|
||||||
}
|
}
|
||||||
byte[] tableName = new byte[offset];
|
byte[] tableName = new byte[offset];
|
||||||
System.arraycopy(regionName, 0, tableName, 0, offset);
|
System.arraycopy(regionName, 0, tableName, 0, offset);
|
||||||
|
@ -606,7 +610,8 @@ public class HRegionInfo implements Comparable<HRegionInfo> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (offset == -1) {
|
if (offset == -1) {
|
||||||
throw new IOException("Invalid regionName format: " + Bytes.toStringBinary(regionName));
|
throw new IOException(INVALID_REGION_NAME_FORMAT_MESSAGE
|
||||||
|
+ ": " + Bytes.toStringBinary(regionName));
|
||||||
}
|
}
|
||||||
byte [] startKey = HConstants.EMPTY_BYTE_ARRAY;
|
byte [] startKey = HConstants.EMPTY_BYTE_ARRAY;
|
||||||
if(offset != tableName.length + 1) {
|
if(offset != tableName.length + 1) {
|
||||||
|
|
|
@ -768,13 +768,13 @@ public interface Admin extends Abortable, Closeable {
|
||||||
/**
|
/**
|
||||||
* Merge two regions. Asynchronous operation.
|
* Merge two regions. Asynchronous operation.
|
||||||
*
|
*
|
||||||
* @param encodedNameOfRegionA encoded name of region a
|
* @param nameOfRegionA encoded or full name of region a
|
||||||
* @param encodedNameOfRegionB encoded name of region b
|
* @param nameOfRegionB encoded or full name of region b
|
||||||
* @param forcible true if do a compulsory merge, otherwise we will only merge two adjacent
|
* @param forcible true if do a compulsory merge, otherwise we will only merge two adjacent
|
||||||
* regions
|
* regions
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
void mergeRegions(final byte[] encodedNameOfRegionA, final byte[] encodedNameOfRegionB,
|
void mergeRegions(final byte[] nameOfRegionA, final byte[] nameOfRegionB,
|
||||||
final boolean forcible) throws IOException;
|
final boolean forcible) throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2434,22 +2434,40 @@ public class HBaseAdmin implements Admin {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isEncodedRegionName(byte[] regionName) throws IOException {
|
||||||
|
try {
|
||||||
|
HRegionInfo.parseRegionName(regionName);
|
||||||
|
return false;
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (StringUtils.stringifyException(e)
|
||||||
|
.contains(HRegionInfo.INVALID_REGION_NAME_FORMAT_MESSAGE)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merge two regions. Asynchronous operation.
|
* Merge two regions. Asynchronous operation.
|
||||||
* @param encodedNameOfRegionA encoded name of region a
|
* @param nameOfRegionA encoded or full name of region a
|
||||||
* @param encodedNameOfRegionB encoded name of region b
|
* @param nameOfRegionB encoded or full name of region b
|
||||||
* @param forcible true if do a compulsory merge, otherwise we will only merge
|
* @param forcible true if do a compulsory merge, otherwise we will only merge
|
||||||
* two adjacent regions
|
* two adjacent regions
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void mergeRegions(final byte[] encodedNameOfRegionA,
|
public void mergeRegions(final byte[] nameOfRegionA,
|
||||||
final byte[] encodedNameOfRegionB, final boolean forcible)
|
final byte[] nameOfRegionB, final boolean forcible)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
Pair<HRegionInfo, ServerName> pair = getRegion(encodedNameOfRegionA);
|
final byte[] encodedNameOfRegionA = isEncodedRegionName(nameOfRegionA) ?
|
||||||
|
nameOfRegionA : HRegionInfo.encodeRegionName(nameOfRegionA).getBytes();
|
||||||
|
final byte[] encodedNameOfRegionB = isEncodedRegionName(nameOfRegionB) ?
|
||||||
|
nameOfRegionB : HRegionInfo.encodeRegionName(nameOfRegionB).getBytes();
|
||||||
|
|
||||||
|
Pair<HRegionInfo, ServerName> pair = getRegion(nameOfRegionA);
|
||||||
if (pair != null && pair.getFirst().getReplicaId() != HRegionInfo.DEFAULT_REPLICA_ID)
|
if (pair != null && pair.getFirst().getReplicaId() != HRegionInfo.DEFAULT_REPLICA_ID)
|
||||||
throw new IllegalArgumentException("Can't invoke merge on non-default regions directly");
|
throw new IllegalArgumentException("Can't invoke merge on non-default regions directly");
|
||||||
pair = getRegion(encodedNameOfRegionB);
|
pair = getRegion(nameOfRegionB);
|
||||||
if (pair != null && pair.getFirst().getReplicaId() != HRegionInfo.DEFAULT_REPLICA_ID)
|
if (pair != null && pair.getFirst().getReplicaId() != HRegionInfo.DEFAULT_REPLICA_ID)
|
||||||
throw new IllegalArgumentException("Can't invoke merge on non-default regions directly");
|
throw new IllegalArgumentException("Can't invoke merge on non-default regions directly");
|
||||||
executeCallable(new MasterCallable<Void>(getConnection()) {
|
executeCallable(new MasterCallable<Void>(getConnection()) {
|
||||||
|
|
|
@ -1407,4 +1407,43 @@ public class TestAdmin1 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMergeRegions() throws Exception {
|
||||||
|
TableName tableName = TableName.valueOf("testMergeWithFullRegionName");
|
||||||
|
HColumnDescriptor cd = new HColumnDescriptor("d");
|
||||||
|
HTableDescriptor td = new HTableDescriptor(tableName);
|
||||||
|
td.addFamily(cd);
|
||||||
|
byte[][] splitRows = new byte[2][];
|
||||||
|
splitRows[0] = new byte[]{(byte)'3'};
|
||||||
|
splitRows[1] = new byte[]{(byte)'6'};
|
||||||
|
try {
|
||||||
|
TEST_UTIL.createTable(td, splitRows);
|
||||||
|
TEST_UTIL.waitTableAvailable(tableName);
|
||||||
|
|
||||||
|
List<HRegionInfo> tableRegions;
|
||||||
|
HRegionInfo regionA;
|
||||||
|
HRegionInfo regionB;
|
||||||
|
|
||||||
|
// merge with full name
|
||||||
|
tableRegions = admin.getTableRegions(tableName);
|
||||||
|
assertEquals(3, admin.getTableRegions(tableName).size());
|
||||||
|
regionA = tableRegions.get(0);
|
||||||
|
regionB = tableRegions.get(1);
|
||||||
|
admin.mergeRegions(regionA.getRegionName(), regionB.getRegionName(), false);
|
||||||
|
Thread.sleep(1000);
|
||||||
|
assertEquals(2, admin.getTableRegions(tableName).size());
|
||||||
|
|
||||||
|
// merge with encoded name
|
||||||
|
tableRegions = admin.getTableRegions(tableName);
|
||||||
|
regionA = tableRegions.get(0);
|
||||||
|
regionB = tableRegions.get(1);
|
||||||
|
admin.mergeRegions(regionA.getEncodedNameAsBytes(), regionB.getEncodedNameAsBytes(), false);
|
||||||
|
Thread.sleep(1000);
|
||||||
|
assertEquals(1, admin.getTableRegions(tableName).size());
|
||||||
|
} finally {
|
||||||
|
this.admin.disableTable(tableName);
|
||||||
|
this.admin.deleteTable(tableName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue