3.2. Restoring a Cluster #
3.2.1. General Limitations and Considerations #
Note the following specifics and limitations of the restore process:
Tablespace remapping: When changing the location of tablespaces via mapping, the target directories must exist and be writable.
All parent backups in the chain (from the specified backup up to the full backup) must be present and available. If any link in the chain is missing, restore is impossible.
Backups with the statuses
CORRUPT,ORPHAN,INVALID,ERROR, orDELETEDcannot be restored. Only backups with theOKstatus are suitable for restore.If errors occur during the recovery process, certain files may be left undeleted and require manual removal. Failure to do so will cause subsequent restore attempts to the same directory to fail.
A backup must be successfully completed at the time of creation. Interrupted or corrupted backups cannot be restored. Using the
--no-validateflag is not recommended, as restoring from a corrupted backup will lead to an inconsistent database.A backup must contain at least ten files to pass validation (protection against an empty
PGDATAor permission issues).Backup segmentation:
chunk_noof each segment must be less thantotal_chunks. All segments must be present for a successful restore.
3.2.2. Full Restore #
Important
For a full restore, the PGDATA directory must be completely empty. Otherwise, the restore will fail.
To restore the database cluster from a backup, run the restore command with at least the following options:
pg_probackup3 restore -Bbackup_dir--instance=instance_name-ibackup_id
Where:
backup_diris the backup catalog that stores all backup files and meta information.instance_nameis the backup instance for the cluster to be restored.backup_idspecifies the backup to restore the cluster from.
If you restore ARCHIVE backups or perform PITR, pg_probackup3 creates a recovery configuration file once all data files are copied into the target directory. This file includes the minimal settings required for recovery, except for the password in the primary_conninfo parameter; you have to add the password manually or use the --primary-conninfo option, if required. pg_probackup3 writes recovery settings into the probackup_recovery.conf file and then includes it into postgresql.auto.conf.
If you are restoring a STREAM backup, the restore is complete at once, with the cluster returned to a self-consistent state at the point when the backup was taken. For ARCHIVE backups, Postgres Pro replays all available archived WAL segments, so the cluster is restored to the latest state possible within the current timeline. You can change this behavior by using the recovery target options with the restore command, as explained in Section 3.2.5.
If the cluster to restore contains tablespaces, pg_probackup3 restores them to their original location by default. To restore tablespaces to a different location, use the --tablespace-mapping/-T option. Otherwise, restoring the cluster on the same host will fail if tablespaces are in use, because the backup would have to be written to the same directories.
When using the --tablespace-mapping/-T option, you must provide absolute paths to the old and new tablespace directories. If a path happens to contain an equals sign (=), escape it with a backslash. This option can be specified multiple times for multiple tablespaces.
Note
Note the syntax for multiple tablespace mappings: instead of multiple -T flags, use a single flag with colon-separated mapping pairs. For example:
pg_probackup3 restore -Bbackup_dir--instance=instance_name-Ddata_dir-j 4 -ibackup_id-T tablespace1_dir=tablespace1_new_dir:tablespace2_dir=tablespace2_new_dir
3.2.3. Incremental Restore #
The speed of restore from backup can be significantly improved by replacing only invalid and changed pages in already existing Postgres Pro data directory using -I/--incremental-mode option with the restore command for local restore or with send-backup for restoring a backup to a remote host.
In this section, we will address local incremental restore using the restore command.
Important
Note the following specifics and limitations of local incremental restore:
During incremental restore, if
PGDATAis empty but a tablespace contains data, the--forceflag must be specified explicitly to clear the tablespace.During incremental restore, files and directories that are missing in the new backup are automatically deleted, which may lead to data loss if used incorrectly.
If
PGDATAand all tablespaces are empty, the mode automatically switches to a full restore.
To restore the database cluster from a backup in incremental mode, run the restore command with the following options:
pg_probackup3 restore -Bbackup_dir--instance=instance_name-Ddata_dir-Iincremental_mode
incremental_mode can take one of the following values:
CHECKSUM(recommended): All data files in the target data directory are read. For each page, the header and checksum are validated. Only pages that are invalid, or whose checksum or LSN does not match the corresponding page in the backup, are replaced. This is the simplest and most reliable incremental mode.LSN: Thepg_controlfile in the target data directory is read to obtain the redo LSN and timeline, determining the shiftpoint — the point where the data directory state diverged from the backup chain history. If the shiftpoint lies outside the backup chain history, the restore is aborted. If it lies within, all data files are read, each page header and checksum is validated, and only invalid pages and those with an LSN greater than the shiftpoint are replaced. This mode offers a greater speedup compared toCHECKSUM, but relies on two conditions:Data checksums must be enabled in the data directory (to avoid corruption due to hint bits). This condition is checked at the start of incremental restore, and the operation aborts if checksums are disabled.
The
pg_controlfile must be synchronized with the state of the data directory. This condition cannot be checked automatically, so it is the user's responsibility to ensure thatpg_controlcontains valid information. Therefore,LSNmode is not recommended in any situation wherepg_controlcannot be trusted or may have been tampered with — for example, after runningpg_resetxlogor after a restore from backup without WAL replay.
Regardless of the chosen incremental mode, pg_probackup3 will check that postmaster in given destination directory is not running and system-identifier is the same as in the backup.
An example of using incremental restore with a tablespace in CHECKSUM mode:
================================================================================================================================ Instance Version ID End time Mode WAL Mode TLI Duration Data WAL Zalg Zratio Start LSN Stop LSN Status ================================================================================================================================ inst 17 1-full 2025-08-05 16:14:10+0700 FULL STREAM 1 1s 47MB - none 1.46 0/A3000028 0/A3000160 OK inst 17 1-delta 2025-08-05 16:14:33+0700 DELTA STREAM 1 1s 21MB - none 3.18 0/A5000028 0/A5000160 OK inst 17 2-delta 2025-08-05 16:14:37+0700 DELTA STREAM 1 0ms 21MB - none 3.18 0/A6000028 0/A6000160 OK backup_user@backup_host:~$ ./pg_probackup3 restore -D /mnt/node -B /mnt/b3b --instance=inst -I checksum --backup-id 2-delta -T /mnt/ts1=/mnt/ts2 --threads=1 [2025-08-05 16:20:38.061117] [264669] [0x79693fc1a4c0] [info] command: ./pg_probackup3 restore -D /mnt/node -B /mnt/backups --instance=inst -I checksum --backup-id 2-delta -T /mnt/ts1=/mnt/ts2 --threads=1 [2025-08-05 16:20:38.061244] [264669] [0x79693fc1a4c0] [info] execute command: 'restore', instance 'inst', backup_id '2-delta' [2025-08-05 16:20:38.061855] [264669] [0x79693fc1a4c0] [info] Start validate 2-delta ... [2025-08-05 16:20:38.065368] [264669] [0x79693d5a66c0] [info] Validating backup 1-full chunk #0 out of 8 [2025-08-05 16:20:38.088840] [264669] [0x79693d5a66c0] [info] Validating backup 1-full chunk #1 out of 8 [2025-08-05 16:20:38.112253] [264669] [0x79693d5a66c0] [info] Validating backup 1-full chunk #2 out of 8 [2025-08-05 16:20:38.193395] [264669] [0x79693d5a66c0] [info] Validating backup 1-full chunk #3 out of 8 [2025-08-05 16:20:38.213982] [264669] [0x79693d5a66c0] [info] Validating backup 1-full chunk #4 out of 8 [2025-08-05 16:20:38.235532] [264669] [0x79693d5a66c0] [info] Validating backup 1-full chunk #5 out of 8 [2025-08-05 16:20:38.256768] [264669] [0x79693d5a66c0] [info] Validating backup 1-full chunk #6 out of 8 [2025-08-05 16:20:38.278902] [264669] [0x79693d5a66c0] [info] Validating backup 1-full chunk #7 out of 8 [2025-08-05 16:20:38.300380] [264669] [0x79693fc1a4c0] [info] Validate time 235ms [2025-08-05 16:20:38.301628] [264669] [0x79693d5a66c0] [info] Validating backup 1-delta chunk #0 out of 8 [2025-08-05 16:20:38.305281] [264669] [0x79693d5a66c0] [info] Validating backup 1-delta chunk #1 out of 8 [2025-08-05 16:20:38.368129] [264669] [0x79693d5a66c0] [info] Validating backup 1-delta chunk #2 out of 8 [2025-08-05 16:20:38.371719] [264669] [0x79693d5a66c0] [info] Validating backup 1-delta chunk #3 out of 8 [2025-08-05 16:20:38.375494] [264669] [0x79693d5a66c0] [info] Validating backup 1-delta chunk #4 out of 8 [2025-08-05 16:20:38.379185] [264669] [0x79693d5a66c0] [info] Validating backup 1-delta chunk #5 out of 8 [2025-08-05 16:20:38.383215] [264669] [0x79693d5a66c0] [info] Validating backup 1-delta chunk #6 out of 8 [2025-08-05 16:20:38.386733] [264669] [0x79693d5a66c0] [info] Validating backup 1-delta chunk #7 out of 8 [2025-08-05 16:20:38.390220] [264669] [0x79693fc1a4c0] [info] Validate time 89ms [2025-08-05 16:20:38.391428] [264669] [0x79693d5a66c0] [info] Validating backup 2-delta chunk #0 out of 8 [2025-08-05 16:20:38.395259] [264669] [0x79693d5a66c0] [info] Validating backup 2-delta chunk #1 out of 8 [2025-08-05 16:20:38.399093] [264669] [0x79693d5a66c0] [info] Validating backup 2-delta chunk #2 out of 8 [2025-08-05 16:20:38.402872] [264669] [0x79693d5a66c0] [info] Validating backup 2-delta chunk #3 out of 8 [2025-08-05 16:20:38.405935] [264669] [0x79693d5a66c0] [info] Validating backup 2-delta chunk #4 out of 8 [2025-08-05 16:20:38.468891] [264669] [0x79693d5a66c0] [info] Validating backup 2-delta chunk #5 out of 8 [2025-08-05 16:20:38.472336] [264669] [0x79693d5a66c0] [info] Validating backup 2-delta chunk #6 out of 8 [2025-08-05 16:20:38.475977] [264669] [0x79693d5a66c0] [info] Validating backup 2-delta chunk #7 out of 8 [2025-08-05 16:20:38.479477] [264669] [0x79693fc1a4c0] [info] Validate time 88ms [2025-08-05 16:20:38.479859] [264669] [0x79693fc1a4c0] [info] INFO: Backup 2-delta is valid [2025-08-05 16:20:38.479992] [264669] [0x79693fc1a4c0] [info] Start restore of backup 2-delta into /mnt/node [2025-08-05 16:20:38.481239] [264669] [0x79693fc1a4c0] [info] Backup 1-delta is chosen as shiftpoint, its Stop LSN will be used as shift LSN [2025-08-05 16:20:38.483006] [264669] [0x79693d5a66c0] [info] Restoring 2-delta chunk #0 out of 8 [2025-08-05 16:20:38.532219] [264669] [0x79693d5a66c0] [info] Restoring 2-delta chunk #1 out of 8 [2025-08-05 16:20:38.569631] [264669] [0x79693d5a66c0] [info] Restoring 2-delta chunk #2 out of 8 [2025-08-05 16:20:38.608792] [264669] [0x79693d5a66c0] [info] Restoring 2-delta chunk #3 out of 8 [2025-08-05 16:20:38.633202] [264669] [0x79693d5a66c0] [info] Restoring 2-delta chunk #4 out of 8 [2025-08-05 16:20:38.733030] [264669] [0x79693d5a66c0] [info] Restoring 2-delta chunk #5 out of 8 [2025-08-05 16:20:38.764890] [264669] [0x79693d5a66c0] [info] Restoring 2-delta chunk #6 out of 8 [2025-08-05 16:20:38.804717] [264669] [0x79693d5a66c0] [info] Restoring 2-delta chunk #7 out of 8 [2025-08-05 16:20:38.839108] [264669] [0x79693fc1a4c0] [info] Restore time 356ms [2025-08-05 16:20:38.839256] [264669] [0x79693fc1a4c0] [info] Removing redundant files in destination directory [2025-08-05 16:20:38.848171] [264669] [0x79693d5a66c0] [info] Restoring 1-delta chunk #0 out of 8 [2025-08-05 16:20:38.860342] [264669] [0x79693d5a66c0] [info] Restoring 1-delta chunk #1 out of 8 [2025-08-05 16:20:38.918134] [264669] [0x79693d5a66c0] [info] Restoring 1-delta chunk #2 out of 8 [2025-08-05 16:20:38.929649] [264669] [0x79693d5a66c0] [info] Restoring 1-delta chunk #3 out of 8 [2025-08-05 16:20:38.942811] [264669] [0x79693d5a66c0] [info] Restoring 1-delta chunk #4 out of 8 [2025-08-05 16:20:38.954785] [264669] [0x79693d5a66c0] [info] Restoring 1-delta chunk #5 out of 8 [2025-08-05 16:20:38.970253] [264669] [0x79693d5a66c0] [info] Restoring 1-delta chunk #6 out of 8 [2025-08-05 16:20:38.983111] [264669] [0x79693d5a66c0] [info] Restoring 1-delta chunk #7 out of 8 [2025-08-05 16:20:38.995516] [264669] [0x79693fc1a4c0] [info] Restore time 148ms [2025-08-05 16:20:38.997560] [264669] [0x79693d5a66c0] [info] Restoring 1-full chunk #0 out of 8 [2025-08-05 16:20:39.032484] [264669] [0x79693d5a66c0] [info] Restoring 1-full chunk #1 out of 8 [2025-08-05 16:20:39.062668] [264669] [0x79693d5a66c0] [info] Restoring 1-full chunk #2 out of 8 [2025-08-05 16:20:39.134805] [264669] [0x79693d5a66c0] [info] Restoring 1-full chunk #3 out of 8 [2025-08-05 16:20:39.160183] [264669] [0x79693d5a66c0] [info] Restoring 1-full chunk #4 out of 8 [2025-08-05 16:20:39.189998] [264669] [0x79693d5a66c0] [info] Restoring 1-full chunk #5 out of 8 [2025-08-05 16:20:39.219022] [264669] [0x79693d5a66c0] [info] Restoring 1-full chunk #6 out of 8 [2025-08-05 16:20:39.249562] [264669] [0x79693d5a66c0] [info] Restoring 1-full chunk #7 out of 8 [2025-08-05 16:20:39.279275] [264669] [0x79693fc1a4c0] [info] Restore time 282ms [2025-08-05 16:20:39.280742] [264669] [0x79693fc1a4c0] [info] INFO: Restore of backup 2-delta completed.
For details on remote incremental restore, refer to Section 3.2.6.
3.2.4. Partial Restore #
You can restore particular databases using partial restore options with the restore command. The sections below describe all supported partial restore methods.
Important
The following specifics apply to all partial restore methods:
After the Postgres Pro cluster is successfully started, drop the excluded databases using the
DROP DATABASEcommand.To decouple a single cluster containing multiple databases into separate clusters with minimal downtime, run partial restore of the cluster as a standby using the
--restore-as-replicaoption for specific databases.The
template0andtemplate1databases are always restored.
3.2.4.1. Partial Restore by Name #
If you have enabled partial restore before taking backups, you can restore specific databases by name using the --db-include-name and --db-exclude-name options.
Important
To restore databases by name, the backup must contain a database map. Without a map, filtering is possible only by OID.
To restore only the specified databases, run the restore command with the following options:
pg_probackup3 restore -Bbackup_dir--instance=instance_name--db-include-name=dbname
To exclude one or more databases from restore, use the --db-exclude-name option:
pg_probackup3 restore -Bbackup_dir--instance=instance_name--db-exclude-name=dbname
The --db-include-name and --db-exclude-name options can be specified multiple times, but cannot be used together. For example, to restore the db1 and db2 databases, run the following command:
pg_probackup3 restore -Bbackup_dir--instance=instance_name--db-include-name=db1 --db-include-name=db2
To exclude the same databases as in the previous example, run:
pg_probackup3 restore -Bbackup_dir--instance=instance_name--db-exclude-name=db1 --db-exclude-name=db2
3.2.4.2. Partial Restore by OID #
You can restore particular databases without any special preparations (unlike partial restore by name) using the --db-include-oid and --db-exclude-oid options.
To restore the specified databases only, run the restore command with the following options:
pg_probackup3 restore -Bbackup_dir--instance=instance_name--db-include-oid=dboid
Note
Information about all included databases is written to the recovery_target_db configuration parameter. Therefore, during restore, only WAL records for the included databases are processed, while others are ignored, which speeds up the operation.
To exclude one or more databases from restore, use the --db-exclude-oid option:
pg_probackup3 restore -Bbackup_dir--instance=instance_name--db-exclude-oid=dboid
The --db-include-oid and --db-exclude-oid options can be specified multiple times, but cannot be used together. For example, to restore only the db1 database with the dboid1 OID and db2 with dboid2, run the following command:
pg_probackup3 restore -Bbackup_dir--instance=instance_name--db-include-oid=dboid1 --db-include-oid=dboid2
To exclude the same databases as in the previous example, run:
pg_probackup3 restore -Bbackup_dir--instance=instance_name--db-exclude-oid=dboid1 --db-exclude-oid=dboid2
3.2.5. Performing Point-in-Time Recovery (PITR) #
You can restore the cluster to its state at an arbitrary point in time (recovery target) using recovery target options with the restore command.
Before starting PITR, make sure the following conditions are met:
You have configured continuous WAL archiving with the
wal_levelparameter set toreplicabefore taking backups.You are taking regular full and incremental backups using pg_probackup3.
You can use both STREAM and ARCHIVE backups for point-in-time recovery as long as the WAL archive contains an unbroken sequence of segments from the backup time to your recovery target time.
Follow the steps below to restore the cluster state at the exact point in time. Use your own values when applicable.
Stop the server:
pg_ctl stop -D
/path/to/database/dataRemove the data directory (
PGDATA):rm -rf
/path/to/database/data mv -f/path/to/database/logs/pg_logfile.log /tmp/demo/logs/pg_logfile.log.oldThis step is optional, as you can use a different directory for restore.
The log file preservation is recommended for diagnostic purposes.
Run the
restorecommand with the following options:pg_probackup3 restore -B
backup_dir--instance=instance_name--recovery-target-time="2024-04-10 18:18:26+03" --recovery-target-action=promoteStart the server:
pg_ctl start -D
/path/to/database/data
After the recovery is complete, a new instance will be automatically promoted to primary, and a new timeline will be created.
You can also extract a specific segment from the archive for manual recovery to a point in time or for diagnostic purposes by running the archive-get command with the --wal-file-path option containing an absolute path to the target file:
pg_probackup3 archive-get -B /backup --instance=main --wal-file-path=/var/lib/pgsql/data/pg_wal/RECOVERYXLOG --wal-file-name=000000010000000000000001
Refer to the section called “Recovery Target Options” for other supported PITR methods.
3.2.6. Remote Restore #
Remote restore in pg_probackup3 is a functionality that allows restoring backups directly to a remote host without the need to manually copy archive files. This approach significantly reduces recovery time and minimizes manual operations during disaster recovery, migration, or automated deployment. It is particularly useful in infrastructures with centralized backup storage where recovery is performed onto isolated remote servers.
The remote restore functionality consists of the following main components:
The send-backup command in the pg_probackup3 utility to send data to the specified port of the remote server using multithreading.
The pgpro_backupstream utility, manually started on the remote server, to receive, extract, and restore the data.
3.2.6.1. Prerequisites #
Before performing remote restore, fulfill the following prerequisites:
On the local host (where send-backup runs):
Install the pg_probackup3 utility and the
libpgprobackuplibrary.Make sure the backup catalog is accessible.
On the remote host (where the data will be restored):
Install the pgpro_backupstream utility.
Note
pgpro_backupstream requires manual startup.
For incremental restore (
-I), thePGDATAdirectory must exist and contain data. If the directory is empty, the operation will automatically switch to full restore mode. Ensure that the directory is in the desired state for your purposes.Ensure the specified port is open and available for incoming connections.
3.2.6.2. Restoring a Backup to a Remote Host #
To restore an instance to a remote host, perform the following steps:
Manually start the pgpro_backupstream utility on the remote host.
On the local host, run the send-backup command via the pg_probackup3 utility to send the backup data to the specified port of the remote host:
pg_probackup3 send-backup -B
backup_dir--instance=instance_name-ibackup_id-pport-hhost[--no-merge] [-Iincremental_mode] [remote_wal_archive_options]Using the
--no-mergeflag will prevent the backup chain from being merged before the data transfer. Otherwise, the backup chain will be merged into a temporary file, which will be deleted after the transfer is complete.If a backup was created in
ARCHIVEmode and its WAL archive is located on a separate server, specify its access parameters —--archive-host,--archive-port, and--archive-user(remote WAL archive options). These parameter values are passed to the remote side and used to constructrestore_commandso that the target instance can read WAL from the archive.If these parameters are omitted, the host defaults to the address used to run
send-backup, and the user defaults to the current remote user.To perform remote incremental restore, specify the
-I/--incremental-modeoption.incremental_modecan take one of the following values:CHECKSUM(recommended): All data files in the target data directory are read. For each page, the header and checksum are validated. Only pages that are invalid, or whose checksum or LSN does not match the corresponding page in the backup, are replaced. This is the simplest and most reliable incremental mode.LSN: Thepg_controlfile in the target data directory is read to obtain the redo LSN and timeline, determining the shiftpoint — the point where the data directory state diverged from the backup chain history. If the shiftpoint lies outside the backup chain history, the restore is aborted. If it lies within, all data files are read, each page header and checksum is validated, and only invalid pages and those with an LSN greater than the shiftpoint are replaced. This mode offers a greater speedup compared toCHECKSUM, but relies on two conditions:Data checksums must be enabled in the data directory (to avoid corruption due to hint bits). This condition is checked at the start of incremental restore, and the operation aborts if checksums are disabled.
The
pg_controlfile must be synchronized with the state of the data directory. This condition cannot be checked automatically, so it is the user's responsibility to ensure thatpg_controlcontains valid information. Therefore,LSNmode is not recommended in any situation wherepg_controlcannot be trusted or may have been tampered with — for example, after runningpg_resetxlogor after a restore from backup without WAL replay.
Warning
For remote incremental restore, the
-Ioption must be used together with--no-merge. Otherwise, the operation will terminate with an error.On the remote host, run the
restorecommand via the pgpro_backupstream utility to receive the backup data and perform restore:pgpro_backupstream restore -D
path_to_restore[-pport]If the port is not specified,
STDINis used.(Optional) The
send-backupcommand does not support recovery target options. Therefore, if you are restoring anARCHIVEbackup and do not want all available WAL files to be replayed on first startup, manually add the following line to thepostgresql.auto.conffile in the targetPGDATAdirectory once the restore is complete:recovery_target = 'immediate'
Important
Always start the pgpro_backupstream utility prior to running send-backup.