Skip to content

fix(inkless:migration): reschedule fetcher on leader change during pending migration - #600

Merged
jeqo merged 1 commit into
mainfrom
giuseppelillo/reschedule-fetcher-pending
May 19, 2026
Merged

fix(inkless:migration): reschedule fetcher on leader change during pending migration#600
jeqo merged 1 commit into
mainfrom
giuseppelillo/reschedule-fetcher-pending

Conversation

@giuseppelillo

Copy link
Copy Markdown
Contributor

During the classic-to-diskless pending window (topic flagged diskless but seal not yet committed) the leader has already sealed its log and frozen its LEO; followers must keep replicating up to that LEO. The diskless branch of applyLocalFollowersDelta only armed a fetcher post-seal, so a leader change mid-PENDING left followers stuck on the previous leader, the new leader saw no follower fetch traffic, and the seal could never be committed.

Capture isNewLeaderEpoch from makeFollower and, for seal == -2, reschedule the ReplicaFetcher on any leader-epoch bump. Once the seal commits, the existing seal >= 0 branch takes over as a bounded catch-up.

…nding migration

During the classic-to-diskless pending window (topic flagged diskless but
seal not yet committed) the leader has already sealed its log and frozen
its LEO; followers must keep replicating up to that LEO. The diskless
branch of applyLocalFollowersDelta only armed a fetcher post-seal, so a
leader change mid-PENDING left followers stuck on the previous leader,
the new leader saw no follower fetch traffic, and the seal could never
be committed.

Capture isNewLeaderEpoch from makeFollower and, for `seal == -2`,
reschedule the ReplicaFetcher on any leader-epoch bump. Once the seal
commits, the existing `seal >= 0` branch takes over as a bounded
catch-up.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a replication stall during classic-to-diskless migration when the partition is in the PENDING window (topic marked diskless, seal offset not yet committed) and the leader changes. The update ensures followers restart their classic ReplicaFetcher when the leader epoch bumps during PENDING so they continue fetching up to the leader’s frozen LEO, allowing the seal to eventually be committed.

Changes:

  • Capture isNewLeaderEpoch from Partition.makeFollower in the diskless-follower path.
  • When seal == CLASSIC_TO_DISKLESS_MIGRATION_PENDING (-2), (re)schedule the classic fetcher on leader-epoch bumps.
  • Replace the prior parameterized test with targeted unit tests covering: never-migrated diskless followers, PENDING scheduling, leader-change rescheduling, and no-op on same epoch.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
core/src/main/scala/kafka/server/ReplicaManager.scala Starts/reschedules classic replica fetchers for diskless followers during migration PENDING when the leader epoch changes.
core/src/test/scala/unit/kafka/server/ReplicaManagerTest.scala Adds focused unit tests to validate fetcher scheduling/rescheduling behavior in PENDING and non-migrated cases.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jeqo
jeqo merged commit 5a17859 into main May 19, 2026
6 checks passed
@jeqo
jeqo deleted the giuseppelillo/reschedule-fetcher-pending branch May 19, 2026 12:46
giuseppelillo added a commit that referenced this pull request May 28, 2026
…nding migration (#600)

During the classic-to-diskless pending window (topic flagged diskless but
seal not yet committed) the leader has already sealed its log and frozen
its LEO; followers must keep replicating up to that LEO. The diskless
branch of applyLocalFollowersDelta only armed a fetcher post-seal, so a
leader change mid-PENDING left followers stuck on the previous leader,
the new leader saw no follower fetch traffic, and the seal could never
be committed.

Capture isNewLeaderEpoch from makeFollower and, for `seal == -2`,
reschedule the ReplicaFetcher on any leader-epoch bump. Once the seal
commits, the existing `seal >= 0` branch takes over as a bounded
catch-up.
giuseppelillo added a commit that referenced this pull request May 29, 2026
…nding migration (#600)

During the classic-to-diskless pending window (topic flagged diskless but
seal not yet committed) the leader has already sealed its log and frozen
its LEO; followers must keep replicating up to that LEO. The diskless
branch of applyLocalFollowersDelta only armed a fetcher post-seal, so a
leader change mid-PENDING left followers stuck on the previous leader,
the new leader saw no follower fetch traffic, and the seal could never
be committed.

Capture isNewLeaderEpoch from makeFollower and, for `seal == -2`,
reschedule the ReplicaFetcher on any leader-epoch bump. Once the seal
commits, the existing `seal >= 0` branch takes over as a bounded
catch-up.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants