This is an automated email from the ASF dual-hosted git repository.
clintropolis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git
The following commit(s) were added to refs/heads/master by this push:
new 65c3ec382f4 fix: replica counting fix for partial load reverts (#19912)
65c3ec382f4 is described below
commit 65c3ec382f4c7a8a7fd3133f6ecd2ceeb0b18c11
Author: Clint Wylie <[email protected]>
AuthorDate: Thu Aug 6 19:01:33 2026 -0700
fix: replica counting fix for partial load reverts (#19912)
---
.../loading/SegmentReplicaCountMap.java | 30 +++++++++++++++++-----
1 file changed, 24 insertions(+), 6 deletions(-)
diff --git
a/server/src/main/java/org/apache/druid/server/coordinator/loading/SegmentReplicaCountMap.java
b/server/src/main/java/org/apache/druid/server/coordinator/loading/SegmentReplicaCountMap.java
index df694086885..7058c261d88 100644
---
a/server/src/main/java/org/apache/druid/server/coordinator/loading/SegmentReplicaCountMap.java
+++
b/server/src/main/java/org/apache/druid/server/coordinator/loading/SegmentReplicaCountMap.java
@@ -23,6 +23,7 @@ import com.google.common.collect.Sets;
import org.apache.druid.client.DataSegmentAndLoadProfile;
import org.apache.druid.client.ImmutableDruidServer;
import org.apache.druid.server.coordinator.DruidCluster;
+import org.apache.druid.server.coordinator.ServerHolder;
import org.apache.druid.timeline.DataSegment;
import org.apache.druid.timeline.SegmentId;
@@ -55,13 +56,13 @@ public class SegmentReplicaCountMap
serverHolder -> {
// Add segments already loaded on this server.
final Collection<DataSegment> servedSegments =
serverHolder.getServedSegments();
- final Set<SegmentId> servedSegmentIds =
Sets.newHashSetWithExpectedSize(servedSegments.size());
+ final Set<SegmentId> partiallyLoadedIds =
Sets.newHashSetWithExpectedSize(servedSegments.size());
for (DataSegment segment : servedSegments) {
- servedSegmentIds.add(segment.getId());
final SegmentReplicaCount replicaCount =
computeIfAbsent(segment.getId(), tier);
if (DataSegmentAndLoadProfile.profileOf(segment) == null) {
replicaCount.incrementLoaded();
} else {
+ partiallyLoadedIds.add(segment.getId());
replicaCount.incrementLoadedWithPartialProfile();
}
}
@@ -69,10 +70,7 @@ public class SegmentReplicaCountMap
// Add segments queued for load, drop or move on this server
serverHolder.getQueuedSegments().forEach(
(segment, state) -> {
- // A load queued on a server that is already serving the
segment is an in-place reload, not an
- // additional replica: the replica exists and was counted
above, and the reload only changes which
- // parts of it the server holds.
- if (state == SegmentAction.LOAD &&
servedSegmentIds.contains(segment.getId())) {
+ if (isPartialLoadRevert(serverHolder, segment, state,
partiallyLoadedIds)) {
return;
}
computeIfAbsent(segment.getId(),
tier).incrementQueued(state);
@@ -99,6 +97,26 @@ public class SegmentReplicaCountMap
});
}
+ /**
+ * Whether a queued operation is the in-place reload that
+ * {@link StrategicSegmentAssigner#revertPartialProfileReplica} queues to
release a partial-load rule that no longer
+ * applies. Such a reload refreshes an existing replica rather than adding
one, so counting it as {@code loading}
+ * would push {@code projectedReplicas} past the requirement; {@code
updateReplicasInTier} would then "correct" the
+ * phantom surplus by canceling the very reload it queued last run, and
requeue it in the same run, churning
+ * forever against a backlogged peon.
+ */
+ private static boolean isPartialLoadRevert(
+ ServerHolder serverHolder,
+ DataSegment segment,
+ SegmentAction state,
+ Set<SegmentId> partiallyLoadedIds
+ )
+ {
+ return state == SegmentAction.LOAD
+ && partiallyLoadedIds.contains(segment.getId())
+ && serverHolder.getInFlightProfile(segment) == null;
+ }
+
SegmentReplicaCount get(SegmentId segmentId, String tier)
{
SegmentReplicaCount count = replicaCounts.getOrDefault(segmentId,
Collections.emptyMap())
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]