Repository navigation
fix(durability): fsync parent directory after creating .graph/WAL and deleting WAL (#389) - #404
Merged
Merged
Conversation
…/WAL and deleting the WAL (#389) On POSIX a created or deleted file survives a power loss only once its parent directory is fsynced. Minigraf fsynced file contents but never a directory, so a power loss could lose a freshly created .graph or <db>.wal, or resurrect a WAL that checkpoint() had deleted. Add storage::dir_sync::sync_parent_dir (open parent dir + sync_all on Unix; no-op elsewhere) and call it: - in FileBackend::open_with after writing the header of a new/empty file - in WalWriter::open_or_create after creating the WAL, and after re-initializing a headerless WAL left by a crash - in WalWriter::delete_file after a successful remove A test-only thread-local log records each sync and whether the child existed at that moment, so unit tests check both that the sync happens and that it follows the create/remove. Resurrected-WAL replay idempotence was already covered by tests/edge_cases_test.rs::test_stale_wal_after_checkpoint_is_idempotent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BedF9ZmqVZLkvDwn91fuKy
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #389.
Problem
On POSIX, a created or deleted file survives a power loss only after its parent directory is fsynced. Minigraf only ever called
sync_all()/sync_data()on file handles (confirmed: no directory sync anywhere insrc/), so a power loss could lose a new.graphor<db>.wal, or bring back a WAL thatcheckpoint()deleted.Fix
New
storage::dir_sync::sync_parent_dir(child)— opens the parent directory and callssync_all()on Unix; no-op on Windows and other targets. Called:FileBackend::open_with.graphWalWriter::open_or_createWalWriter::delete_fileremove_fileErrors propagate like the existing file
sync_all()calls. Reopening an existing, initialized file does no directory sync.Tests
A test-only thread-local log records every sync with whether the child file existed at that moment, so tests verify both that the sync happens and its order (exists after create, gone after delete). 10 new unit tests; suite: 1192 passed, 8 ignored.
The resurrected-WAL replay path the issue flagged as untested is already covered by
tests/edge_cases_test.rs::test_stale_wal_after_checkpoint_is_idempotent(replay skips entries ≤last_checkpointed_tx_count).🤖 Generated with Claude Code
https://claude.ai/code/session_01BedF9ZmqVZLkvDwn91fuKy