diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncRegionLocatorHelper.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncRegionLocatorHelper.java index 5f4bc9f999f..a4191d9e622 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncRegionLocatorHelper.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncRegionLocatorHelper.java @@ -19,6 +19,7 @@ package org.apache.hadoop.hbase.client; import static org.apache.hadoop.hbase.exceptions.ClientExceptionsUtil.findException; import static org.apache.hadoop.hbase.exceptions.ClientExceptionsUtil.isMetaClearingException; +import static org.apache.hadoop.hbase.exceptions.ClientExceptionsUtil.isRegionServerOverloadedException; import java.util.Arrays; import java.util.Optional; @@ -67,7 +68,8 @@ final class AsyncRegionLocatorHelper { LOG.debug("The actual exception when updating {} is {}", loc, cause != null ? cause.toString() : "none"); } - if (cause == null || !isMetaClearingException(cause)) { + if (cause == null || !isMetaClearingException(cause) + || isRegionServerOverloadedException(cause)) { LOG.debug("Will not update {} because the exception is null or not the one we care about", loc); return; diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/exceptions/ClientExceptionsUtil.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/exceptions/ClientExceptionsUtil.java index 6b1e251953b..e330c3c2239 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/exceptions/ClientExceptionsUtil.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/exceptions/ClientExceptionsUtil.java @@ -32,7 +32,6 @@ import java.util.concurrent.TimeoutException; import org.apache.hadoop.hbase.CallDroppedException; import org.apache.hadoop.hbase.CallQueueTooBigException; import org.apache.hadoop.hbase.DoNotRetryIOException; -import org.apache.hadoop.hbase.MultiActionResultTooLarge; import org.apache.hadoop.hbase.NotServingRegionException; import org.apache.hadoop.hbase.RegionTooBusyException; import org.apache.hadoop.hbase.RetryImmediatelyException; @@ -59,18 +58,28 @@ public final class ClientExceptionsUtil { if (cur == null) { return true; } - return !isSpecialException(cur) || (cur instanceof RegionMovedException) - || cur instanceof NotServingRegionException; + return !isMetaCachePreservingException(cur); } - public static boolean isSpecialException(Throwable cur) { - return (cur instanceof RegionMovedException || cur instanceof RegionOpeningException - || cur instanceof RegionTooBusyException || cur instanceof RpcThrottlingException - || cur instanceof MultiActionResultTooLarge || cur instanceof RetryImmediatelyException - || cur instanceof CallQueueTooBigException || cur instanceof CallDroppedException - || cur instanceof NotServingRegionException || cur instanceof RequestTooBigException); + public static boolean isRegionServerOverloadedException(Throwable t) { + t = findException(t); + return isInstanceOfRegionServerOverloadedException(t); } + private static boolean isInstanceOfRegionServerOverloadedException(Throwable t) { + return t instanceof CallQueueTooBigException || t instanceof CallDroppedException; + } + + private static boolean isMetaCachePreservingException(Throwable t) { + return t instanceof RegionOpeningException || t instanceof RegionTooBusyException + || t instanceof RpcThrottlingException || t instanceof RetryImmediatelyException + || t instanceof RequestTooBigException; + } + + private static boolean isExceptionWeCare(Throwable t) { + return isMetaCachePreservingException(t) || isInstanceOfRegionServerOverloadedException(t) + || t instanceof NotServingRegionException; + } /** * Look for an exception we know in the remote exception: @@ -87,7 +96,7 @@ public final class ClientExceptionsUtil { } Throwable cur = (Throwable) exception; while (cur != null) { - if (isSpecialException(cur)) { + if (isExceptionWeCare(cur)) { return cur; } if (cur instanceof RemoteException) { @@ -95,7 +104,7 @@ public final class ClientExceptionsUtil { cur = re.unwrapRemoteException(); // unwrapRemoteException can return the exception given as a parameter when it cannot - // unwrap it. In this case, there is no need to look further + // unwrap it. In this case, there is no need to look further // noinspection ObjectEquality if (cur == re) { return cur; diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestMetaCache.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestMetaCache.java index 4bfdcad029a..e0a1847edbe 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestMetaCache.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestMetaCache.java @@ -27,6 +27,7 @@ import java.io.IOException; import java.util.Arrays; import java.util.List; import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.CallDroppedException; import org.apache.hadoop.hbase.CallQueueTooBigException; import org.apache.hadoop.hbase.HBaseClassTestRule; import org.apache.hadoop.hbase.HBaseTestingUtility; @@ -38,6 +39,7 @@ import org.apache.hadoop.hbase.RetryImmediatelyException; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.exceptions.ClientExceptionsUtil; import org.apache.hadoop.hbase.exceptions.RegionOpeningException; +import org.apache.hadoop.hbase.exceptions.RequestTooBigException; import org.apache.hadoop.hbase.quotas.RpcThrottlingException; import org.apache.hadoop.hbase.regionserver.HRegionServer; import org.apache.hadoop.hbase.regionserver.RSRpcServices; @@ -149,12 +151,14 @@ public class TestMetaCache { table.mutateRow(mutations); } catch (IOException ex) { // Only keep track of the last exception that updated the meta cache - if (ClientExceptionsUtil.isMetaClearingException(ex) || success) { + if ((ClientExceptionsUtil.isMetaClearingException(ex) + && !ClientExceptionsUtil.isRegionServerOverloadedException(ex)) || success) { exp = ex; } } // Do not test if we did not touch the meta cache in this iteration. - if (exp != null && ClientExceptionsUtil.isMetaClearingException(exp)) { + if (exp != null && ClientExceptionsUtil.isMetaClearingException(exp) + && !ClientExceptionsUtil.isRegionServerOverloadedException(exp)) { assertNull(locator.getRegionLocationInCache(TABLE_NAME, row)); } else if (success) { assertNotNull(locator.getRegionLocationInCache(TABLE_NAME, row)); @@ -199,7 +203,8 @@ public class TestMetaCache { return Arrays.asList(new RegionOpeningException(" "), new RegionTooBusyException("Some old message"), new RpcThrottlingException(" "), new MultiActionResultTooLarge(" "), new RetryImmediatelyException(" "), - new CallQueueTooBigException()); + new RequestTooBigException(), new CallQueueTooBigException(), + new CallDroppedException()); } public static class RegionServerWithFakeRpcServices extends HRegionServer {