HBASE-19260 Add lock back to avoid parallel accessing meta to locate region
This commit is contained in:
parent
330b0d05b9
commit
777b653b45
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue