Skip to content

--no-wal mount option#15

Merged
vbp1 merged 1 commit intomainfrom
no-wal-mount-option
Dec 12, 2025
Merged

--no-wal mount option#15
vbp1 merged 1 commit intomainfrom
no-wal-mount-option

Conversation

@vbp1
Copy link
Copy Markdown
Owner

@vbp1 vbp1 commented Dec 12, 2025

What this PR does

Adds a pbkfs mount --no-wal option that makes WAL under pg_wal/ effectively virtual: PostgreSQL sees a consistent PGDATA view, but WAL mutations are not materialized into pbk_diff. This reduces I/O and disk usage for recovery/analysis runs where WAL is disposable.

User-visible behavior

  • New flag: pbkfs mount ... --no-wal (default: off).
  • Applies only to files under pg_wal/.
  • Unchanged WAL segments (never written/truncated/created/renamed during the mount):
    • Read directly from the backup chain.
    • Do not create diff copies.
  • Changed or newly created WAL segments:
    • As soon as a WAL file is written/truncated/created/renamed/unlinked, it is treated as “changed”.
    • Reads return zero bytes within [0, logical_size) and EOF at/after logical_size.
    • Logical size grows/shrinks according to successful write/truncate operations, despite no data being persisted.
  • WAL operations write, truncate, create/mknod, rename, unlink, fsync, fallocate are emulated in-memory and reported as successful, without touching pbk_diff or pbk_store.
  • Diff directory becomes non-resumable after a --no-wal mount:
    • First --no-wal mount emits a warning.
    • Binding is persisted with no_wal_used=true.
    • Any later attempt to reuse that diff dir (with or without --no-wal) fails with a clear error.

Implementation overview

  • CLI / Binding

    • Added no_wal to MountArgs, set PBKFS_NO_WAL consistently.
    • Persisted no_wal_used in binding and reject reuse when set.
    • Files: src/cli/mount.rs, src/binding/lock.rs.
  • Overlay

    • OverlayInner.no_wal initialized from PBKFS_NO_WAL.
    • For WAL under no_wal, reads use a non-materializing path; legacy WAL copy-up fallback is disabled.
    • File: src/fs/overlay.rs.
  • FUSE layer

    • Added no_wal flag and an in-memory wal_state map to OverlayFs.
    • Implemented WAL virtualization: write/truncate/create/rename/unlink/fsync/fallocate update only WAL state.
    • Reads return either real chain bytes (unchanged) or zero-filled bytes/ENOENT (changed/deleted).
    • readdir and stat_path/getattr synthesize WAL entries from WAL state.
    • File: src/fs/fuse.rs.

Tests

  • Updated all test MountArgs initializations to include no_wal.
  • Integration:
    • --no-wal + write to pg_wal/<seg> ⇒ reads return zeros, stat.size reflects logical growth, no WAL diff file is created.
    • --no-wal + unchanged WAL read ⇒ bytes come from backup chain without diff materialization.
    • File: tests/integration/mount_postgres_tests.rs.
  • Contract:
    • Binding records no_wal_used on first --no-wal mount and reuse is rejected.
    • File: tests/contract/cli_contract_tests.rs.
  • Unit:
    • Overlay reads PBKFS_NO_WAL into no_wal.
    • Binding no_wal_used round-trips and defaults to false.
    • Files: tests/unit/fs_overlay_tests.rs, tests/unit/binding_tests.rs.

Notes

  • Default behavior is unchanged; virtualization is strictly opt-in.
  • WAL data is intentionally never persisted in pbk_diff in this mode.

@vbp1 vbp1 changed the title no wal mount option --no-wal mount option Dec 12, 2025
@vbp1 vbp1 merged commit 167ed5c into main Dec 12, 2025
1 check passed
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