Skip to content

Stop a rollback moving chunk metadata forward - #8244

Open
Amaury Chamayou (achamayou) wants to merge 1 commit into
achamayou-order-chunk-metadata-rollbackfrom
achamayou-clamp-chunker-rollback
Open

Stop a rollback moving chunk metadata forward#8244
Amaury Chamayou (achamayou) wants to merge 1 commit into
achamayou-order-chunk-metadata-rollbackfrom
achamayou-clamp-chunker-rollback

Conversation

@achamayou

@achamayou Amaury Chamayou (achamayou) commented Aug 30, 2026

Copy link
Copy Markdown
Member

Stacked on #8243. Review the top commit only; the base PRs must merge first.

Why this is necessary

Store::rollback() has two paths. If the target is below the store''s version it truncates; if the target is at or beyond it, nothing local is discarded and it returns early. Both paths reset the chunker to the rollback target.

For the truncating path that is right. For the early-return path it is not, because the chunker is allowed to lag the store. An entry is assigned a version by next_version() well before Store::commit() records its size, so at any moment the chunker can legitimately be behind. Resetting it to a target at or beyond the store''s version therefore moves it forward, past entries whose sizes were never recorded.

The chunker''s counter is independent of the store''s version and only ever advances, so the offset is permanent. Every subsequent entry is then recorded against the wrong version, transaction_sizes acquires a hole, and get_unchunked_size() silently under-counts - chunk boundaries drift from what the ledger contains, and compacted_to() can prune entries that were never accounted for.

A rollback to exactly the current version is routine: it is how a view change is communicated when there is nothing to truncate.

What changes

Clamp the rollback target to the store''s own version, so a rollback can only ever move chunk metadata back:

chunker->rolled_back_to(std::min<Version>(tx_id.seqno, version));

Why this is minimal

One std::min on the non-truncating path. The truncating path is untouched - there the target is below version by construction, so the clamp would be a no-op.

The alternative, keeping the chunker eagerly in step with allocation rather than with commit, would mean recording sizes for entries that may never be replicated, which is the resurrection problem the previous PR in this stack fixes.

Performance

None. One comparison on a path taken only during a view change.

Testing

kv_test gains "A rollback never moves chunk metadata past the store''s version", covering both a rollback to exactly the current version and one beyond it, then asserting later entries are still recorded against their own version. Single-threaded and deterministic.

Verified that the test fails without the clamp - the chunker ends ahead of the store, and stays ahead - and passes with it.

Labelled run-long-test.


Review stack

These five PRs come from one investigation and are stacked; review and merge in order.

PR Change
#8242 Reject stale-view writes before local commit
#8243 Order chunk metadata and snapshot scheduling with rollback
#8244 Stop a rollback moving chunk metadata forward
#8245 Guard rollback-sensitive transaction flags
#8246 Guard reserved signature side effects

All were found by an interleaving-exploration harness built over the real KV, consensus and history stack (draft #8238). The harness itself is deliberately not included here; these PRs carry only the fixes and the single-threaded regression tests that pin them.

A rollback whose target is at or beyond the store's own version discards nothing, but still reset the chunker to that target. The chunker can legitimately lag the store, because an entry is allocated a version well before its size is recorded, so this moved the chunker forward past the store and left a permanent offset that skewed every later chunk boundary.

Clamp the target to the store's version, so a rollback can only ever move chunk metadata back.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 75d99c5d-6efa-4048-8032-8c78b97208d9
@achamayou
Amaury Chamayou (achamayou) force-pushed the achamayou-clamp-chunker-rollback branch from 3d925bc to 4562e3c Compare August 31, 2026 12:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

run-long-test Run Long Test job

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants