diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncRequestFutureImpl.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncRequestFutureImpl.java index e46a50e761..00d3460631 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncRequestFutureImpl.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncRequestFutureImpl.java @@ -913,7 +913,7 @@ class AsyncRequestFutureImpl implements AsyncRequestFuture { } private void cleanServerCache(ServerName server, Throwable regionException) { - if (ClientExceptionsUtil.isMetaClearingException(regionException)) { + if (ClientExceptionsUtil.isCleanServerCacheException(regionException)) { // We want to make sure to clear the cache in case there were location-related exceptions. // We don't to clear the cache for every possible exception that comes through, however. asyncProcess.connection.clearCaches(server); 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 6b1e251953..4464495f8b 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 @@ -53,6 +53,22 @@ public final class ClientExceptionsUtil { private ClientExceptionsUtil() {} + public static boolean isCleanServerCacheException(Throwable cur) { + cur = findException(cur); + if (cur == null) { + return true; + } + boolean notCleanServerException = + (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 + || cur instanceof CallTimeoutException || cur instanceof DoNotRetryIOException); + // Exception like ConnectException should clean server's meta cache + return !notCleanServerException; + } + public static boolean isMetaClearingException(Throwable cur) { cur = findException(cur); @@ -68,7 +84,8 @@ public final class ClientExceptionsUtil { || cur instanceof RegionTooBusyException || cur instanceof RpcThrottlingException || cur instanceof MultiActionResultTooLarge || cur instanceof RetryImmediatelyException || cur instanceof CallQueueTooBigException || cur instanceof CallDroppedException - || cur instanceof NotServingRegionException || cur instanceof RequestTooBigException); + || cur instanceof NotServingRegionException || cur instanceof RequestTooBigException + || cur instanceof TimeoutIOException || cur instanceof CallTimeoutException); } diff --git a/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestAsyncProcess.java b/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestAsyncProcess.java index 81dcc46f48..c7f50aed74 100644 --- a/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestAsyncProcess.java +++ b/hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestAsyncProcess.java @@ -23,6 +23,7 @@ import static org.junit.Assert.assertTrue; import java.io.IOException; import java.io.InterruptedIOException; +import java.net.ConnectException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -1812,7 +1813,7 @@ public class TestAsyncProcess { myConf.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 0); AsyncProcessWithFailure ap = - new AsyncProcessWithFailure(conn, myConf, new RegionOpeningException("test")); + new AsyncProcessWithFailure(conn, myConf, new ConnectException("test")); BufferedMutatorParams bufferParam = createBufferedMutatorParams(ap, DUMMY_TABLE); BufferedMutatorImpl mutator = new BufferedMutatorImpl(conn, bufferParam, ap); @@ -1836,6 +1837,22 @@ public class TestAsyncProcess { } Mockito.verify(conn, Mockito.times(1)).clearCaches(loc1.getServerName()); + + // Not invoke clearCaches + AsyncProcessWithFailure ap2 = + new AsyncProcessWithFailure(conn, myConf, new RegionOpeningException("test")); + BufferedMutatorImpl mutator2 = new BufferedMutatorImpl(conn, bufferParam, ap2); + Assert.assertNotNull(mutator2.getAsyncProcess().createServerErrorTracker()); + + mutator2.mutate(p); + try { + mutator2.flush(); + Assert.fail(); + } catch (RetriesExhaustedWithDetailsException expected) { + assertEquals(1, expected.getNumExceptions()); + assertTrue(expected.getRow(0) == p); + } + Mockito.verify(conn, Mockito.times(1)).clearCaches(loc1.getServerName()); } @Test