8000 fix(wal): replay WAL entries of more than 1,000,000 facts (#686) by adityamukho · Pull Request #698 · project-minigraf/minigraf · GitHub
[go: up one dir, main page]

Skip to content

fix(wal): replay WAL entries of more than 1,000,000 facts (#686) - #698

Merged
adityamukho merged 4 commits into
v3from
fix/686-wal-entry-cap
Oct 23, 2026
Merged

adityamukho merged 4 commits into
v3from
fix/686-wal-entry-cap

Conversation

@adityamukho
Copy link
Copy Markdown
Collaborator

Summary

For #686 (data-integrity; the v2.x backport is a separate PR, and the issue stays open until a published release has the fix).

WAL replay treated an entry of more than 1,000,000 facts as damage and stopped there. The writer never had that limit. scan_entries also drives the writer's tail cut at open (#513), so the next open truncated the WAL at that entry and lost it and every later entry. On v3 no transaction writes such an entry since #550, but a WAL left by v2.x can hold one.

  • src/wal.rs: the count cap is gone. A fact count is now damage only when the bytes left in the file cannot hold that many facts (every fact has at least its 4-byte length prefix). The check runs on the raw u64 before the usize conversion, so on 32-bit an impossible count ends replay where it used to fail with WAL-005 (Codex review). A corrupt count that passes the bound still ends at EOF, a bad fact or the CRC, as before. Memory use stays bounded by the file's size.
  • MAX_FACTS_PER_ENTRY is removed. MAX_TX_CHUNK_FACTS (1,000,000) keeps the transaction_chunk_facts clamp as a memory bound; its doc comment and the large_tx.rs assertion no longer tie it to the WAL.
  • No new error code and no format change.

Tests

  • test_wal_entry_of_more_than_a_million_facts_replays: an entry of 1,000,001 facts plus a later one replay; reopening the writer cuts off nothing, and an append lands after them. Before the fix, reopening cut the 41 MB WAL back to its 32-byte header.
  • test_wal_entry_with_more_facts_than_bytes_left_ends_replay (replaces the 1,000,001-count test): a count of left/4 + 1, and one of u64::MAX, end replay at that entry, and reopening the writer cuts the WAL off there.
  • Full suite: 1,754 passed, 14 ignored (1,768). cargo clippy --all-features -- -D warnings is clean.

Docs

CHANGELOG (Fixed), docs/TEST_COVERAGE.md, CLAUDE.md test count. The docs site needs no change.

🤖 Generated with Claude Code

https://claude.ai/code/session_0169pNQsLcCEn48te9X9WuZW

adityamukho and others added 4 commits October 23, 2026 09:37
Replay took an entry of more than 1,000,000 facts as damage, and the
writer's tail cut at open removed it and every later entry, so those
committed transactions were lost after a crash or close without a
checkpoint. A fact count is now damage only when the bytes after it
cannot hold that many facts (each has at least its 4-byte length),
checked before the count is converted to usize.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0169pNQsLcCEn48te9X9WuZW
Take the entry's offset from valid_end rather than stream_position, and
fall back to no bound when the file length is unavailable (a corrupt
count still ends at EOF), so the coverage gate's branch floor holds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0169pNQsLcCEn48te9X9WuZW
The byte bound now stops the truncated-entry tests before the fact
loop; cover the loop's two truncation exits directly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0169pNQsLcCEn48te9X9WuZW
@adityamukho
adityamukho merged commit 15a2038 into v3 Oct 23, 2026
23 of 24 checks passed
@adityamukho
adityamukho deleted the fix/686-wal-entry-cap branch October 23, 2026 05:47
@codecov
codecov Bot commented Oct 23, 2026
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

0