fix(tern): settle grouped applies when the engine loses in-flight work - #1192
Open
aparajon wants to merge 3 commits into
Open
fix(tern): settle grouped applies when the engine loses in-flight work#1192aparajon wants to merge 3 commits into
aparajon wants to merge 3 commits into
Conversation
The grouped drive now detects the same engine-vs-storage divergence the sequential drive settles: a progress poll reporting no active schema change while stored tasks are in flight. One apply-level tracker spends the engine-declared trust budget (zero for engines with synchronous work registration), then each in-flight task settles from one shared re-plan of the reviewed schema set — completed when its change already landed, retryable when the target still needs it, and revert-phase tasks always retryable because a schema read cannot settle a revert. Verification failures count against the same bounded consecutive-error budget as failed polls, pausing the apply retryable when exhausted instead of polling forever and holding the database's active-apply slot. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR extends the “lost engine in-flight work” settlement mechanism (introduced for the sequential drive) to the grouped/atomic drive path (Vitess applies and MySQL defer_cutover), preventing applies from polling pending forever when the engine forgets accepted work and continuing to hold the database’s active-apply slot.
Changes:
- Add grouped-drive detection of “engine reports pending/no active work while durable tasks are in-flight” and apply a bounded trust budget before settling from the target schema.
- Settle grouped in-flight tasks using a single shared re-plan of the reviewed schema set; revert-phase tasks are always settled retryable without reading the target.
- Add focused grouped-drive progress tests covering converged targets, non-converged targets, bounded verification failures, self-healing stale snapshots, and revert-phase behavior.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| pkg/tern/local_control_resume.go | Extracts a reusable helper to re-plan the reviewed schema set against the live target and index remaining changes by (namespace, shard, table). |
| pkg/tern/local_apply_sequential.go | Refactors lost-work settlement into clearer helpers reused by grouped settlement; adds lost-work tracking state for shared polling structures. |
| pkg/tern/local_apply_grouped.go | Implements grouped/atomic lost-work detection with a trust budget and per-task settlement driven by a shared target re-plan. |
| pkg/tern/local_apply_grouped_progress_test.go | Adds test coverage for grouped lost-work detection and settlement outcomes, including revert-phase handling and bounded verification errors. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…it holds The table field carried an engine task-state string but was named for engine.State, which reads as a different type than the one the helper takes. Name it after the parameter it feeds.
…ified A revert-phase task settles without reading the target, so an unreadable plan must not strand it alongside the tasks that do need verifying. The mixed case was documented but unproven: every existing case had either all revert-phase tasks or a readable plan, so nothing failed if the revert settlement moved behind the plan load.
aparajon
marked this pull request as ready for review
August 29, 2026 16:29
aparajon
requested review from
JashLal,
Kiran01bm,
eeSeeGee,
jayjanssen,
jemiahw and
morgo
as code owners
August 29, 2026 16:29
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why this matters
Follow-up to #1113, which settled lost engine work for the sequential drive only. The grouped drive — all Vitess applies, and MySQL under
defer_cutover— had no equivalent: an engine that lost its in-flight work kept answering progress polls with "no active schema change", which maps to pending, so the drive polled forever and the apply never left running. It held the database's active-apply slot for as long as the process lived, queueing every later change to that database behind work that no longer existed.What it does
An engine reports "no active schema change" for two very different reasons: it is still setting the work up, or the work is gone. The report alone does not distinguish them — but waiting a fixed period does, because a healthy engine starts reporting real progress and one that has lost the work never will. Past that period engine progress can never terminalize the tasks, so the live target schema is the only remaining authority and the drive reads it.
Two safety properties worth calling out:
The settled task states drive the existing aggregate derivation in the same tick, so the apply quiesces — or the operation drive exits for operator projection — through the normal paths. The per-task settlement and re-plan helpers are shared with the sequential drive rather than duplicated.
Opened by Claude (Fable 5); summary revised by Claude (Opus 5).