fix(partitions): preserve purge cleanup across retries and recovery - #4130
diegomrsantos wants to merge 7 commits into
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #4130 +/- ##
=============================================
- Coverage 87.62% 70.65% -16.97%
Complexity 1575 1575
=============================================
Files 1284 1282 -2
Lines 225457 200038 -25419
Branches 188820 163400 -25420
=============================================
- Hits 197549 141340 -56209
- Misses 23177 54038 +30861
+ Partials 4731 4660 -71
🚀 New features to boost your workflow:
|
A purge can record completion even though an offset directory sync failed, allowing stale bookmarks to survive power loss and skip fresh messages. Exercise shared purge completion and recovery with SimStorage under both consumer offset durability policies. Keep direct completion failures separate from crash recovery checks so every policy and directory case runs. The eight regression cases intentionally fail until the production bug is fixed.
33c07b3 to
5b487f2
Compare
The purge regressions required following several helpers to understand one scenario. Put both complete scenarios before their fixtures and declare the four policy and directory cases together. Inject directory sync errors by path instead of locating an operation through a second purge. Record the directory state at the failure and spell out the expected recovery state for failed and successful completion separately.
Keep purge failure scenarios readable without modifying shared simulator behavior. Use explicit test functions and a local storage adapter for directory sync failures. Allow cleanup to stop at the first error while preserving generation and recovery assertions. Validation: workspace formatting and Clippy pass. The focused suite has two passing controls and eight expected failures for the existing purge bug.
Failed bookmark directory synchronization must leave purge completion pending without allowing a retry to erase fresh committed messages. Record the durable message reset separately, resume cleanup before loading bookmarks, and protect the reset boundary when state transfer replaces history. Cover power loss, full purge retries, pending offset commits, marker failures, singleton recovery, and state transfer rollback.
|
@hubcio @spetz, working on #4130 raised a broader question about the guarantees we want from purge. Today, purge clears messages, restarts their offsets at zero, and separately removes consumer bookmarks. If a bookmark deletion is not durable, an old bookmark at The fundamental requirement is that messages, bookmarks, and recovery metadata agree about which history they describe. Physical file deletion can take several steps, provided recovery restores a coherent logical state. A persisted cutoff is only meaningful if the sequence it describes is also recovered consistently. There is a related defect in the current PR. A local partition regression with three replicas and both durability policies set to I looked at how other systems handle this.
These systems have different atomicity and durability guarantees. The common ideas worth considering are stable identities, precise replay boundaries, and separating the committed logical change from storage reclamation. I'd appreciate your input on three points.
My preference is to fix the concrete recovery defect in this PR and add the missing restart regression, then evaluate the broader design separately. The tests should also cover failed directory synchronization, retries after fresh writes, and another crash during recovery. |
Purge now returns an error without advancing its applied generation when consumer bookmark cleanup or directory synchronization fails. Fixes #4128.
A checksummed
purge.resetrecord separates durable message reset from cleanup completion. Retries for the same generation finish cleanup and publishpurge.genwhile preserving fresh committed messages and the original journal boundary. Recovery loads that boundary and finishes pending cleanup before loading bookmarks. Fresh bookmark mutations wait until cleanup completes.The reset record follows the partition incarnation and discarded history. State transfer rebases both the record and WAL purge floor when replacing a longer operation sequence, with an install backup protecting rollback even when the partition has no WAL.
The simulator regressions cover both consumer kinds and both offset durability policies, including repeated cleanup failure during recovery and real
Nextpolls after power loss. Separate partition tests exercise full purge retries with fresh committed messages, completion marker failures, waiting offset commits, singleton recovery, andNoAckrequests. The simulator fixture rebuilds a partition from storage; it does not run full server boot or prove client receipt of replies.Local validation on macOS:
cargo test -p journal -p partitions -p simulator -p server --lib: 1,053 passed, 7 ignored, no failures.--no-format, Clippy with all features and targets, and TOML formatting passed.