7.3 Physical Base Backups with pg_basebackup
Key Takeaways
- Physical base backups create an exact binary copy of the entire PostgreSQL cluster directory (PGDATA) and external tablespaces at the filesystem block level, capturing all databases, system catalogs, and transaction status files.
- pg_basebackup connects to the server using the PostgreSQL streaming replication protocol over libpq, requiring a dedicated user role with the REPLICATION attribute and appropriate network permissions in pg_hba.conf.
- The utility provides two output formats: plain directory format (-F p), which reproduces a ready-to-run cluster directory, and tar format (-F t), which produces base.tar and separate tarballs for each external tablespace.
- WAL management is critical for self-consistency: -X stream opens a concurrent secondary replication connection to stream WAL records in real-time throughout the backup, whereas -X fetch gathers WAL segments only after file copying finishes and risks failure if segments are recycled.
- Starting in PostgreSQL 13, pg_basebackup generates a cryptographic backup_manifest file containing SHA256 checksums, enabling administrators to verify backup integrity using pg_verifybackup before disaster strikes.
7.3 Physical Base Backups with pg_basebackup
[!NOTE] Logical vs. Physical Backups: While
pg_dumpexports logical SQL definitions and row data from a single database, a physical base backup takes a raw, binary snapshot of the entire PostgreSQL cluster filesystem directory (PGDATA) along with all external tablespaces. Physical backups capture all databases simultaneously, system catalogs, transaction status logs (pg_xact), and configuration files. Physical backups are dramatically faster to restore than logical dumps because they bypass SQL parsing, query planning, and index generation during recovery.
The core utility for physical base backups in modern PostgreSQL is pg_basebackup. It coordinates with the running database engine to produce a consistent, standalone physical snapshot suitable for disaster recovery or for bootstrapping streaming replication standbys.
How pg_basebackup Operates
Unlike traditional operating system file-copy commands (cp or rsync)—which fail on live database clusters due to fractured blocks (torn pages written concurrently while the file is copied)—pg_basebackup coordinates directly with the PostgreSQL storage engine.
The Streaming Replication Connection
pg_basebackup connects to the PostgreSQL server over the standard PostgreSQL port (default 5432) using the PostgreSQL Streaming Replication Protocol (a specialized sub-protocol running over libpq).
To allow pg_basebackup to connect, two prerequisite security requirements must be satisfied:
- User Role Attribute: The connecting database user must possess the
REPLICATIONattribute (or be a superuser):CREATE ROLE backup_user WITH REPLICATION LOGIN PASSWORD 'SecurePass123!'; - Authentication Rules in
pg_hba.conf: The server's host-based authentication configuration must explicitly permit replication connections for that user:# TYPE DATABASE USER ADDRESS METHOD host replication backup_user 10.0.1.0/24 scram-sha-256
Internal Execution Mechanics
When pg_basebackup connects, it issues internal replication commands:
- It sends the
BASE_BACKUPreplication command. - The engine executes a checkpoint to flush dirty data buffers to disk and records a baseline Log Sequence Number (LSN).
- The engine creates a
backup_labelfile recording the backup start time, checkpoint location, and start LSN. - Raw disk blocks and files from
PGDATAare streamed across the replication connection. - Upon completion, the engine logs a backup-end WAL record and reports the stop LSN.
Output Formats: Plain Directory vs. Tar Archives
pg_basebackup supports two primary output formats, chosen using the -F (or --format) parameter:
1. Plain Directory Format (-F p or --format=plain)
- Default Mode: When no format is specified,
pg_basebackupdefaults to plain directory format. - Output: Generates an exact replica of the
PGDATAfilesystem directory in the specified target folder (-D <directory>). - Readiness: The resulting directory is immediately ready to run as a functional PostgreSQL instance (or streaming replica).
- Tablespace Handling (
-T/--tablespace-mapping): If the cluster contains external tablespaces located outsidePGDATA, plain format requires the administrator to specify--tablespace-mapping(or-T) to relocate tablespaces to new directory paths. If omitted and the backup is executed on the same host, the backup will abort to prevent overwriting live tablespace data!
# Plain directory backup with tablespace remapping
pg_basebackup -h localhost -U backup_user -D /var/backups/pgdata_plain -F p \
-T /mnt/ssd/indexes=/var/backups/tablespaces/indexes
2. Tar Archive Format (-F t or --format=tar)
- Output: Generates a set of
.tarfiles in the destination directory.- The primary cluster directory (
PGDATA) is written tobase.tar. - Each external tablespace is written to a separate tar file named after its tablespace OID (e.g.,
<tablespace_oid>.tar).
- The primary cluster directory (
- Compression Support (
-z/--gzip): Tar format supports direct gzip compression during streaming, reducing network transfer volume and storage consumption. - Standard Output Streaming: Tar archives can be streamed directly to standard output (
-D -) to pipe backups into cloud storage or encryption utilities.
# Gzip-compressed tar backup
pg_basebackup -h localhost -U backup_user -D /var/backups/pgdata_tar -F t -z -P
Handling WAL During Physical Backups: -X fetch vs. -X stream
Because a physical backup of a large database can take hours to complete, the data files copied early in the backup process will become out-of-sync with files copied later. To ensure that a restored physical backup can reach a consistent, recoverable state, the database engine requires all Write-Ahead Log (WAL) records generated between the backup start checkpoint and backup completion.
pg_basebackup controls WAL capture through the -X (or --wal-method) switch:
-X stream | --wal-method=stream (Stream WAL concurrently via 2nd connection - RECOMMENDED)
-X fetch | --wal-method=fetch (Fetch WAL segments at the conclusion of the backup)
-X none | --wal-method=none (Do not collect WAL; relies on external WAL archiving)
1. -X stream (Concurrent Streaming - Modern Default)
When -X stream is configured, pg_basebackup opens two concurrent streaming replication connections to the server:
- Connection 1 streams the raw filesystem data files.
- Connection 2 streams WAL records in real time as they are generated by the primary.
Advantages: Because WAL records are streamed concurrently, the backup is completely immune to WAL recycling on the primary! It creates a completely self-contained, standalone physical backup that can be recovered without relying on an external WAL archive. In modern PostgreSQL, -X stream is the default behavior.
[!IMPORTANT]
max_wal_sendersRequirement: Because-X streamconsumes two replication connections simultaneously, the PostgreSQL server configuration parametermax_wal_sendersmust be set to at least 2.
2. -X fetch (Fetch at End)
With -X fetch, pg_basebackup uses a single connection to copy all data files first. Once all data files have transferred, it issues a request to download the WAL segments accumulated during the backup.
The Recycled WAL Hazard: If a database experiences high write activity and the backup takes several hours, the PostgreSQL server may recycle or delete older WAL segments before pg_basebackup gets around to fetching them at the end. In this scenario, the backup immediately aborts with the fatal error:
pg_basebackup: error: could not get WAL for checkpoint: ERROR: requested WAL segment ... has already been removed.
For this reason, -X fetch is discouraged in high-throughput production environments unless wal_keep_size is set to an extraordinarily high value.
Checkpoint Mode: -c fast vs. -c spread
Before streaming data, pg_basebackup must initiate a checkpoint on the server to establish a clean starting baseline. The administrator controls how aggressively this checkpoint runs using -c (or --checkpoint):
-c fast: Forces PostgreSQL to complete the checkpoint as rapidly as possible, bypassing I/O throttling. The backup begins transferring data almost immediately, but the aggressive checkpoint can cause a temporary I/O write spike that impacts concurrent production queries.-c spread(Default): Instructs the checkpointer to throttle I/O writes smoothly across the time interval governed bycheckpoint_completion_target. This minimizes production performance degradation, butpg_basebackupmay pause for several minutes before beginning data transfer.
Bootstrapping Replicas: -R / --write-recovery-conf
A primary use case for pg_basebackup is provisioning new streaming replication read replicas. Specifying the -R (or --write-recovery-conf) flag automates replica setup:
- It creates an empty trigger file named
standby.signalin the target directory, informing PostgreSQL upon startup to run as a read-only standby. - It appends connection parameters (host, port, user, replication password) to
postgresql.auto.confvia theprimary_conninfodirective.
# Provision a standby instance ready to start
pg_basebackup -h primary.example.com -U replicator -D /var/lib/postgresql/data -F p -R -P
Backup Manifests and Verification with pg_verifybackup
Beginning in PostgreSQL 13, pg_basebackup automatically creates a metadata file named backup_manifest at the root of the backup directory.
The backup_manifest Architecture
The manifest is a structured JSON file containing:
- Backup metadata: start LSN, stop LSN, timeline ID, and checkpoint timestamp.
- A comprehensive inventory of every file in the backup, including exact byte lengths and a per-file checksum. The default algorithm is
CRC32C, not a cryptographic hash;pg_basebackup --manifest-checksumscan selectNONE,CRC32C,SHA224,SHA256,SHA384, orSHA512when you need a cryptographic digest instead. - A list of all WAL segments required to achieve consistency.
Verifying Integrity via pg_verifybackup
Taking a backup is useless if bit rot, disk corruption, or aborted network transfers render it unbootable. PostgreSQL includes the standalone command-line verification utility pg_verifybackup:
# Verify physical backup integrity against the manifest
pg_verifybackup /var/backups/pgdata_plain
# Verify a backup with an external manifest path
pg_verifybackup -m /secure/backup_manifest /var/backups/pgdata_plain
pg_verifybackup reads the manifest, recalculates checksums across every file on disk, verifies file lengths, and validates that all required WAL ranges are present. If a single page has corrupted bits or a file was deleted, pg_verifybackup reports the discrepancy immediately.
[!TIP]
CRC32Cis fast and detects accidental corruption, but it is not a cryptographic hash and does not defend against deliberate tampering of an archived backup. If your compliance regime requires tamper evidence, take the backup withpg_basebackup --manifest-checksums=SHA256, which costs measurable extra CPU on the backup host.
Summary of Key pg_basebackup Flags
| Option | Long Option | Function |
|---|---|---|
-D <dir> | --pgdata=<dir> | Destination directory for plain backup or tar archives. |
-F p / -F t | --format=plain / tar | Output format: plain directory or tarballs. |
-X s / -X f | --wal-method=stream / fetch | Streaming concurrent WAL vs. fetching at conclusion. |
-c fast / -c spread | --checkpoint=fast / spread | Immediate checkpoint vs. throttled I/O checkpoint. |
-R | --write-recovery-conf | Writes standby.signal and primary_conninfo. |
-P | --progress | Displays real-time transfer progress and throughput. |
-T old=new | --tablespace-mapping=old=new | Relocates external tablespace directories. |
-z | --gzip | Enables gzip compression (tar format only). |
Exam Tips and Common Pitfalls
- Exam Trap: Protocol and Permissions:
pg_basebackupdoes not run over standard SQL query sessions; it connects via the Streaming Replication Protocol. The connecting role must have theREPLICATIONattribute, andpg_hba.confmust have areplicationdatabase entry. - Exam Trap: Missing Connections for
-X stream: If an administrator configurespg_basebackup -X streamand receives connection errors, verifymax_wal_senders. Streaming WAL concurrently requires at least two available WAL sender slots. - Exam Trap: Tablespace Overwrite Hazard: When taking a plain-format (
-F p) backup of a database with external tablespaces on the same server, you must use-T(--tablespace-mapping). Otherwise,pg_basebackupwill attempt to write the tablespace into its original live directory and abort to prevent data corruption. - Exam Trap: Manifest Verification: The
backup_manifestfile is generated automatically bypg_basebackupin PostgreSQL 13+, and is validated offline usingpg_verifybackup. Its per-file checksums default toCRC32C; SHA-family digests are available but must be requested with--manifest-checksums.
An administrator is executing a physical base backup of a busy 1TB transactional cluster using the command 'pg_basebackup -D /backup/base -F p -X fetch'. After running for 3 hours, the command terminates with the error: 'pg_basebackup: error: could not get WAL for checkpoint: ERROR: requested WAL segment ... has already been removed'. What is the root cause of this failure and how should the command be adjusted?
A PostgreSQL cluster has an external tablespace located on a mounted storage volume at '/mnt/data/fast_tablespace'. An administrator runs 'pg_basebackup -h localhost -U replicator -D /backups/pgdata -F p' on the same physical host. Why does the backup command fail immediately before copying any files?
How does the pg_verifybackup utility, introduced in PostgreSQL 13, validate the integrity of a physical base backup?