diff --git src/main/java/org/apache/hadoop/hbase/client/HConnection.java src/main/java/org/apache/hadoop/hbase/client/HConnection.java
index f3bd9fa..f3bc0cb 100644
--- src/main/java/org/apache/hadoop/hbase/client/HConnection.java
+++ src/main/java/org/apache/hadoop/hbase/client/HConnection.java
@@ -163,6 +163,14 @@ public interface HConnection extends Abortable, Closeable {
public void clearRegionCache(final byte [] tableName);
/**
+ * Deletes cached locations for the specific region.
+ * @param tableName Name of the table to which the region belongs.
+ * @param location The location object for the region, to be purged from cache.
+ */
+ public void deleteCachedRegionLocation(final byte [] tableName,
+ final HRegionLocation location);
+
+ /**
* Find the location of the region of tableName that row
* lives in, ignoring any value that might be in the cache.
* @param tableName name of the table row is in
diff --git src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
index a9a51f9..d370e57 100644
--- src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
+++ src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
@@ -1172,11 +1172,10 @@ public class HConnectionManager {
*/
void deleteCachedLocation(final byte [] tableName, final byte [] row) {
synchronized (this.cachedRegionLocations) {
- Map tableLocations =
- getTableLocations(tableName);
- // start to examine the cache. we can only do cache actions
- // if there's something in the cache for this table.
+ Map tableLocations = getTableLocations(tableName);
if (!tableLocations.isEmpty()) {
+ // start to examine the cache. we can only do cache actions
+ // if there's something in the cache for this table.
HRegionLocation rl = getCachedLocation(tableName, row);
if (rl != null) {
tableLocations.remove(rl.getRegionInfo().getStartKey());
@@ -1192,6 +1191,26 @@ public class HConnectionManager {
}
@Override
+ public void deleteCachedRegionLocation(final byte[] tableName, final HRegionLocation location) {
+ if (location == null) {
+ return;
+ }
+ synchronized (this.cachedRegionLocations) {
+ Map tableLocations = getTableLocations(tableName);
+ if (!tableLocations.isEmpty()) {
+ // if there's something in the cache for this table.
+ tableLocations.remove(location.getRegionInfo().getStartKey());
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Removed " +
+ location.getRegionInfo().getRegionNameAsString() +
+ " for tableName=" + Bytes.toString(tableName) +
+ " from cache");
+ }
+ }
+ }
+ }
+
+ @Override
public void clearCaches(String sn) {
clearCachedLocationForServer(sn);
}
diff --git src/main/java/org/apache/hadoop/hbase/client/ServerCallable.java src/main/java/org/apache/hadoop/hbase/client/ServerCallable.java
index fcf43e7..8f5b4e0 100644
--- src/main/java/org/apache/hadoop/hbase/client/ServerCallable.java
+++ src/main/java/org/apache/hadoop/hbase/client/ServerCallable.java
@@ -32,6 +32,7 @@ import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.DoNotRetryIOException;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionLocation;
+import org.apache.hadoop.hbase.NotServingRegionException;
import org.apache.hadoop.hbase.ipc.HBaseRPC;
import org.apache.hadoop.hbase.ipc.HRegionInterface;
import org.apache.hadoop.hbase.util.Bytes;
@@ -174,6 +175,10 @@ public abstract class ServerCallable implements Callable {
if (hrl != null) {
getConnection().clearCaches(hrl.getHostnamePort());
}
+ } else if (t instanceof NotServingRegionException && numRetries == 1) {
+ // Reload this specific region into META cache since we don't call
+ // connect(true) and hence do not refresh the META cache.
+ getConnection().deleteCachedRegionLocation(tableName, location);
}
RetriesExhaustedException.ThrowableWithExtraContext qt =
new RetriesExhaustedException.ThrowableWithExtraContext(t,