Skip to content

Startup WAL recovery deletes the writer's own active file — WAL provides no crash durability #594

Description

@xe-nvdk

Found while verifying the #590 fix (2026-08-13). Severity: the WAL subsystem's core guarantee is silently void.

Chain:

  1. wal.NewWriter (cmd/arc/main.go:710) creates the writer, which immediately rotates in its active file (header-only, 7 bytes).
  2. Startup recovery (cmd/arc/main.go:771) calls RecoverWithOptions without SkipActiveFile — the periodic flush-failure recovery path (main.go:842) passes it correctly, the startup call forgot it.
  3. internal/wal/recovery.go deletes empty (header-only) files after scanning — which is the writer's own active file.
  4. The writer keeps appending to the now-unlinked inode for the whole session. data/wal/ is empty while the server runs; on crash, nothing exists to replay.

Observed: every crash-replay test performed today (multiple binaries, fsync mode, multi-second waits) recovered 0 entries; the WAL directory is empty during operation on any WAL-enabled instance.

Fix: pass SkipActiveFile: walWriter.CurrentFile() in the startup recovery call, mirroring main.go:842.

🤖 Generated with Claude Code

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions