use of org.apache.hadoop.hbase.UnknownRegionException in project hbase by apache.
the class HMaster method move.
// Public so can be accessed by tests. Blocks until move is done.
// Replace with an async implementation from which you can get
// a success/failure result.
@InterfaceAudience.Private
public void move(final byte[] encodedRegionName, byte[] destServerName) throws IOException {
RegionState regionState = assignmentManager.getRegionStates().getRegionState(Bytes.toString(encodedRegionName));
RegionInfo hri;
if (regionState != null) {
hri = regionState.getRegion();
} else {
throw new UnknownRegionException(Bytes.toStringBinary(encodedRegionName));
}
ServerName dest;
List<ServerName> exclude = hri.getTable().isSystemTable() ? assignmentManager.getExcludedServersForSystemTable() : new ArrayList<>(1);
if (destServerName != null && exclude.contains(ServerName.valueOf(Bytes.toString(destServerName)))) {
LOG.info(Bytes.toString(encodedRegionName) + " can not move to " + Bytes.toString(destServerName) + " because the server is in exclude list");
destServerName = null;
}
if (destServerName == null || destServerName.length == 0) {
LOG.info("Passed destination servername is null/empty so " + "choosing a server at random");
exclude.add(regionState.getServerName());
final List<ServerName> destServers = this.serverManager.createDestinationServersList(exclude);
dest = balancer.randomAssignment(hri, destServers);
if (dest == null) {
LOG.debug("Unable to determine a plan to assign " + hri);
return;
}
} else {
ServerName candidate = ServerName.valueOf(Bytes.toString(destServerName));
dest = balancer.randomAssignment(hri, Lists.newArrayList(candidate));
if (dest == null) {
LOG.debug("Unable to determine a plan to assign " + hri);
return;
}
// TODO: deal with table on master for rs group.
if (dest.equals(serverName)) {
// To avoid unnecessary region moving later by balancer. Don't put user
// regions on master.
LOG.debug("Skipping move of region " + hri.getRegionNameAsString() + " to avoid unnecessary region moving later by load balancer," + " because it should not be on master");
return;
}
}
if (dest.equals(regionState.getServerName())) {
LOG.debug("Skipping move of region " + hri.getRegionNameAsString() + " because region already assigned to the same server " + dest + ".");
return;
}
// Now we can do the move
RegionPlan rp = new RegionPlan(hri, regionState.getServerName(), dest);
assert rp.getDestination() != null : rp.toString() + " " + dest;
try {
checkInitialized();
if (this.cpHost != null) {
this.cpHost.preMove(hri, rp.getSource(), rp.getDestination());
}
TransitRegionStateProcedure proc = this.assignmentManager.createMoveRegionProcedure(rp.getRegionInfo(), rp.getDestination());
if (conf.getBoolean(WARMUP_BEFORE_MOVE, DEFAULT_WARMUP_BEFORE_MOVE)) {
// Warmup the region on the destination before initiating the move.
// A region server could reject the close request because it either does not
// have the specified region or the region is being split.
LOG.info(getClientIdAuditPrefix() + " move " + rp + ", warming up region on " + rp.getDestination());
warmUpRegion(rp.getDestination(), hri);
}
LOG.info(getClientIdAuditPrefix() + " move " + rp + ", running balancer");
Future<byte[]> future = ProcedureSyncWait.submitProcedure(this.procedureExecutor, proc);
try {
// Is this going to work? Will we throw exception on error?
// TODO: CompletableFuture rather than this stunted Future.
future.get();
} catch (InterruptedException | ExecutionException e) {
throw new HBaseIOException(e);
}
if (this.cpHost != null) {
this.cpHost.postMove(hri, rp.getSource(), rp.getDestination());
}
} catch (IOException ioe) {
if (ioe instanceof HBaseIOException) {
throw (HBaseIOException) ioe;
}
throw new HBaseIOException(ioe);
}
}
use of org.apache.hadoop.hbase.UnknownRegionException in project hbase by apache.
the class TestMaster method testMoveThrowsUnknownRegionException.
@Test
public void testMoveThrowsUnknownRegionException() throws IOException {
final TableName tableName = TableName.valueOf(name.getMethodName());
TableDescriptorBuilder tableDescriptorBuilder = TableDescriptorBuilder.newBuilder(tableName);
ColumnFamilyDescriptor columnFamilyDescriptor = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("value")).build();
tableDescriptorBuilder.setColumnFamily(columnFamilyDescriptor);
admin.createTable(tableDescriptorBuilder.build());
try {
RegionInfo hri = RegionInfoBuilder.newBuilder(tableName).setStartKey(Bytes.toBytes("A")).setEndKey(Bytes.toBytes("Z")).build();
admin.move(hri.getEncodedNameAsBytes());
fail("Region should not be moved since it is fake");
} catch (IOException ioe) {
assertTrue(ioe instanceof UnknownRegionException);
} finally {
TEST_UTIL.deleteTable(tableName);
}
}
use of org.apache.hadoop.hbase.UnknownRegionException in project hbase by apache.
the class HBaseAdmin method mergeRegionsAsync.
/**
* Merge two regions. Asynchronous operation.
* @param nameofRegionsToMerge encoded or full name of daughter regions
* @param forcible true if do a compulsory merge, otherwise we will only merge
* adjacent regions
* @throws IOException
*/
@Override
public Future<Void> mergeRegionsAsync(final byte[][] nameofRegionsToMerge, final boolean forcible) throws IOException {
assert (nameofRegionsToMerge.length >= 2);
byte[][] encodedNameofRegionsToMerge = new byte[nameofRegionsToMerge.length][];
for (int i = 0; i < nameofRegionsToMerge.length; i++) {
encodedNameofRegionsToMerge[i] = isEncodedRegionName(nameofRegionsToMerge[i]) ? nameofRegionsToMerge[i] : HRegionInfo.encodeRegionName(nameofRegionsToMerge[i]).getBytes();
}
TableName tableName = null;
Pair<HRegionInfo, ServerName> pair;
for (int i = 0; i < nameofRegionsToMerge.length; i++) {
pair = getRegion(nameofRegionsToMerge[i]);
if (pair != null) {
if (pair.getFirst().getReplicaId() != HRegionInfo.DEFAULT_REPLICA_ID) {
throw new IllegalArgumentException("Can't invoke merge on non-default regions directly");
}
if (tableName == null) {
tableName = pair.getFirst().getTable();
} else if (!tableName.equals(pair.getFirst().getTable())) {
throw new IllegalArgumentException("Cannot merge regions from two different tables " + tableName + " and " + pair.getFirst().getTable());
}
} else {
throw new UnknownRegionException("Can't invoke merge on unknown region " + Bytes.toStringBinary(encodedNameofRegionsToMerge[i]));
}
}
MergeTableRegionsResponse response = executeCallable(new MasterCallable<MergeTableRegionsResponse>(getConnection(), getRpcControllerFactory()) {
@Override
protected MergeTableRegionsResponse rpcCall() throws Exception {
MergeTableRegionsRequest request = RequestConverter.buildMergeTableRegionsRequest(encodedNameofRegionsToMerge, forcible, ng.getNonceGroup(), ng.newNonce());
return master.mergeTableRegions(getRpcController(), request);
}
});
return new MergeTableRegionsFuture(this, tableName, response);
}
use of org.apache.hadoop.hbase.UnknownRegionException in project hbase by apache.
the class MergeTableRegionsProcedure method prepareMergeRegion.
/**
* Prepare merge and do some check
* @param env MasterProcedureEnv
* @throws IOException
*/
private void prepareMergeRegion(final MasterProcedureEnv env) throws IOException {
// Note: the following logic assumes that we only have 2 regions to merge. In the future,
// if we want to extend to more than 2 regions, the code needs to modify a little bit.
//
CatalogJanitor catalogJanitor = env.getMasterServices().getCatalogJanitor();
boolean regionAHasMergeQualifier = !catalogJanitor.cleanMergeQualifier(regionsToMerge[0]);
if (regionAHasMergeQualifier || !catalogJanitor.cleanMergeQualifier(regionsToMerge[1])) {
String msg = "Skip merging regions " + getRegionsToMergeListFullNameString() + ", because region " + (regionAHasMergeQualifier ? regionsToMerge[0].getEncodedName() : regionsToMerge[1].getEncodedName()) + " has merge qualifier";
LOG.warn(msg);
throw new MergeRegionException(msg);
}
RegionStates regionStates = getAssignmentManager(env).getRegionStates();
RegionState regionStateA = regionStates.getRegionState(regionsToMerge[0].getEncodedName());
RegionState regionStateB = regionStates.getRegionState(regionsToMerge[1].getEncodedName());
if (regionStateA == null || regionStateB == null) {
throw new UnknownRegionException(regionStateA == null ? regionsToMerge[0].getEncodedName() : regionsToMerge[1].getEncodedName());
}
if (!regionStateA.isOpened() || !regionStateB.isOpened()) {
throw new MergeRegionException("Unable to merge regions not online " + regionStateA + ", " + regionStateB);
}
}
use of org.apache.hadoop.hbase.UnknownRegionException in project hbase by apache.
the class TestAssignmentManagerOnCluster method testMoveRegionOfDeletedTable.
/**
* If a table is deleted, we should not be able to move it anymore.
* Otherwise, the region will be brought back.
* @throws Exception
*/
@Test(timeout = 50000)
public void testMoveRegionOfDeletedTable() throws Exception {
final TableName tableName = TableName.valueOf(name.getMethodName());
Admin admin = TEST_UTIL.getAdmin();
try {
HRegionInfo hri = createTableAndGetOneRegion(tableName);
HMaster master = TEST_UTIL.getHBaseCluster().getMaster();
AssignmentManager am = master.getAssignmentManager();
RegionStates regionStates = am.getRegionStates();
ServerName serverName = regionStates.getRegionServerOfRegion(hri);
ServerName destServerName = null;
for (int i = 0; i < 3; i++) {
HRegionServer destServer = TEST_UTIL.getHBaseCluster().getRegionServer(i);
if (!destServer.getServerName().equals(serverName)) {
destServerName = destServer.getServerName();
break;
}
}
assertTrue(destServerName != null && !destServerName.equals(serverName));
TEST_UTIL.deleteTable(tableName);
try {
admin.move(hri.getEncodedNameAsBytes(), Bytes.toBytes(destServerName.getServerName()));
fail("We should not find the region");
} catch (IOException ioe) {
assertTrue(ioe instanceof UnknownRegionException);
}
am.balance(new RegionPlan(hri, serverName, destServerName));
assertFalse("The region should not be in transition", regionStates.isRegionInTransition(hri));
} finally {
if (admin.tableExists(tableName)) {
TEST_UTIL.deleteTable(tableName);
}
}
}
Aggregations