Home / Alt manpages / pg_restorecluster(1)

  • pg_restorecluster(1)
  • User command
  • linux

Restore a PostgreSQL Cluster from a Debian Backup

You will finish with a newly named PostgreSQL cluster restored from a pg_backupcluster backup, running on a deliberate port and ready for verification. The installed command is from postgresql-common version 257build1.1. Allow about 20 minutes for a small dump, or longer for a basebackup and any WAL recovery.

This guide assumes you already have a completed backup. A backup name must end in .basebackup or .dump. The command creates a new cluster and updates its configuration for the new name and data location. It does not turn an existing cluster into a renamed copy.

1. Check the restore prerequisites

Use an account that can create the PostgreSQL data and configuration files. The examples use sudo because the default locations are system-owned; omit it if you are already running as the appropriate administrator. Do not restore over a production data directory while that cluster is serving traffic. Choose a maintenance window and a separate destination first.

Confirm the installed binary and package version:

$ command -v pg_restorecluster
/usr/bin/pg_restorecluster
$ dpkg-query -W -f='${Package} ${Version}\n' postgresql-common
postgresql-common 257build1.1

The command has no documented --help or --version option in this installed release. Its required shape is:

pg_restorecluster [options] VERSION CLUSTER BACKUP

VERSION is the PostgreSQL major version, CLUSTER is the new cluster name, and BACKUP is the path reported by pg_backupcluster ... list. Keep those three positional arguments in that order.

2. Identify the backup without guessing its path

List backups for the source cluster. This asks pg_backupcluster to show dumps, basebackups and WAL with their sizes. It does not restore anything:

$ sudo pg_backupcluster VERSION SOURCE_CLUSTER list
# output is host-specific; copy the complete path ending in .dump or .basebackup

Replace VERSION and SOURCE_CLUSTER with real values, such as 16 and main. Copy the full backup path from the listing rather than typing a timestamp by hand. A .dump contains database dumps and cluster-level SQL files. A .basebackup is a physical backup restored as-is.

Checkpoint: save the exact path in a shell variable and check that it is readable before changing PostgreSQL state:

$ BACKUP='/var/backups/postgresql/VERSION-SOURCE_CLUSTER/TIMESTAMP.dump'
$ test -r "$BACKUP" && echo "backup is readable"
backup is readable

The example path is a placeholder. Do not continue until test succeeds for the path on your machine.

3. Choose the new cluster name, directory and port

Pick a name that does not describe the old cluster ambiguously. The following values are examples only:

$ VERSION=16
$ NEW_CLUSTER='recovered'
$ RESTORE_DIR='/var/lib/postgresql/16/recovered'
$ RESTORE_PORT=55432

For a dump, pg_restorecluster uses pg_createcluster and restores schema and data with pg_restore. For a basebackup, it restores the physical backup as-is. The default data directory is chosen by createcluster.conf, normally /var/lib/postgresql/VERSION/CLUSTER. The -d option makes the destination explicit:

$ sudo pg_restorecluster -d "$RESTORE_DIR" -p "$RESTORE_PORT" \
    "$VERSION" "$NEW_CLUSTER" "$BACKUP"

Port selection is easy to overlook. Without -p, the command uses the next free port, which can make scripts and connection tests point at the wrong service. Check that your chosen port is free and that firewall, monitoring and application settings will not mistake the restored cluster for the original.

4. Restore a dump and verify that it starts

A dump restore starts the new cluster by default. You can make that choice explicit with -s; after starting, the command runs ANALYZE on all databases. Starting a cluster is a service change, so make sure the name and port are correct before running it.

$ sudo pg_restorecluster -d "$RESTORE_DIR" -p "$RESTORE_PORT" -s \
    "$VERSION" "$NEW_CLUSTER" "$BACKUP"

There is no fixed success transcript to copy. Treat a zero exit status as completion of the restore operation, then verify the endpoint with the PostgreSQL client using the port you selected:

$ psql -h 127.0.0.1 -p 55432 -d postgres -c 'select current_database(), version();'
 current_database | version
------------------+---------
 postgres          | PostgreSQL ...
(1 row)

The version string and spacing vary. The useful checks are that the connection reaches the new port and that the returned server is the expected PostgreSQL major version. Repeat the query against a restored application database if the backup contains one.

5. Restore a basebackup deliberately

Basebackups are not treated like dumps. They are restored as-is, and the default is not to start the cluster after the restore. Use -s only when you are ready for the restored service to start:

$ sudo pg_restorecluster -d "$RESTORE_DIR" -p "$RESTORE_PORT" \
    "$VERSION" "$NEW_CLUSTER" "$BASEBACKUP"
$ sudo pg_restorecluster -d "$RESTORE_DIR" -p "$RESTORE_PORT" -s \
    "$VERSION" "$NEW_CLUSTER" "$BASEBACKUP"

Run one of these commands, not both. If the first command completes, inspect the generated cluster configuration and decide whether to start it separately through your normal PostgreSQL service tooling. If you use the second form, verify the port immediately with psql as in the previous step.

Keep the original backup until the restored cluster has passed application-level checks. If the restore fails, preserve the destination and its diagnostics, stop any newly started cluster using your normal cluster administration procedure, and investigate before retrying into the same directory. Do not delete the original backup or a failed data directory as a first response.

6. Configure WAL archive recovery or point-in-time recovery

Use archive options only when the backup has a usable WAL archive. --archive sets restore_command to read from the wal directory beside the backup's parent. To use another archive directory, add --wal-archive DIR:

$ sudo pg_restorecluster --archive \
    --wal-archive '/srv/postgresql-wal' \
    -d "$RESTORE_DIR" -p "$RESTORE_PORT" \
    "$VERSION" "$NEW_CLUSTER" "$BASEBACKUP"

For point-in-time recovery, add --pitr TIMESTAMP, or its long equivalent --recovery-target-time TIMESTAMP. This also sets the recovery action to promote, so the cluster will leave recovery at the target time. Treat the timestamp as a recovery boundary, not as a promise that every transaction visible at that wall-clock time belongs to the desired application state.

$ sudo pg_restorecluster --archive \
    --wal-archive '/srv/postgresql-wal' \
    --pitr '2026-09-26 14:30:00+00' \
    -d "$RESTORE_DIR" -p "$RESTORE_PORT" -s \
    "$VERSION" "$NEW_CLUSTER" "$BASEBACKUP"

Do not add recovery options to a routine logical dump restore unless you have confirmed that the backup type and WAL archive support that workflow. If recovery does not reach the expected point, leave the original backup and archive untouched and record the restore log before trying another target.

7. Diagnose the common mistakes

  • If the command rejects the backup, check its suffix. The positional backup must end in .basebackup or .dump, and the path should come from the backup listing.
  • If the connection test reaches the wrong server, check -p and the cluster name. The default is the next free port, not a fixed PostgreSQL port.
  • If a dump appears stopped, remember that dumps start by default, whereas basebackups do not. Use -s when the restored basebackup should start immediately.
  • If archive recovery cannot find WAL, check the archive directory and the relationship between the backup path and its adjacent wal directory. --wal-archive overrides the default.
  • If you need to retry, use a new cluster name or a confirmed empty destination. Do not blindly rerun a restore over a directory that may contain a partially restored cluster.

Done means

  • You identified a readable .dump or .basebackup from the backup listing.
  • The restored cluster has an intentional name, data directory and port.
  • You know whether the command started the cluster, and you verified the endpoint with psql.
  • Any WAL archive and recovery target were supplied deliberately and checked against the backup.
  • The original backup remains available until application-level validation is complete.