From 7924ba39e7ce573369deda84f55e2a0e6ecb4872 Mon Sep 17 00:00:00 2001 From: Guanghao Zhang Date: Tue, 15 Oct 2019 11:16:43 +0800 Subject: [PATCH] HBASE-23155 May NPE when concurrent AsyncNonMetaRegionLocator#updateCachedLocationOnError (#718) --- .../hadoop/hbase/client/AsyncNonMetaRegionLocator.java | 3 +++ .../hbase/client/TestAsyncNonMetaRegionLocator.java | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncNonMetaRegionLocator.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncNonMetaRegionLocator.java index db552de83e0..0cdfcdd083c 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncNonMetaRegionLocator.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncNonMetaRegionLocator.java @@ -570,6 +570,9 @@ class AsyncNonMetaRegionLocator { byte[] startKey = loc.getRegion().getStartKey(); for (;;) { RegionLocations oldLocs = tableCache.cache.get(startKey); + if (oldLocs == null) { + return; + } HRegionLocation oldLoc = oldLocs.getRegionLocation(loc.getRegion().getReplicaId()); if (!canUpdateOnError(loc, oldLoc)) { return; diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNonMetaRegionLocator.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNonMetaRegionLocator.java index 559e4a02a28..d1ed5b7cda8 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNonMetaRegionLocator.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNonMetaRegionLocator.java @@ -399,4 +399,14 @@ public class TestAsyncNonMetaRegionLocator { assertArrayEquals(loc.getRegion().getStartKey(), EMPTY_START_ROW); assertArrayEquals(loc.getRegion().getEndKey(), EMPTY_END_ROW); } + + @Test + public void testConcurrentUpdateCachedLocationOnError() throws Exception { + createSingleRegionTable(); + HRegionLocation loc = + getDefaultRegionLocation(TABLE_NAME, EMPTY_START_ROW, RegionLocateType.CURRENT, false) + .get(); + IntStream.range(0, 100).parallel() + .forEach(i -> LOCATOR.updateCachedLocationOnError(loc, new NotServingRegionException())); + } }