8000 WAL entries of more than 1M facts are never replayed: the transaction and every later one are lost · Issue #686 · project-minigraf/minigraf · GitHub
[go: up one dir, main page]

Skip to content

WAL entries of more than 1M facts are never replayed: the transaction and every later one are lost #686

Closed

Description

@adityamukho

Summary

A transact or retract (or a WriteTransaction commit) of more than 1,000,000 facts succeeds, but the WAL entry it writes is never replayed. WAL replay stops at that entry, so after a crash, kill, or close without a checkpoint, that transaction and every later transaction in the WAL are lost.

Cause

src/wal.rs: the writer (serialize_entry) writes any number of facts, but the reader treats an entry with more than MAX_FACTS_PER_ENTRY (1,000,000) facts as corrupt and stops reading:

// Sanity cap: no legitimate entry has more than 1M facts
const MAX_FACTS_PER_ENTRY: usize = 1_000_000;
if num_facts > MAX_FACTS_PER_ENTRY {
    break; // treat as corrupt entry
}

The cap came in with 91fd04c (2026-03-21, first released in v0.5.0). It is the same on main (src/wal.rs:363) and v3 (src/wal.rs:454).

Reproduction (main, v2.0.9)

let db = OpenOptions::new().wal_checkpoint_threshold(usize::MAX).path(&path).open()?;
let facts: String = (0..1_000_001).map(|i| format!("[:e{i} :n {i}]")).collect();
db.execute(&format!("(transact [{facts}])"))?;   // Ok
db.execute("(transact [[:after :n 1]])")?;       // Ok; current_tx_count() == 2
drop(db);                                        // no checkpoint: the WAL keeps both entries
let db = Minigraf::open(&path)?;
// current_tx_count() == 0; neither transaction's facts are there

The same happens after a crash or SIGKILL before the next checkpoint, with the default threshold. A checkpoint before the crash writes the facts to the file, so the window is between the commit and the next checkpoint.

Affected

Fix options

  • Reject the transaction before it takes a tx_count, with a structured error, when it would write an entry the reader refuses, as WAL-003 does for oversized facts. On v2.x that is the smallest change that never reports a lost commit as success.
  • Or remove the count cap from the reader. It guards against a corrupt count before the CRC is checked, so it would need another bound, such as the entry's byte length against the file's remaining length.

Data-integrity bug: stays open until the fix is in a published release (CONTRIBUTING.md). Needs a v3 fix and a v2.x backport.

Activity

  1. added
    bugSomething isn't working
    durabilityData durability concern
    known-issueBug present in a published release and not yet fixed in one; listed in the pinned known-issues issue
    on Oct 22, 2026
  2. adityamukho commented on Oct 23, 2026

    @adityamukho
    CollaboratorAuthor

    Fixed in v2.0.10, released 2026-10-23 (crates.io, CHANGELOG). Also fixed on v3 for v3.0.0. Moved to "Fixed in v2.0.10" in #421.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdata-integrityData integrity issuedurabilityData durability concernknown-issueBug present in a published release and not yet fixed in one; listed in the pinned known-issues issue

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      0