Skip to content

Add test for broken WAL delta after stream records abort#7787

Merged
timvisee merged 10 commits intodevfrom
abort-stream-records-breaks-wal-delta
Dec 17, 2025
Merged

Add test for broken WAL delta after stream records abort#7787
timvisee merged 10 commits intodevfrom
abort-stream-records-breaks-wal-delta

Conversation

@timvisee
Copy link
Member

@timvisee timvisee commented Dec 16, 2025

Fixed by #7791

Aborting a stream records (or other) transfer may break future WAL delta transfers.

This PR adds a test to reproduce the problematic behavior.

Specifically, any new updates coming in during a stream records (or other) transfer may bump the last seen clocks. This also happens on the node that is receiving the transfer. If we abort the stream records transfer, the last seen clocks may have jumped over a huge gap. A follow up WAL delta transfer will only transfer changes since the last seen clocks, missing a huge set of changes in that jump.

In practice, this sequence is problematic:

  • start stream records transfer to recover replica
  • send new update through all peers
  • abort stream records transfer
  • start WAL delta transfer
  • ⚠️ WAL delta resolves very short or empty diff

Imagine the initial stream records transfer only covered 10% of the points before it got aborted. The WAL delta transfer after it will then miss the remaining 90% of point changes, corrupting the target replica.

Test:

cargo build --features staging
pytest tests/consensus_tests/test_shard_wal_delta_transfer.py -k test_abort_stream_records_breaks_wal_delta

All Submissions:

  • Contributions should target the dev branch. Did you create your branch from dev?
  • Have you followed the guidelines in our Contributing document?
  • Have you checked to ensure there aren't other open Pull Requests for the same update/change?

New Feature Submissions:

  1. Does your submission pass tests?
  2. Have you formatted your code locally using cargo +nightly fmt --all command prior to submission?
  3. Have you checked your code using cargo clippy --all --all-features command?

Changes to Core Features:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your core changes, as applicable?
  • Have you successfully ran tests with your changes locally?

@timvisee timvisee force-pushed the abort-stream-records-breaks-wal-delta branch from 275d10b to e4d6444 Compare December 16, 2025 10:34
@timvisee timvisee marked this pull request as ready for review December 17, 2025 10:29
@timvisee
Copy link
Member Author

Note to reviewers: @agourlay @ffuugoo @coszio

This PR contains the test, and #7791 which you've already reviewed.

timvisee and others added 7 commits December 17, 2025 11:31
* Make set_replica_state async

* Add function called when active state of local replica changes

* Add snapshot for newest clocks

* Bump newest clocks snapshot on replica deactivation

* Use newest clocks snapshot during recovery

* Add enum for specifying whether to take or clear clocks snapshot

* Store clock snapshot inside clock map, removing extra file

This greatly simplifies state handling. It also prevent any kind of
desynchronization because all newest clocks are always persisted
atomically.

* Immediately persist clocks after taking snapshot

* Always update snapshot, only take if missing

* Take clock snapshots through each shard flavor, including proxies

* Propagate dedicated functions for taking and clearing clocks snapshot

* Only persist clocks immediately if changed on snapshot/clear

* Simplify recovery point logic, always take clocks snapshot if exists

* Remove unwrap
@timvisee timvisee force-pushed the abort-stream-records-breaks-wal-delta branch from f225e02 to 3790ef3 Compare December 17, 2025 10:31
coderabbitai[bot]

This comment was marked as resolved.

@qdrant qdrant deleted a comment from coderabbitai bot Dec 17, 2025
Copy link
Member

@agourlay agourlay left a comment

Choose a reason for hiding this comment

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

Impressive integration test 👏

@timvisee timvisee merged commit 0196323 into dev Dec 17, 2025
15 checks passed
@timvisee timvisee deleted the abort-stream-records-breaks-wal-delta branch December 17, 2025 11:33
timvisee added a commit that referenced this pull request Dec 18, 2025
* Add test to reproduce broken WAL delta after aborting stream records

* Add staging env var to slow down stream records transfers for test

* Tweak test formatting and utilities a bit

* Add comment to test, link to PR describing bug

* Update test so it still succeeds with patched behavior

* Fix broken WAL delta after stream records abort (#7791)

* Make set_replica_state async

* Add function called when active state of local replica changes

* Add snapshot for newest clocks

* Bump newest clocks snapshot on replica deactivation

* Use newest clocks snapshot during recovery

* Add enum for specifying whether to take or clear clocks snapshot

* Store clock snapshot inside clock map, removing extra file

This greatly simplifies state handling. It also prevent any kind of
desynchronization because all newest clocks are always persisted
atomically.

* Immediately persist clocks after taking snapshot

* Always update snapshot, only take if missing

* Take clock snapshots through each shard flavor, including proxies

* Propagate dedicated functions for taking and clearing clocks snapshot

* Only persist clocks immediately if changed on snapshot/clear

* Simplify recovery point logic, always take clocks snapshot if exists

* Remove unwrap

* Fix typo

* Fix doc comment

* Transfer driver is async, use Tokio sleep

* Reduce visibility
@timvisee timvisee mentioned this pull request Dec 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants