Skip to content

compute: don't forward implied capabilities while rehydrating a replica - #40418

Merged
DAlperin merged 1 commit into
mainfrom
dov/compute-rehydrate-read-holds
Nov 7, 2026
Merged

DAlperin merged 1 commit into
mainfrom
dov/compute-rehydrate-read-holds

Conversation

@DAlperin

@DAlperin DAlperin commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

rehydrate_replica removes a replica and adds it back. If it is the cluster's only replica, the replica map is empty in between, and remove_replica called forward_implied_capabilities, which treats an empty replica map as a paused cluster. It advanced the read holds of indexes that had not hydrated past their as-of, and the storage controller then let their inputs compact. The replica process is still running those dataflows, and on reconnect compute reconciliation keeps them at their old as-of, because their output frontier is at or below the new one. A dataflow whose persist reader had not registered yet then halts the process with unhandled error in compute_import: ... cannot serve requested as_of, and the replay repeats it.

An Antithesis run under heavy network faults hit this. The full timeline, confirmed from persist state history, is in CPU-228.

The fix drops the call from remove_replica. maintain already forwards implied capabilities on every tick, after rehydrating failed replicas, so a cluster that really has no replicas still gets the downgrade within a tick.

Tests

test/cluster gets test-replica-reconnect-keeps-read-holds. It puts an index on a cluster with one unmanaged replica, pauses the replica's container until the controller times out and reconnects, and asserts that the index's read frontier never passes its write frontier. The reconciliation side of the halt (a kept dataflow whose reader has not registered) is not covered. Reproducing it needs a stalled persist reader registration, which no failpoint provides today.

Refs: CPU-228

🤖 Generated with Claude Code

@linear-code

linear-code Bot commented Nov 2, 2026

Copy link
Copy Markdown

CPU-228

`rehydrate_replica` removes a replica and adds it back. If it is the
cluster's only replica, the replica map is empty in between, and
`remove_replica` called `forward_implied_capabilities`, which treats that
as a paused cluster. It advanced the read holds of indexes that had not
hydrated past their as-of, and the storage controller let their inputs
compact. The replica process is still running those dataflows, and on
reconnect compute reconciliation keeps them at the old as-of. A dataflow
whose persist reader had not registered yet then halts the process with
"cannot serve requested as_of".

`maintain` already forwards implied capabilities on every tick, after
rehydrating failed replicas, so clusters that really have no replicas
still get the downgrade.

Refs: CPU-228
@DAlperin
DAlperin force-pushed the dov/compute-rehydrate-read-holds branch from ce2c549 to d439ff0 Compare November 2, 2026 17:16
@DAlperin

DAlperin commented Nov 2, 2026

Copy link
Copy Markdown
Member Author

This unwinds some of the work in #27363, but I think it's worth it for now in lieu of some greater refactoring.

@DAlperin
DAlperin marked this pull request as ready for review November 2, 2026 18:26
@DAlperin
DAlperin requested a review from a team as a code owner November 2, 2026 18:26

@antiguru antiguru left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good, thanks for figuring this out.

@DAlperin
DAlperin enabled auto-merge (squash) November 2, 2026 18:28
@DAlperin
DAlperin merged commit c2559a5 into main Nov 7, 2026
83 checks passed
@DAlperin
DAlperin deleted the dov/compute-rehydrate-read-holds branch November 7, 2026 08:03
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.

2 participants