Swap: keep the journal replayable across failures and crashes
- Replay recovers every complete record before a torn final record (the normal result of a crash mid-append) and reports it through err, instead of rejecting the whole journal. SwapReplay_TruncatedLog is updated to the new behaviour. - A record that cannot be written (open/write failure, breaker open) marks the journal as having a gap. Later position-based records are dropped until a checkpoint re-establishes the content; recorders request one on the next edit (at most once per second). - A failed append is truncated back off the file, and a failed header write closes the file so the next attempt starts fresh. - Inserts over the 24-bit record limit are split into consecutive records; buffers too large to checkpoint are no longer snapshotted and rejected on every checkpoint. - Declining to delete an unreadable swap moves it to .corrupt so new edits are not appended behind the bad data. - NotifyFilenameChanged no longer writes a full checkpoint into the journal it is about to delete. Audit findings D7, P5. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015rcVQiiWyTzoNrsvLSaAfB
This commit is contained in:
@@ -192,6 +192,11 @@ private:
|
||||
std::uint64_t last_chkpt_ns{0};
|
||||
std::uint64_t edit_bytes_since_chkpt{0};
|
||||
std::uint64_t approx_size_bytes{0};
|
||||
// A record was lost (write failure, breaker open, oversize). Records are
|
||||
// position-based, so later ones no longer apply to the journal's state:
|
||||
// drop them until a checkpoint re-establishes the full content.
|
||||
bool gap{false};
|
||||
std::uint64_t gap_chkpt_request_ns{0};
|
||||
};
|
||||
|
||||
struct Pending {
|
||||
|
||||
Reference in New Issue
Block a user