You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by zh...@apache.org on 2018/04/07 05:43:40 UTC
hbase git commit: HBASE-20182 Can not locate region after split and
merge
Repository: hbase
Updated Branches:
refs/heads/master a422310da -> adc0e85e8
HBASE-20182 Can not locate region after split and merge
Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/adc0e85e
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/adc0e85e
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/adc0e85e
Branch: refs/heads/master
Commit: adc0e85e8532870fa83cb21a44061c83ae77ec34
Parents: a422310
Author: zhangduo <zh...@apache.org>
Authored: Fri Mar 30 17:39:10 2018 +0800
Committer: zhangduo <zh...@apache.org>
Committed: Sat Apr 7 13:37:53 2018 +0800
----------------------------------------------------------------------
.../hbase/client/AsyncNonMetaRegionLocator.java | 90 +++++++-----
.../hbase/client/ConnectionImplementation.java | 147 +++++++++----------
.../org/apache/hadoop/hbase/TestSplitMerge.java | 106 +++++++++++++
...syncNonMetaRegionLocatorConcurrenyLimit.java | 27 ++--
4 files changed, 241 insertions(+), 129 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hbase/blob/adc0e85e/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncNonMetaRegionLocator.java
----------------------------------------------------------------------
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 45d3f52..c30de9a 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
@@ -17,7 +17,6 @@
*/
package org.apache.hadoop.hbase.client;
-import static org.apache.hadoop.hbase.HConstants.CATALOG_FAMILY;
import static org.apache.hadoop.hbase.HConstants.NINES;
import static org.apache.hadoop.hbase.HConstants.ZEROES;
import static org.apache.hadoop.hbase.TableName.META_TABLE_NAME;
@@ -32,7 +31,6 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
-import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
@@ -41,13 +39,14 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
-
import org.apache.hadoop.hbase.DoNotRetryIOException;
+import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionLocation;
import org.apache.hadoop.hbase.MetaTableAccessor;
import org.apache.hadoop.hbase.RegionLocations;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.TableNotFoundException;
+import org.apache.hadoop.hbase.client.Scan.ReadType;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.yetus.audience.InterfaceAudience;
import org.slf4j.Logger;
@@ -269,26 +268,22 @@ class AsyncNonMetaRegionLocator {
toSend.ifPresent(r -> locateInMeta(tableName, r));
}
- private void onScanComplete(TableName tableName, LocateRequest req, List<Result> results,
+ // return whether we should stop the scan
+ private boolean onScanNext(TableName tableName, LocateRequest req, Result result,
Throwable error) {
if (error != null) {
complete(tableName, req, null, error);
- return;
- }
- if (results.isEmpty()) {
- complete(tableName, req, null, new TableNotFoundException(tableName));
- return;
- }
- RegionLocations locs = MetaTableAccessor.getRegionLocations(results.get(0));
- if (LOG.isDebugEnabled()) {
- LOG.debug("The fetched location of '" + tableName + "', row='" +
- Bytes.toStringBinary(req.row) + "', locateType=" + req.locateType + " is " + locs);
+ return true;
}
+ RegionLocations locs = MetaTableAccessor.getRegionLocations(result);
+ LOG.debug("The fetched location of '{}', row='{}', locateType={} is {}", tableName,
+ Bytes.toStringBinary(req.row), req.locateType, locs);
+
if (locs == null || locs.getDefaultRegionLocation() == null) {
complete(tableName, req, null,
new IOException(String.format("No location found for '%s', row='%s', locateType=%s",
tableName, Bytes.toStringBinary(req.row), req.locateType)));
- return;
+ return true;
}
HRegionLocation loc = locs.getDefaultRegionLocation();
RegionInfo info = loc.getRegion();
@@ -296,33 +291,20 @@ class AsyncNonMetaRegionLocator {
complete(tableName, req, null,
new IOException(String.format("HRegionInfo is null for '%s', row='%s', locateType=%s",
tableName, Bytes.toStringBinary(req.row), req.locateType)));
- return;
- }
- if (!info.getTable().equals(tableName)) {
- complete(tableName, req, null, new TableNotFoundException(
- "Table '" + tableName + "' was not found, got: '" + info.getTable() + "'"));
- return;
- }
- if (info.isSplit()) {
- complete(tableName, req, null,
- new RegionOfflineException(
- "the only available region for the required row is a split parent," +
- " the daughters should be online soon: '" + info.getRegionNameAsString() + "'"));
- return;
+ return true;
}
- if (info.isOffline()) {
- complete(tableName, req, null, new RegionOfflineException("the region is offline, could" +
- " be caused by a disable table call: '" + info.getRegionNameAsString() + "'"));
- return;
+ if (info.isSplitParent()) {
+ return false;
}
if (loc.getServerName() == null) {
complete(tableName, req, null,
new NoServerForRegionException(
String.format("No server address listed for region '%s', row='%s', locateType=%s",
info.getRegionNameAsString(), Bytes.toStringBinary(req.row), req.locateType)));
- return;
+ return true;
}
complete(tableName, req, loc, null);
+ return true;
}
private HRegionLocation locateRowInCache(TableCache tableCache, TableName tableName, byte[] row) {
@@ -368,21 +350,49 @@ class AsyncNonMetaRegionLocator {
LOG.trace("Try locate '" + tableName + "', row='" + Bytes.toStringBinary(req.row) +
"', locateType=" + req.locateType + " in meta");
}
- byte[] metaKey;
+ byte[] metaStartKey;
if (req.locateType.equals(RegionLocateType.BEFORE)) {
if (isEmptyStopRow(req.row)) {
byte[] binaryTableName = tableName.getName();
- metaKey = Arrays.copyOf(binaryTableName, binaryTableName.length + 1);
+ metaStartKey = Arrays.copyOf(binaryTableName, binaryTableName.length + 1);
} else {
- metaKey = createRegionName(tableName, req.row, ZEROES, false);
+ metaStartKey = createRegionName(tableName, req.row, ZEROES, false);
}
} else {
- metaKey = createRegionName(tableName, req.row, NINES, false);
+ metaStartKey = createRegionName(tableName, req.row, NINES, false);
}
+ byte[] metaStopKey =
+ RegionInfo.createRegionName(tableName, HConstants.EMPTY_START_ROW, "", false);
conn.getTable(META_TABLE_NAME)
- .scanAll(new Scan().withStartRow(metaKey).setReversed(true).addFamily(CATALOG_FAMILY)
- .setOneRowLimit())
- .whenComplete((results, error) -> onScanComplete(tableName, req, results, error));
+ .scan(new Scan().withStartRow(metaStartKey).withStopRow(metaStopKey, true)
+ .addFamily(HConstants.CATALOG_FAMILY).setReversed(true).setCaching(5)
+ .setReadType(ReadType.PREAD), new AdvancedScanResultConsumer() {
+
+ private boolean completeNormally = false;
+
+ @Override
+ public void onError(Throwable error) {
+ onScanNext(tableName, req, null, error);
+ }
+
+ @Override
+ public void onComplete() {
+ if (!completeNormally) {
+ onScanNext(tableName, req, null, new TableNotFoundException(tableName));
+ }
+ }
+
+ @Override
+ public void onNext(Result[] results, ScanController controller) {
+ for (Result result : results) {
+ if (onScanNext(tableName, req, result, null)) {
+ completeNormally = true;
+ controller.terminate();
+ return;
+ }
+ }
+ }
+ });
}
private HRegionLocation locateInCache(TableCache tableCache, TableName tableName, byte[] row,
http://git-wip-us.apache.org/repos/asf/hbase/blob/adc0e85e/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java
----------------------------------------------------------------------
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java
index 7723161..a272ffb 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java
@@ -58,6 +58,7 @@ import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.TableNotEnabledException;
import org.apache.hadoop.hbase.TableNotFoundException;
import org.apache.hadoop.hbase.ZooKeeperConnectionException;
+import org.apache.hadoop.hbase.client.Scan.ReadType;
import org.apache.hadoop.hbase.client.backoff.ClientBackoffPolicy;
import org.apache.hadoop.hbase.client.backoff.ClientBackoffPolicyFactory;
import org.apache.hadoop.hbase.exceptions.ClientExceptionsUtil;
@@ -771,41 +772,34 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
return locations;
}
- /*
- * Search the hbase:meta table for the HRegionLocation
- * info that contains the table and row we're seeking.
- */
- private RegionLocations locateRegionInMeta(TableName tableName, byte[] row,
- boolean useCache, boolean retry, int replicaId) throws IOException {
-
- // If we are supposed to be using the cache, look in the cache to see if
- // we already have the region.
+ /**
+ * Search the hbase:meta table for the HRegionLocation info that contains the table and row we're
+ * seeking.
+ */
+ private RegionLocations locateRegionInMeta(TableName tableName, byte[] row, boolean useCache,
+ boolean retry, int replicaId) throws IOException {
+ // If we are supposed to be using the cache, look in the cache to see if we already have the
+ // region.
if (useCache) {
RegionLocations locations = getCachedLocation(tableName, row);
if (locations != null && locations.getRegionLocation(replicaId) != null) {
return locations;
}
}
-
// build the key of the meta region we should be looking for.
// the extra 9's on the end are necessary to allow "exact" matches
// without knowing the precise region names.
byte[] metaStartKey = RegionInfo.createRegionName(tableName, row, HConstants.NINES, false);
byte[] metaStopKey =
RegionInfo.createRegionName(tableName, HConstants.EMPTY_START_ROW, "", false);
-
- Scan s = new Scan();
- s.setReversed(true);
- s.withStartRow(metaStartKey);
- s.withStopRow(metaStopKey, true);
- s.addFamily(HConstants.CATALOG_FAMILY);
-
+ Scan s = new Scan().withStartRow(metaStartKey).withStopRow(metaStopKey, true)
+ .addFamily(HConstants.CATALOG_FAMILY).setReversed(true).setCaching(5)
+ .setReadType(ReadType.PREAD);
if (this.useMetaReplicas) {
s.setConsistency(Consistency.TIMELINE);
}
-
int maxAttempts = (retry ? numTries : 1);
- for (int tries = 0; true; tries++) {
+ for (int tries = 0; ; tries++) {
if (tries >= maxAttempts) {
throw new NoServerForRegionException("Unable to find region for "
+ Bytes.toStringBinary(row) + " in " + tableName + " after " + tries + " tries.");
@@ -821,7 +815,6 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
// We are only supposed to clean the cache for the specific replicaId
metaCache.clearCache(tableName, row, replicaId);
}
-
// Query the meta region
long pauseBase = this.pause;
userRegionLock.lock();
@@ -832,60 +825,64 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
return locations;
}
}
- Result regionInfoRow = null;
s.resetMvccReadPoint();
- s.setOneRowLimit();
try (ReversedClientScanner rcs =
- new ReversedClientScanner(conf, s, TableName.META_TABLE_NAME, this, rpcCallerFactory,
- rpcControllerFactory, getMetaLookupPool(), metaReplicaCallTimeoutScanInMicroSecond)) {
- regionInfoRow = rcs.next();
- }
-
- if (regionInfoRow == null) {
- throw new TableNotFoundException(tableName);
- }
- // convert the row result into the HRegionLocation we need!
- RegionLocations locations = MetaTableAccessor.getRegionLocations(regionInfoRow);
- if (locations == null || locations.getRegionLocation(replicaId) == null) {
- throw new IOException("RegionInfo null in " + tableName + ", row=" + regionInfoRow);
- }
- RegionInfo regionInfo = locations.getRegionLocation(replicaId).getRegion();
- if (regionInfo == null) {
- throw new IOException("RegionInfo null or empty in " +
- TableName.META_TABLE_NAME + ", row=" + regionInfoRow);
- }
-
- // possible we got a region of a different table...
- if (!regionInfo.getTable().equals(tableName)) {
- throw new TableNotFoundException(
- "Region of '" + regionInfo.getRegionNameAsString() + "' is expected in the table of '" + tableName + "', " +
- "but hbase:meta says it is in the table of '" + regionInfo.getTable() + "'. " +
- "hbase:meta might be damaged.");
- }
- if (regionInfo.isSplit()) {
- throw new RegionOfflineException ("Region for row is a split parent, daughters not online: " +
- regionInfo.getRegionNameAsString());
- }
- if (regionInfo.isOffline()) {
- throw new RegionOfflineException("Region offline; 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));
- }
-
- if (isDeadServer(serverName)){
- throw new RegionServerStoppedException("hbase:meta says the region "+
- regionInfo.getRegionNameAsString()+" is managed by the server " + serverName +
- ", but it is dead.");
+ new ReversedClientScanner(conf, s, TableName.META_TABLE_NAME, this, rpcCallerFactory,
+ rpcControllerFactory, getMetaLookupPool(), metaReplicaCallTimeoutScanInMicroSecond)) {
+ boolean tableNotFound = true;
+ for (;;) {
+ Result regionInfoRow = rcs.next();
+ if (regionInfoRow == null) {
+ if (tableNotFound) {
+ throw new TableNotFoundException(tableName);
+ } else {
+ throw new NoServerForRegionException(
+ "Unable to find region for " + Bytes.toStringBinary(row) + " in " + tableName);
+ }
+ }
+ tableNotFound = false;
+ // convert the row result into the HRegionLocation we need!
+ RegionLocations locations = MetaTableAccessor.getRegionLocations(regionInfoRow);
+ if (locations == null || locations.getRegionLocation(replicaId) == null) {
+ throw new IOException("RegionInfo null in " + tableName + ", row=" + regionInfoRow);
+ }
+ RegionInfo regionInfo = locations.getRegionLocation(replicaId).getRegion();
+ if (regionInfo == null) {
+ throw new IOException("RegionInfo null or empty in " + TableName.META_TABLE_NAME +
+ ", row=" + regionInfoRow);
+ }
+ // See HBASE-20182. It is possible that we locate to a split parent even after the
+ // children are online, so here we need to skip this region and go to the next one.
+ if (regionInfo.isSplitParent()) {
+ continue;
+ }
+ if (regionInfo.isOffline()) {
+ throw new RegionOfflineException("Region offline; disable table call? " +
+ regionInfo.getRegionNameAsString());
+ }
+ // It is possible that the split children have not been online yet and we have skipped
+ // the parent in the above condition, so we may have already reached a region which does
+ // not contains us.
+ if (!regionInfo.containsRow(row)) {
+ throw new NoServerForRegionException(
+ "Unable to find region for " + Bytes.toStringBinary(row) + " in " + tableName);
+ }
+ 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));
+ }
+ if (isDeadServer(serverName)) {
+ throw new RegionServerStoppedException(
+ "hbase:meta says the region " + regionInfo.getRegionNameAsString() +
+ " is managed by the server " + serverName + ", but it is dead.");
+ }
+ // Instantiate the location
+ cacheLocation(tableName, locations);
+ return locations;
+ }
}
- // Instantiate the location
- cacheLocation(tableName, locations);
- return locations;
} catch (TableNotFoundException e) {
// if we got this error, probably means the table just plain doesn't
// exist. rethrow the error immediately. this should always be coming
@@ -901,12 +898,8 @@ class ConnectionImplementation implements ClusterConnection, Closeable {
pauseBase = this.pauseForCQTBE;
}
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='{}', attempt={} of {} failed; retrying " +
+ "after sleep of {}", TableName.META_TABLE_NAME, tries, maxAttempts, maxAttempts, e);
} else {
throw e;
}
http://git-wip-us.apache.org/repos/asf/hbase/blob/adc0e85e/hbase-server/src/test/java/org/apache/hadoop/hbase/TestSplitMerge.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/TestSplitMerge.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/TestSplitMerge.java
new file mode 100644
index 0000000..5f96678
--- /dev/null
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/TestSplitMerge.java
@@ -0,0 +1,106 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.concurrent.TimeUnit;
+import org.apache.hadoop.hbase.Waiter.ExplainingPredicate;
+import org.apache.hadoop.hbase.client.AsyncConnection;
+import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
+import org.apache.hadoop.hbase.client.ConnectionFactory;
+import org.apache.hadoop.hbase.client.RegionInfo;
+import org.apache.hadoop.hbase.client.TableDescriptor;
+import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
+import org.apache.hadoop.hbase.testclassification.MediumTests;
+import org.apache.hadoop.hbase.testclassification.MiscTests;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+@Category({ MiscTests.class, MediumTests.class })
+public class TestSplitMerge {
+
+ @ClassRule
+ public static final HBaseClassTestRule CLASS_RULE =
+ HBaseClassTestRule.forClass(TestSplitMerge.class);
+
+ private static final HBaseTestingUtility UTIL = new HBaseTestingUtility();
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_META_OPERATION_TIMEOUT, 1000);
+ UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 2);
+ UTIL.startMiniCluster(1);
+ }
+
+ @AfterClass
+ public static void tearDown() throws Exception {
+ UTIL.shutdownMiniCluster();
+ }
+
+ @Test
+ public void test() throws Exception {
+ TableName tableName = TableName.valueOf("SplitMerge");
+ byte[] family = Bytes.toBytes("CF");
+ TableDescriptor td = TableDescriptorBuilder.newBuilder(tableName)
+ .setColumnFamily(ColumnFamilyDescriptorBuilder.of(family)).build();
+ UTIL.getAdmin().createTable(td, new byte[][] { Bytes.toBytes(1) });
+ UTIL.waitTableAvailable(tableName);
+ UTIL.getAdmin().split(tableName, Bytes.toBytes(2));
+ UTIL.waitFor(30000, new ExplainingPredicate<Exception>() {
+
+ @Override
+ public boolean evaluate() throws Exception {
+ return UTIL.getMiniHBaseCluster().getRegions(tableName).size() == 3;
+ }
+
+ @Override
+ public String explainFailure() throws Exception {
+ return "Split has not finished yet";
+ }
+ });
+ RegionInfo regionA = null;
+ RegionInfo regionB = null;
+ for (RegionInfo region : UTIL.getAdmin().getRegions(tableName)) {
+ if (region.getStartKey().length == 0) {
+ regionA = region;
+ } else if (Bytes.equals(region.getStartKey(), Bytes.toBytes(1))) {
+ regionB = region;
+ }
+ }
+ assertNotNull(regionA);
+ assertNotNull(regionB);
+ UTIL.getAdmin().mergeRegionsAsync(regionA.getRegionName(), regionB.getRegionName(), false)
+ .get(30, TimeUnit.SECONDS);
+ assertEquals(2, UTIL.getAdmin().getRegions(tableName).size());
+
+ ServerName expected = UTIL.getMiniHBaseCluster().getRegionServer(0).getServerName();
+ assertEquals(expected, UTIL.getConnection().getRegionLocator(tableName)
+ .getRegionLocation(Bytes.toBytes(1), true).getServerName());
+ try (AsyncConnection asyncConn =
+ ConnectionFactory.createAsyncConnection(UTIL.getConfiguration()).get()) {
+ assertEquals(expected, asyncConn.getRegionLocator(tableName)
+ .getRegionLocation(Bytes.toBytes(1), true).get().getServerName());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/hbase/blob/adc0e85e/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNonMetaRegionLocatorConcurrenyLimit.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNonMetaRegionLocatorConcurrenyLimit.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNonMetaRegionLocatorConcurrenyLimit.java
index f31fbfa..c6624e7 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNonMetaRegionLocatorConcurrenyLimit.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNonMetaRegionLocatorConcurrenyLimit.java
@@ -87,9 +87,9 @@ public class TestAsyncNonMetaRegionLocatorConcurrenyLimit {
}
@Override
- public void preScannerOpen(ObserverContext<RegionCoprocessorEnvironment> e, Scan scan)
- throws IOException {
- if (e.getEnvironment().getRegionInfo().isMetaRegion()) {
+ public boolean preScannerNext(ObserverContext<RegionCoprocessorEnvironment> c,
+ InternalScanner s, List<Result> result, int limit, boolean hasNext) throws IOException {
+ if (c.getEnvironment().getRegionInfo().isMetaRegion()) {
int concurrency = CONCURRENCY.incrementAndGet();
for (;;) {
int max = MAX_CONCURRENCY.get();
@@ -102,14 +102,16 @@ public class TestAsyncNonMetaRegionLocatorConcurrenyLimit {
}
Threads.sleepWithoutInterrupt(10);
}
+ return hasNext;
}
@Override
- public void postScannerClose(ObserverContext<RegionCoprocessorEnvironment> e, InternalScanner s)
- throws IOException {
- if (e.getEnvironment().getRegionInfo().isMetaRegion()) {
+ public boolean postScannerNext(ObserverContext<RegionCoprocessorEnvironment> c,
+ InternalScanner s, List<Result> result, int limit, boolean hasNext) throws IOException {
+ if (c.getEnvironment().getRegionInfo().isMetaRegion()) {
CONCURRENCY.decrementAndGet();
}
+ return hasNext;
}
}
@@ -119,7 +121,7 @@ public class TestAsyncNonMetaRegionLocatorConcurrenyLimit {
conf.set(REGION_COPROCESSOR_CONF_KEY, CountingRegionObserver.class.getName());
conf.setInt(MAX_CONCURRENT_LOCATE_REQUEST_PER_TABLE, MAX_ALLOWED);
TEST_UTIL.startMiniCluster(3);
- TEST_UTIL.getAdmin().setBalancerRunning(false, true);
+ TEST_UTIL.getAdmin().balancerSwitch(false, true);
AsyncRegistry registry = AsyncRegistryFactory.getRegistry(TEST_UTIL.getConfiguration());
CONN = new AsyncConnectionImpl(TEST_UTIL.getConfiguration(), registry,
registry.getClusterId().get(), User.getCurrent());
@@ -142,14 +144,14 @@ public class TestAsyncNonMetaRegionLocatorConcurrenyLimit {
for (int i = 0; i < futures.size(); i++) {
HRegionLocation loc = futures.get(i).get();
if (i == 0) {
- assertTrue(isEmptyStartRow(loc.getRegionInfo().getStartKey()));
+ assertTrue(isEmptyStartRow(loc.getRegion().getStartKey()));
} else {
- assertEquals(String.format("%02x", i), Bytes.toString(loc.getRegionInfo().getStartKey()));
+ assertEquals(String.format("%02x", i), Bytes.toString(loc.getRegion().getStartKey()));
}
if (i == futures.size() - 1) {
- assertTrue(isEmptyStopRow(loc.getRegionInfo().getEndKey()));
+ assertTrue(isEmptyStopRow(loc.getRegion().getEndKey()));
} else {
- assertEquals(String.format("%02x", i + 1), Bytes.toString(loc.getRegionInfo().getEndKey()));
+ assertEquals(String.format("%02x", i + 1), Bytes.toString(loc.getRegion().getEndKey()));
}
}
}
@@ -161,6 +163,7 @@ public class TestAsyncNonMetaRegionLocatorConcurrenyLimit {
.map(r -> LOCATOR.getRegionLocation(TABLE_NAME, r, RegionLocateType.CURRENT, false))
.collect(toList());
assertLocs(futures);
- assertTrue(MAX_CONCURRENCY.get() <= MAX_ALLOWED);
+ assertTrue("max allowed is " + MAX_ALLOWED + " but actual is " + MAX_CONCURRENCY.get(),
+ MAX_CONCURRENCY.get() <= MAX_ALLOWED);
}
}