Skip to main content

Restore

By the end of this page you will have rebuilt a fresh ScramDB instance from a base backup, replaying every available WAL segment, and verified it against a real query.

This page covers a full restore: rebuild everything the backup and its WAL can give you, with no target point. If you want to stop replay at a specific LSN or timestamp instead, see Point-in-time recovery, it is the same command with one extra flag.

Before you start​

You need:

  • A base backup taken with scramdb backup (see Backups), reachable at a local path or object storage URL.
  • A config file whose storage.basedir points at an empty or nonexistent directory. Restore refuses to write into a directory that already has content in it, so do not reuse the original instance's basedir unless you have emptied it first.

Step by step​

  1. Prepare a restore config file naming a fresh basedir. For example, /etc/scramdb/restore-config.toml:

    [storage]
    basedir = "/var/lib/scramdb/restored"

    Confirm that directory is empty or does not exist yet:

    ls /var/lib/scramdb/restored 2>/dev/null

    Expect either "No such file or directory" or an empty listing.

  2. Run scramdb restore pointing --backup at your backup destination. Since this is a full restore, you still need to satisfy the CLI's target requirement (see Point-in-time recovery if you want to bound it); to replay everything currently available, target a timestamp far enough in the future, or use the most recent timestamp you know is covered by your WAL:

    scramdb restore --config /etc/scramdb/restore-config.toml \
    --backup file:///var/lib/scramdb/backups/2026-08-02 \
    --target-time 2026-08-02T12:00:00Z

    If your WAL archive lives at a different location than the backup itself, add --wal-source:

    scramdb restore --config /etc/scramdb/restore-config.toml \
    --backup file:///var/lib/scramdb/backups/2026-08-02 \
    --wal-source file:///var/lib/scramdb/wal-archive \
    --target-time 2026-08-02T12:00:00Z

    --wal-source defaults to the same value as --backup if you omit it, since a backup and its WAL archive commonly share a destination root.

  3. Check the output. A successful restore logs:

    restore complete: replayed to lsn=<LSN>, target config=/etc/scramdb/restore-config.toml

    The lsn value is your verification anchor. Compare it against the base_lsn your original backup reported, it should be equal to or ahead of it, reflecting however much WAL got replayed.

  4. Start the restored instance:

    scramdb --config /etc/scramdb/restore-config.toml
  5. Verify with a real query. Connect and check the data is what you expect:

    psql "host=127.0.0.1 port=5432 user=scramdb dbname=scramdb" -c "SELECT count(*) FROM your_table;"

    Compare the row count (and, ideally, a spot-checked row or two you know the value of) against what you expected from the source instance at the time of the backup plus replayed WAL. A clean server start with no error output, plus a query that returns the row counts you expect, is your sign the restore worked.

If it fails​

SymptomLikely causeWhat to do
restore target data directory '<dir>' already exists and is not emptystorage.basedir in your restore config points at a directory with existing contentPoint at a genuinely empty or nonexistent directory
backup manifest format_version N is not supportedThe manifest is from an incompatible or corrupt backupRe-take the backup, or use a build of scramdb that matches the manifest's format
backup was taken with WAL format version N but this build expects MBackup and restore binaries are from different, WAL-incompatible buildsRestore with a matching scramdb build, or re-take the backup with the current build
no WAL segments available at the configured WAL source starting from file_id NNeither --backup nor --wal-source has the WAL segments needed to replay forward from the backup's recorded positionCheck --wal-source points at the right archive location, and that retention has not pruned the segments you need
A file's checksum mismatch during restoreThe backup's data/ tree was corrupted or partially copiedRe-take the backup; restore verifies every file's checksum as it lands and fails loud rather than restoring silently-corrupt data

Every file restore writes is checksum-verified against the manifest as it lands, so a corrupted backup fails loudly during restore rather than producing a silently-broken instance.

Next​

  • Point-in-time recovery: the same command, aimed at an exact LSN or timestamp instead of the latest available point.
  • Branching: fork a database as of a past moment on a running server, without a separate restore step.