Skip to content

Commit b6aef44

Browse files
authored
HBASE-27897 ConnectionImplementation#locateRegionInMeta should pause and retry when taking user region lock failed (#5258)
Signed-off-by: Wellington Chevreuil <[email protected]>
1 parent c7abf17 commit b6aef44

File tree

2 files changed

+18
-13
lines changed

2 files changed

+18
-13
lines changed

hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,9 +1008,12 @@ private RegionLocations locateRegionInMeta(TableName tableName, byte[] row, bool
10081008
}
10091009
// Query the meta region
10101010
long pauseBase = connectionConfig.getPauseMillis();
1011-
takeUserRegionLock();
1012-
final long lockStartTime = EnvironmentEdgeManager.currentTime();
1011+
long lockStartTime = 0;
1012+
boolean lockedUserRegion = false;
10131013
try {
1014+
takeUserRegionLock();
1015+
lockStartTime = EnvironmentEdgeManager.currentTime();
1016+
lockedUserRegion = true;
10141017
// We don't need to check if useCache is enabled or not. Even if useCache is false
10151018
// we already cleared the cache for this row before acquiring userRegion lock so if this
10161019
// row is present in cache that means some other thread has populated it while we were
@@ -1119,10 +1122,12 @@ rpcControllerFactory, getMetaLookupPool(), connectionConfig.getMetaReadRpcTimeou
11191122
ConnectionUtils.getPauseTime(pauseBase, tries), TimeUnit.MILLISECONDS);
11201123
}
11211124
} finally {
1122-
userRegionLock.unlock();
1123-
// update duration of the lock being held
1124-
if (metrics != null) {
1125-
metrics.updateUserRegionLockHeld(EnvironmentEdgeManager.currentTime() - lockStartTime);
1125+
if (lockedUserRegion) {
1126+
userRegionLock.unlock();
1127+
// update duration of the lock being held
1128+
if (metrics != null) {
1129+
metrics.updateUserRegionLockHeld(EnvironmentEdgeManager.currentTime() - lockStartTime);
1130+
}
11261131
}
11271132
}
11281133
try {

hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestMetaCache.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -592,21 +592,21 @@ public void testUserRegionLockThrowsException() throws IOException, InterruptedE
592592
// obtain the client metrics
593593
MetricsConnection metrics = conn.getConnectionMetrics();
594594
long queueCount = metrics.getUserRegionLockQueue().getCount();
595-
assertEquals("Queue of userRegionLock should be updated twice. queueCount: " + queueCount,
596-
queueCount, 2);
595+
assertEquals("Queue of userRegionLock should be updated twice. queueCount: " + queueCount, 2,
596+
queueCount);
597597

598598
long timeoutCount = metrics.getUserRegionLockTimeout().getCount();
599-
assertEquals("Timeout of userRegionLock should happen once. timeoutCount: " + timeoutCount,
600-
timeoutCount, 1);
599+
assertEquals("Timeout of userRegionLock should happen once. timeoutCount: " + timeoutCount, 1,
600+
timeoutCount);
601601

602602
long waitingTimerCount = metrics.getUserRegionLockWaitingTimer().getCount();
603603
assertEquals("userRegionLock should be grabbed successfully once. waitingTimerCount: "
604-
+ waitingTimerCount, waitingTimerCount, 1);
604+
+ waitingTimerCount, 1, waitingTimerCount);
605605

606606
long heldTimerCount = metrics.getUserRegionLockHeldTimer().getCount();
607607
assertEquals(
608-
"userRegionLock should be held successfully once. heldTimerCount: " + heldTimerCount,
609-
heldTimerCount, 1);
608+
"userRegionLock should be held successfully once. heldTimerCount: " + heldTimerCount, 1,
609+
heldTimerCount);
610610
double heldTime = metrics.getUserRegionLockHeldTimer().getSnapshot().getMax();
611611
assertTrue("Max held time should be greater than 2 seconds. heldTime: " + heldTime,
612612
heldTime >= 2E9);

0 commit comments

Comments
 (0)