Skip to content

Commit c6962ca

Browse files
committed
resolve conflicts
1 parent e1831b7 commit c6962ca

2 files changed

Lines changed: 25 additions & 29 deletions

File tree

hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/RegionInTransitionTracker.java

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818
package org.apache.hadoop.hbase.master.assignment;
1919

20+
import com.google.errorprone.annotations.RestrictedApi;
2021
import java.util.ArrayList;
2122
import java.util.List;
2223
import java.util.Objects;
@@ -39,34 +40,30 @@
3940
@InterfaceAudience.Private
4041
public class RegionInTransitionTracker {
4142
private static final Logger LOG = LoggerFactory.getLogger(RegionInTransitionTracker.class);
42-
private static final LongConsumer NOOP_RIT_DURATION_CONSUMER = ignored -> {
43-
};
4443

4544
private static final List<RegionState.State> DISABLE_TABLE_REGION_STATE =
4645
List.of(RegionState.State.OFFLINE, RegionState.State.CLOSED);
4746

4847
private static final List<RegionState.State> ENABLE_TABLE_REGION_STATE =
4948
List.of(RegionState.State.OPEN);
5049

51-
// DO NOT USE containsKey()/remove() on regionInTransition with a different RegionInfo instance:
52-
// this map is ordered by RegionInfo.COMPARATOR, and that comparator includes the offline flag.
53-
// Lookups can therefore fail if the RegionInfo used as the key has a different offline value,
54-
// even when it refers to the same region. Offline value changes with splitting.
50+
// DO NOT USE containsKey()/remove() on regionInTransition with a RegionInfo instance whose
51+
// offline flag differs from the one stored as the key: RegionInfo#equals and #hashCode both
52+
// include the offline flag, so such a lookup misses even when it refers to the same region.
53+
// Offline value changes with splitting.
5554
private final ConcurrentHashMap<RegionInfo, Pair<RegionStateNode, Long>> regionInTransition =
5655
new ConcurrentHashMap<>();
5756

5857
private final LongConsumer ritDurationConsumer;
5958
private TableStateManager tableStateManager;
6059

61-
public RegionInTransitionTracker() {
62-
this(NOOP_RIT_DURATION_CONSUMER);
63-
}
64-
6560
public RegionInTransitionTracker(LongConsumer ritDurationConsumer) {
6661
this.ritDurationConsumer = Objects.requireNonNull(ritDurationConsumer);
6762
}
6863

69-
public boolean isRegionInTransition(final RegionInfo regionInfo) {
64+
@RestrictedApi(explanation = "Should only be called in tests", link = "",
65+
allowedOnPath = ".*/src/test/.*")
66+
boolean isRegionInTransition(final RegionInfo regionInfo) {
7067
return regionInTransition.containsKey(regionInfo);
7168
}
7269

@@ -75,11 +72,10 @@ public boolean isRegionInTransition(final RegionInfo regionInfo) {
7572
* it was hosting are automatically added to the RIT list since they need to be reassigned to
7673
* other servers.
7774
* @param regionStateNode the region whose hosting server crashed
78-
* @param crashTime the time the hosting server crashed, used as the RIT start time. We take
79-
* it explicitly instead of reading {@link RegionStateNode#getLastUpdate()}
80-
* because the latter is masked by a stale procedure that may still be
81-
* attached from before the server died, which would anchor the duration at
82-
* the wrong time. A non-positive value falls back to the node's last
75+
* @param crashTime the RIT start time to use when the region is not already in transition
76+
* (an existing entry keeps its earlier start). Passed explicitly rather
77+
* than read from {@link RegionStateNode#getLastUpdate()}, which a stale
78+
* procedure can mask. A non-positive value falls back to the node's last
8379
* update.
8480
*/
8581
public void regionCrashed(RegionStateNode regionStateNode, long crashTime) {
@@ -171,7 +167,7 @@ private boolean removeRegionInTransition(final RegionInfo regionInfo) {
171167
Pair<RegionStateNode, Long> removed = regionInTransition.remove(regionInfo);
172168
if (removed != null) {
173169
long duration = EnvironmentEdgeManager.currentTime() - removed.getSecond();
174-
if (duration > 0) {
170+
if (duration >= 0) {
175171
ritDurationConsumer.accept(duration);
176172
}
177173
}
@@ -205,5 +201,4 @@ public void setTableStateManager(TableStateManager tableStateManager) {
205201
private static boolean isReplica(RegionStateNode regionStateNode) {
206202
return regionStateNode.getRegionInfo().getReplicaId() != RegionInfo.DEFAULT_REPLICA_ID;
207203
}
208-
209204
}

hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestAssignmentManagerRitDurationMetrics.java

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.apache.hadoop.hbase.TableName;
2727
import org.apache.hadoop.hbase.client.RegionInfo;
2828
import org.apache.hadoop.hbase.client.Table;
29+
import org.apache.hadoop.hbase.master.assignment.AssignmentTestingUtil;
2930
import org.apache.hadoop.hbase.testclassification.MasterTests;
3031
import org.apache.hadoop.hbase.testclassification.MediumTests;
3132
import org.apache.hadoop.hbase.util.Bytes;
@@ -49,7 +50,6 @@ public class TestAssignmentManagerRitDurationMetrics {
4950

5051
private static HMaster MASTER;
5152
private static final String RIT_DURATION_NUM_OPS_METRIC = "RitDuration_num_ops";
52-
private static final String RIT_DURATION_MAX_METRIC = "RitDuration_max";
5353

5454
@BeforeAll
5555
public static void startCluster() throws Exception {
@@ -69,7 +69,7 @@ public void testRitDurationHistogramMetric(TestInfo testInfo) throws Exception {
6969
RegionInfo regionInfo =
7070
MASTER.getAssignmentManager().getRegionStates().getRegionsOfTable(tableName).get(0);
7171
TEST_UTIL.waitFor(WAIT_TIMEOUT_MS,
72-
() -> !MASTER.getAssignmentManager().isRegionInTransition(regionInfo)
72+
() -> !AssignmentTestingUtil.isRegionInTransition(regionInfo, MASTER.getAssignmentManager())
7373
&& MASTER.getAssignmentManager().getRegionStates().getRegionServerOfRegion(regionInfo)
7474
!= null);
7575

@@ -85,16 +85,17 @@ public void testRitDurationHistogramMetric(TestInfo testInfo) throws Exception {
8585
.orElseThrow(() -> new IllegalStateException("Need at least two regionservers"));
8686

8787
TEST_UTIL.getAdmin().move(regionInfo.getEncodedNameAsBytes(), target);
88-
TEST_UTIL.waitFor(WAIT_TIMEOUT_MS,
89-
() -> target.equals(
90-
MASTER.getAssignmentManager().getRegionStates().getRegionServerOfRegion(regionInfo))
91-
&& !MASTER.getAssignmentManager().isRegionInTransition(regionInfo));
88+
TEST_UTIL.waitFor(WAIT_TIMEOUT_MS, () -> target
89+
.equals(MASTER.getAssignmentManager().getRegionStates().getRegionServerOfRegion(regionInfo))
90+
&& !AssignmentTestingUtil.isRegionInTransition(regionInfo, MASTER.getAssignmentManager()));
9291

93-
MetricsRecord metricsRecord = snapshotMetrics(amSource);
94-
assertEquals(ritDurationNumOps + 1,
95-
getMetricValue(metricsRecord, RIT_DURATION_NUM_OPS_METRIC));
96-
assertTrue(getMetricValue(metricsRecord, RIT_DURATION_MAX_METRIC) > 0,
97-
"ritDuration histogram should export a positive max value");
92+
// num_ops is cumulative (never reset on snapshot); an increase proves the histogram is now
93+
// fed on RIT completion. Use >= not ==: background RIT may also add. _max is not asserted --
94+
// snapshot() resets it on every read, racing the metrics2 sampler.
95+
long ritDurationNumOpsAfter =
96+
getMetricValue(snapshotMetrics(amSource), RIT_DURATION_NUM_OPS_METRIC);
97+
assertTrue(ritDurationNumOpsAfter >= ritDurationNumOps + 1,
98+
"RitDuration histogram num_ops should increase after a region transition");
9899
}
99100
}
100101

0 commit comments

Comments
 (0)