use of org.apache.hadoop.hbase.NotServingRegionException in project hbase by apache.
the class HRegion method startRegionOperation.
@Override
public void startRegionOperation(Operation op) throws IOException {
boolean isInterruptableOp = false;
switch(op) {
// interruptible read operations
case GET:
case SCAN:
isInterruptableOp = true;
checkReadsEnabled();
break;
// interruptible write operations
case INCREMENT:
case APPEND:
case PUT:
case DELETE:
case BATCH_MUTATE:
case CHECK_AND_MUTATE:
isInterruptableOp = true;
break;
default:
// all others
break;
}
if (op == Operation.MERGE_REGION || op == Operation.SPLIT_REGION || op == Operation.COMPACT_REGION || op == Operation.COMPACT_SWITCH) {
// region
return;
}
if (this.closing.get()) {
throw new NotServingRegionException(getRegionInfo().getRegionNameAsString() + " is closing");
}
lock(lock.readLock());
// Update regionLockHolders ONLY for any startRegionOperation call that is invoked from
// an RPC handler
Thread thisThread = Thread.currentThread();
if (isInterruptableOp) {
regionLockHolders.put(thisThread, true);
}
if (this.closed.get()) {
lock.readLock().unlock();
throw new NotServingRegionException(getRegionInfo().getRegionNameAsString() + " is closed");
}
// prepared for snapshot operation before proceeding.
if (op == Operation.SNAPSHOT) {
stores.values().forEach(HStore::preSnapshotOperation);
}
try {
if (coprocessorHost != null) {
coprocessorHost.postStartRegionOperation(op);
}
} catch (Exception e) {
if (isInterruptableOp) {
// would be harmless to remove what we didn't add but we know by 'isInterruptableOp'
// if we added this thread to regionLockHolders
regionLockHolders.remove(thisThread);
}
lock.readLock().unlock();
throw new IOException(e);
}
}
use of org.apache.hadoop.hbase.NotServingRegionException in project hbase by apache.
the class RegionReplicaTestHelper method testLocator.
static void testLocator(HBaseTestingUtil util, TableName tableName, Locator locator) throws Exception {
RegionLocations locs = locator.getRegionLocations(tableName, RegionReplicaUtil.DEFAULT_REPLICA_ID, false);
assertEquals(3, locs.size());
for (int i = 0; i < 3; i++) {
HRegionLocation loc = locs.getRegionLocation(i);
assertNotNull(loc);
ServerName serverName = getRSCarryingReplica(util, tableName, i).get();
assertEquals(serverName, loc.getServerName());
}
ServerName newServerName = moveRegion(util, locs.getDefaultRegionLocation());
// The cached location should not be changed
assertEquals(locs.getDefaultRegionLocation().getServerName(), locator.getRegionLocations(tableName, RegionReplicaUtil.DEFAULT_REPLICA_ID, false).getDefaultRegionLocation().getServerName());
// should get the new location when reload = true
// when meta replica LoadBalance mode is enabled, it may delay a bit.
util.waitFor(3000, new ExplainingPredicate<Exception>() {
@Override
public boolean evaluate() throws Exception {
ServerName sn = locator.getRegionLocations(tableName, RegionReplicaUtil.DEFAULT_REPLICA_ID, true).getDefaultRegionLocation().getServerName();
return newServerName.equals(sn);
}
@Override
public String explainFailure() throws Exception {
return "New location does not show up in meta (replica) region";
}
});
assertEquals(newServerName, locator.getRegionLocations(tableName, RegionReplicaUtil.DEFAULT_REPLICA_ID, true).getDefaultRegionLocation().getServerName());
// the cached location should be replaced
assertEquals(newServerName, locator.getRegionLocations(tableName, RegionReplicaUtil.DEFAULT_REPLICA_ID, false).getDefaultRegionLocation().getServerName());
ServerName newServerName1 = moveRegion(util, locs.getRegionLocation(1));
ServerName newServerName2 = moveRegion(util, locs.getRegionLocation(2));
// The cached location should not be change
assertEquals(locs.getRegionLocation(1).getServerName(), locator.getRegionLocations(tableName, 1, false).getRegionLocation(1).getServerName());
// clear the cached location for replica 1
locator.updateCachedLocationOnError(locs.getRegionLocation(1), new NotServingRegionException());
// the cached location for replica 2 should not be changed
assertEquals(locs.getRegionLocation(2).getServerName(), locator.getRegionLocations(tableName, 2, false).getRegionLocation(2).getServerName());
// should get the new location as we have cleared the old location
assertEquals(newServerName1, locator.getRegionLocations(tableName, 1, false).getRegionLocation(1).getServerName());
// as we will get the new location for replica 2 at once, we should also get the new location
// for replica 2
assertEquals(newServerName2, locator.getRegionLocations(tableName, 2, false).getRegionLocation(2).getServerName());
}
use of org.apache.hadoop.hbase.NotServingRegionException in project hbase by apache.
the class HRegionServer method closeRegion.
/**
* Close asynchronously a region, can be called from the master or internally by the regionserver
* when stopping. If called from the master, the region will update the status.
*
* <p>
* If an opening was in progress, this method will cancel it, but will not start a new close. The
* coprocessors are not called in this case. A NotServingRegionException exception is thrown.
* </p>
*
* <p>
* If a close was in progress, this new request will be ignored, and an exception thrown.
* </p>
*
* @param encodedName Region to close
* @param abort True if we are aborting
* @param destination Where the Region is being moved too... maybe null if unknown.
* @return True if closed a region.
* @throws NotServingRegionException if the region is not online
*/
protected boolean closeRegion(String encodedName, final boolean abort, final ServerName destination) throws NotServingRegionException {
// Check for permissions to close.
HRegion actualRegion = this.getRegion(encodedName);
// Can be null if we're calling close on a region that's not online
if ((actualRegion != null) && (actualRegion.getCoprocessorHost() != null)) {
try {
actualRegion.getCoprocessorHost().preClose(false);
} catch (IOException exp) {
LOG.warn("Unable to close region: the coprocessor launched an error ", exp);
return false;
}
}
// previous can come back 'null' if not in map.
final Boolean previous = this.regionsInTransitionInRS.putIfAbsent(Bytes.toBytes(encodedName), Boolean.FALSE);
if (Boolean.TRUE.equals(previous)) {
LOG.info("Received CLOSE for the region:" + encodedName + " , which we are already " + "trying to OPEN. Cancelling OPENING.");
if (!regionsInTransitionInRS.replace(Bytes.toBytes(encodedName), previous, Boolean.FALSE)) {
// The replace failed. That should be an exceptional case, but theoretically it can happen.
// We're going to try to do a standard close then.
LOG.warn("The opening for region " + encodedName + " was done before we could cancel it." + " Doing a standard close now");
return closeRegion(encodedName, abort, destination);
}
// Let's get the region from the online region list again
actualRegion = this.getRegion(encodedName);
if (actualRegion == null) {
// If already online, we still need to close it.
LOG.info("The opening previously in progress has been cancelled by a CLOSE request.");
// The master deletes the znode when it receives this exception.
throw new NotServingRegionException("The region " + encodedName + " was opening but not yet served. Opening is cancelled.");
}
} else if (previous == null) {
LOG.info("Received CLOSE for {}", encodedName);
} else if (Boolean.FALSE.equals(previous)) {
LOG.info("Received CLOSE for the region: " + encodedName + ", which we are already trying to CLOSE, but not completed yet");
return true;
}
if (actualRegion == null) {
LOG.debug("Received CLOSE for a region which is not online, and we're not opening.");
this.regionsInTransitionInRS.remove(Bytes.toBytes(encodedName));
// The master deletes the znode when it receives this exception.
throw new NotServingRegionException("The region " + encodedName + " is not online, and is not opening.");
}
CloseRegionHandler crh;
final RegionInfo hri = actualRegion.getRegionInfo();
if (hri.isMetaRegion()) {
crh = new CloseMetaHandler(this, this, hri, abort);
} else {
crh = new CloseRegionHandler(this, this, hri, abort, destination);
}
this.executorService.submit(crh);
return true;
}
use of org.apache.hadoop.hbase.NotServingRegionException in project hbase by apache.
the class TestAsyncNonMetaRegionLocator method testConcurrentUpdateCachedLocationOnError.
@Test
public void testConcurrentUpdateCachedLocationOnError() throws Exception {
createSingleRegionTable();
HRegionLocation loc = getDefaultRegionLocation(TABLE_NAME, EMPTY_START_ROW, RegionLocateType.CURRENT, false).get();
IntStream.range(0, 100).parallel().forEach(i -> locator.updateCachedLocationOnError(loc, new NotServingRegionException()));
}
use of org.apache.hadoop.hbase.NotServingRegionException in project hbase by apache.
the class TestAsyncNonMetaRegionLocator method testRegionMove.
@Test
public void testRegionMove() throws IOException, InterruptedException, ExecutionException {
createSingleRegionTable();
ServerName serverName = TEST_UTIL.getRSForFirstRegionInTable(TABLE_NAME).getServerName();
HRegionLocation loc = getDefaultRegionLocation(TABLE_NAME, EMPTY_START_ROW, RegionLocateType.CURRENT, false).get();
assertLocEquals(EMPTY_START_ROW, EMPTY_END_ROW, serverName, loc);
ServerName newServerName = TEST_UTIL.getHBaseCluster().getRegionServerThreads().stream().map(t -> t.getRegionServer().getServerName()).filter(sn -> !sn.equals(serverName)).findAny().get();
TEST_UTIL.getAdmin().move(Bytes.toBytes(loc.getRegion().getEncodedName()), newServerName);
while (!TEST_UTIL.getRSForFirstRegionInTable(TABLE_NAME).getServerName().equals(newServerName)) {
Thread.sleep(100);
}
// Should be same as it is in cache
assertSame(loc, getDefaultRegionLocation(TABLE_NAME, EMPTY_START_ROW, RegionLocateType.CURRENT, false).get());
locator.updateCachedLocationOnError(loc, null);
// null error will not trigger a cache cleanup
assertSame(loc, getDefaultRegionLocation(TABLE_NAME, EMPTY_START_ROW, RegionLocateType.CURRENT, false).get());
locator.updateCachedLocationOnError(loc, new NotServingRegionException());
assertLocEquals(EMPTY_START_ROW, EMPTY_END_ROW, newServerName, getDefaultRegionLocation(TABLE_NAME, EMPTY_START_ROW, RegionLocateType.CURRENT, false).get());
}
Aggregations