Skip to content

Backup Mechanism

pgBackRest concepts—stanzas, repositories, backup chains, retention, and timelines—and how Pigsty maps parameters to commands.

Pigsty’s backup and restore operations execute pgBackRest commands. For safe operation, understand the pgBackRest model and how Pigsty maps its orchestration parameters to native options.


Core pgBackRest Concepts

Stanza: the Cluster’s Backup Identity

A stanza names one PostgreSQL backup configuration and isolates that cluster inside a repository. Pigsty uses pg_cluster as the stanza name. The pg-meta stanza stores data under backup/pg-meta/ and archive/pg-meta/. Thus, several clusters can share one repository.

The stanza records the source system identifier and major version. pgBackRest checks these values before a backup. Because of this check, a cross-cluster clone needs stanza-upgrade afterward. Pigsty creates the stanza during cluster initialization. stanza-upgrade updates it after a major-version change or clone.

Repository: Where Backups Live

A repository stores backup files and WAL archives. repo1-type selects POSIX, S3, Azure, GCS, or SFTP. repo1-path, repo1-cipher-*, and repo1-retention-* define location, encryption, and retention. Pigsty generates these settings from pgbackrest_repo. See Backup Repository.

Backup Chains and Labels

TypeContentsLabel suffix
FullComplete database-cluster copyF
DifferentialChanges since the latest fullD
IncrementalChanges since the latest backup of any typeI

Labels identify the backup chain. 20250715-013657F is a full backup. 20250715-013657F_20250715-013724D and ..._20250715-013730I depend on the full backup identified before the underscore. Use --set to select the starting backup explicitly. Otherwise, pgBackRest selects the newest usable set before the target.

Retention: Keeping the Repository Bounded

repo1-retention-full and repo1-retention-full-type (count or time) determine when full backup chains expire. Dependent differential/incremental backups and WAL needed only by that chain expire with the full backup. Pigsty enables expire-auto. Use pig pb expire --plan to preview a manual run.

Time retention defines a minimum window. It does not remove every full backup older than N days. An old full backup expires only when another retained full backup has reached that age. With weekly full backups, a 14-day setting therefore commonly retains three full chains and approximately 14–21 days of history.

WAL Archiving

PostgreSQL calls archive-push when a WAL segment fills or archive_timeout elapses. During recovery, restore_command calls archive-get. Pigsty enables asynchronous archiving through /pg/spool. Thus, a temporary repository delay does not block the primary directly.

Timelines

Each promotion after recovery or failover creates a new timeline. Older timeline history remains in the repository. --target-timeline selects the recovery branch and defaults to latest. See the conceptual PITR mechanism.

What restore Actually Does

restore first reconstructs the data directory. Pigsty enables --delta, so pgBackRest validates existing files and rewrites only files that differ. It then writes the recovery state (recovery.signal, restore_command, and recovery_target_*). WAL replay starts after PostgreSQL starts.

A successful restore command does not complete PITR. --target-action controls what happens when replay reaches the target: pause, promote, or shutdown.

pgbackrest --stanza=pg-meta restore
pgbackrest --stanza=pg-meta --type=immediate restore
pgbackrest --stanza=pg-meta --type=time --target='2025-07-13 10:00:00+00' restore
pgbackrest --stanza=pg-meta --type=xid --target='250000' --target-exclusive restore
pgbackrest --stanza=pg-meta --type=name --target='my-restore-point' restore
pgbackrest --stanza=pg-meta --type=lsn --target='0/4001C80' --target-action=promote restore

Observe a Backup Chain

Run read-only info after full, differential, and incremental backups to inspect labels, size, WAL bounds, and references:

pig pb info

A representative sequence looks like:

full backup: 20250715-013657F
diff backup: 20250715-013657F_20250715-013724D
    backup reference total: 1 full
incr backup: 20250715-013657F_20250715-013730I
    backup reference total: 1 full, 1 diff

Pigsty’s Wrapper Layers

LayerInterfaceWhat it does
Cluster orchestrationpg_pitr + pgsql-pitr.ymlPause HA, stop nodes, render configuration, restore/replay, inspect control data, clean etcd, and rebuild HA
Instance orchestrationpig pitrPreflight, keep one target offline, restore, optionally start PostgreSQL, and leave Patroni stopped for inspection
Command primitivepig pb, pb, pg-backupSupply stanza/DBSU context and call the corresponding pgBackRest command
EnginepgbackrestRead /etc/pgbackrest/pgbackrest.conf and perform backup, archive, and restore operations

Command Primitives

pb is a login-shell function that reads the first stanza from the local configuration and forwards arguments:

pb() (
    stanza=$(grep -o '\[[^][]*]' /etc/pgbackrest/pgbackrest.conf | head -n1 | sed 's/.*\[\([^]]*\)].*/\1/')
    pgbackrest --stanza="${stanza}" "$@"
)
pb info     # pgbackrest --stanza=pg-meta info
pb backup   # pgbackrest --stanza=pg-meta backup

pg-backup adds a primary-role check for scheduled use:

pg-backup full
pg-backup diff
pg-backup incr   # the default; pgBackRest promotes it when no full exists

pig pb adds stanza detection, DBSU privilege handling, primary checks for backup, and plan/confirmation guards for destructive primitives. See Admin Commands.

Parameter Mapping

pg_pitr fieldpig pitr optionpgBackRest optionMeaning
cluster--stanza--stanzaSource cluster/stanza
type plus time/xid/lsn/namecorresponding target option--type + --targetRecovery target
default--defaultno --type/--targetReplay to archive end
immediate--immediate--type=immediateStop at the first consistent point
exclusive--exclusive / -X--target-exclusiveStop before the target
action--target-action--target-actionpause, promote, or shutdown
timeline--target-timeline / -T--target-timelineTarget timeline
set--set / -b--setStarting backup set
db_include / db_exclude—--db-include / --db-excludeSelect databases in a physical restore
link_map—--link-mapRemap directory or tablespace links
process—process-maxParallel restore processes
data--data / -D--pg1-pathTarget data directory
reporepository number only in pig pitrrendered repo1-*Override repository definition in the playbook

A selective restore is still a physical restore. Excluded databases receive sparse zeroed files so PostgreSQL can complete recovery. These databases are inaccessible. You must remove them explicitly afterward. This is not a logical subset as with pg_dump.

How Configuration Is Rendered

pgbackrest_method selects the entry that Pigsty writes to /etc/pgbackrest/pgbackrest.conf. Pigsty converts underscores to hyphens and adds the repo1- prefix to keys.

pgbackrest_repo:
  minio:
    type: s3                  # repo1-type=s3
    s3_endpoint: sss.pigsty   # repo1-s3-endpoint=sss.pigsty
    cipher_type: aes-256-cbc  # repo1-cipher-type=aes-256-cbc
    retention_full: 14        # repo1-retention-full=14

pgsql-pitr.yml generates a separate temporary configuration at /pg/conf/pitr.conf. PostgreSQL recovery output goes to /pg/tmp/recovery.log.


Scheduled Backups

Pigsty installs pg_crontab entries for the postgres OS user on every cluster node. pg-backup checks the current role, so only the primary makes backups. After promotion, the new primary runs future scheduled backups.

pg_crontab:
  - '00 01 * * 1 /pg/bin/pg-backup full'
  - '00 01 * * 2,3,4,5,6,7 /pg/bin/pg-backup'
./pgsql.yml -t pg_crontab -l pg-meta

See Backup Policy for frequency and retention design.


Deployment Details

The pg_backup subtask installs and configures pgBackRest, then creates the stanza. If pgbackrest_init_backup is enabled, it attempts an initial full backup. It writes /etc/pgbackrest/initial.done only after that backup succeeds.

PathPurpose
/usr/bin/pgbackrestpgBackRest binary
/etc/pgbackrest/pgbackrest.confMain stanza and repository configuration
/pg/backupLocal repository path
/pg/spoolAsynchronous archive spool
/pg/log/pgbackrest/Backup, archive, and restore logs
/pg/conf/pitr.confTemporary PITR configuration
/pg/tmp/recovery.logPostgreSQL recovery log

pgbackrest_exporter exports backup metrics and listens on pgbackrest_exporter_port, which defaults to 9854. To disable it, use pgbackrest_exporter_enabled. To customize it, use pgbackrest_exporter_options.

Was this page helpful?