HBASE-19260 Add lock back to avoid parallel accessing meta to locate region

This commit is contained in:
Michael Stack 2017-11-17 14:03:56 -08:00
parent 330b0d05b9
commit 777b653b45
No known key found for this signature in database
GPG Key ID: 9816C7FC8ACC93D2
1 changed files with 26 additions and 19 deletions

View File

@ -47,6 +47,7 @@ import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -212,6 +213,9 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
*/
private final String alternateBufferedMutatorClassName;
/** lock guards against multiple threads trying to query the meta region at the same time */
private final ReentrantLock userRegionLock = new ReentrantLock();
/**
* constructor
* @param conf Configuration object
@ -788,12 +792,10 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
}
int maxAttempts = (retry ? numTries : 1);
for (int tries = 0; true; tries++) {
if (tries >= maxAttempts) {
throw new NoServerForRegionException("Unable to find region for "
+ Bytes.toStringBinary(row) + " in " + tableName +
" after " + tries + " tries.");
+ Bytes.toStringBinary(row) + " in " + tableName + " after " + tries + " tries.");
}
if (useCache) {
RegionLocations locations = getCachedLocation(tableName, row);
@ -809,7 +811,14 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
// Query the meta region
long pauseBase = this.pause;
userRegionLock.lock();
try {
if (useCache) {// re-check cache after get lock
RegionLocations locations = getCachedLocation(tableName, row);
if (locations != null && locations.getRegionLocation(replicaId) != null) {
return locations;
}
}
Result regionInfoRow = null;
s.resetMvccReadPoint();
s.setOneRowLimit();
@ -842,23 +851,20 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
"hbase:meta might be damaged.");
}
if (regionInfo.isSplit()) {
throw new RegionOfflineException("the only available region for" +
" the required row is a split parent," +
" the daughters should be online soon: " +
regionInfo.getRegionNameAsString());
throw new RegionOfflineException(
"the only available region for the required row is a split parent,"
+ " the daughters should be online soon: " + regionInfo.getRegionNameAsString());
}
if (regionInfo.isOffline()) {
throw new RegionOfflineException("the region is offline, could" +
" be caused by a disable table call: " +
regionInfo.getRegionNameAsString());
throw new RegionOfflineException("the region is offline, could"
+ " be caused by a disable table call: " + regionInfo.getRegionNameAsString());
}
ServerName serverName = locations.getRegionLocation(replicaId).getServerName();
if (serverName == null) {
throw new NoServerForRegionException("No server address listed " +
"in " + TableName.META_TABLE_NAME + " for region " +
regionInfo.getRegionNameAsString() + " containing row " +
Bytes.toStringBinary(row));
throw new NoServerForRegionException("No server address listed in "
+ TableName.META_TABLE_NAME + " for region " + regionInfo.getRegionNameAsString()
+ " containing row " + Bytes.toStringBinary(row));
}
if (isDeadServer(serverName)){
@ -885,11 +891,10 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
}
if (tries < maxAttempts - 1) {
if (LOG.isDebugEnabled()) {
LOG.debug("locateRegionInMeta parentTable=" +
TableName.META_TABLE_NAME + ", metaLocation=" +
", attempt=" + tries + " of " +
maxAttempts + " failed; retrying after sleep of " +
ConnectionUtils.getPauseTime(pauseBase, tries) + " because: " + e.getMessage());
LOG.debug("locateRegionInMeta parentTable=" + TableName.META_TABLE_NAME
+ ", metaLocation=" + ", attempt=" + tries + " of " + maxAttempts
+ " failed; retrying after sleep of "
+ ConnectionUtils.getPauseTime(pauseBase, tries) + " because: " + e.getMessage());
}
} else {
throw e;
@ -899,6 +904,8 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
e instanceof NoServerForRegionException)) {
relocateRegion(TableName.META_TABLE_NAME, metaKey, replicaId);
}
} finally {
userRegionLock.unlock();
}
try{
Thread.sleep(ConnectionUtils.getPauseTime(pauseBase, tries));