KAFKA-18940: fix electionWasClean (#19156)

The electionWasClean should also consider if the election is done
through ELR. Otherwise, the metric uncleanLeaderElection will wrongly
count the ELR election
https://issues.apache.org/jira/browse/KAFKA-18940

Reviewers: Jun Rao <junrao@gmail.com>
This commit is contained in:
Calvin Liu 2025-03-07 11:04:06 -08:00 committed by Colin P. McCabe
parent 5c0b8bef07
commit d671e7dbc5
3 changed files with 10 additions and 8 deletions

View File

@ -128,7 +128,8 @@ class ControllerMetricsChanges {
isWithoutPreferredLeader = !next.hasPreferredLeader();
// take current all replicas as ISR if prev is null (new created partition), so we won't treat it as unclean election.
int[] prevIsr = prev != null ? prev.isr : next.replicas;
if (!PartitionRegistration.electionWasClean(next.leader, prevIsr)) {
int[] prevElr = prev != null ? prev.elr : new int[]{};
if (!PartitionRegistration.electionWasClean(next.leader, prevIsr, prevElr)) {
uncleanLeaderElection++;
}
}

View File

@ -165,8 +165,8 @@ public class PartitionRegistration {
public final int leaderEpoch;
public final int partitionEpoch;
public static boolean electionWasClean(int newLeader, int[] isr) {
return newLeader == NO_LEADER || Replicas.contains(isr, newLeader);
public static boolean electionWasClean(int newLeader, int[] isr, int[] elr) {
return newLeader == NO_LEADER || Replicas.contains(isr, newLeader) || Replicas.contains(elr, newLeader);
}
private static List<Uuid> checkDirectories(PartitionRecord record) {
@ -347,7 +347,7 @@ public class PartitionRegistration {
}
public void maybeLogPartitionChange(Logger log, String description, PartitionRegistration prev) {
if (!electionWasClean(leader, prev.isr)) {
if (!electionWasClean(leader, prev.isr, prev.elr)) {
log.info("UNCLEAN partition change for {}: {}", description, diff(prev));
} else if (log.isDebugEnabled()) {
log.debug("partition change for {}: {}", description, diff(prev));

View File

@ -58,10 +58,11 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
public class PartitionRegistrationTest {
@Test
public void testElectionWasClean() {
assertTrue(PartitionRegistration.electionWasClean(1, new int[]{1, 2}));
assertFalse(PartitionRegistration.electionWasClean(1, new int[]{0, 2}));
assertFalse(PartitionRegistration.electionWasClean(1, new int[]{}));
assertTrue(PartitionRegistration.electionWasClean(3, new int[]{1, 2, 3, 4, 5, 6}));
assertTrue(PartitionRegistration.electionWasClean(1, new int[]{1, 2}, new int[]{}));
assertFalse(PartitionRegistration.electionWasClean(1, new int[]{0, 2}, new int[]{}));
assertFalse(PartitionRegistration.electionWasClean(1, new int[]{}, new int[]{3, 4}));
assertTrue(PartitionRegistration.electionWasClean(3, new int[]{1, 2, 3, 4, 5, 6}, new int[]{}));
assertTrue(PartitionRegistration.electionWasClean(3, new int[]{}, new int[]{1, 2, 3}));
}
@Test