🚧 Under construction — VoTechWorks is being built. A free tech program — complimentary, as our commitment to get America working.
voTechWorksGrade 13 · a vocational technology learning center, by urbanicity
newSchoolWorks.com › VoTechWorks › Technology & Design › Data Management / Database Administration › Database Backup and Recovery › Lesson 3
TEC-DATA86-04 · Lesson 3 · 14 clock hours · lab

PostgreSQL Physical Backups: pg_basebackup and WAL Archiving

Objective. Students will configure WAL archiving, take a base backup with pg_basebackup, and perform a point-in-time recovery to a target timestamp using a recovery configuration file.

⚠ Pending professional review

This lesson, its worked examples and its practice questions has not yet been verified by an industry-certified professional or by a certification or approval body. It is a study draft and may contain errors. Do not use it as instructions for work on a job site or on live equipment. Always follow your instructor, your supervising professional, and current official references and regulations.

VoTechWorks program approval and accreditation are still in progress. Credentials are issued only by the certifying bodies named in each program, after their own exams.

PostgreSQL Physical Backups: pg_basebackup and WAL Archiving

Why Physical Backups Matter

A physical backup copies the actual data files that make up a PostgreSQL cluster—the base directory, tablespace files, and Write-Ahead Log (WAL) segments. Unlike a logical backup (pg_dump), a physical backup captures the cluster at the binary level, making it the foundation of Point-In-Time Recovery (PITR). PITR lets you restore a database to any precise moment in the past, not just the moment a backup was taken. This capability is essential for database administrators responding to accidental data deletion, application errors, or corruption.

Understanding WAL and WAL Archiving

PostgreSQL records every change to data in the Write-Ahead Log before applying it to the actual data files. WAL segments are fixed-size files (16 MB by default) stored in `pg_wal/`. The server reuses old segments once they are no longer needed for crash recovery. To support PITR, you must preserve every WAL segment generated after your base backup by archiving them to a safe location before the server recycles them.

WAL archiving requires three settings in `postgresql.conf`:

```

archive_command = 'cp %p /mnt/wal_archive/%f'

```

Here `%p` is the full path to the source WAL file and `%f` is just the filename. The command must return exit code 0 only on success. If the command fails, PostgreSQL retries it and keeps the WAL segment safe until archiving succeeds.

After editing `postgresql.conf`, reload the server with `pg_ctl reload` or `SELECT pg_reload_conf();`. Force a WAL switch with `SELECT pg_switch_wal();` to confirm the first segment appears in your archive directory.

Taking a Base Backup with pg_basebackup

`pg_basebackup` connects to the running server using the replication protocol and copies the entire data directory in a consistent state. The command used in this lab is:

```bash

pg_basebackup -Ft -z -P -Xs -D /path/to/backup_dir

```

| Flag | Meaning |

|------|---------|

| `-Ft` | Output format: tar |

| `-z` | Compress with gzip |

| `-P` | Show progress |

| `-Xs` | Stream WAL during the backup using a second connection |

| `-D` | Destination directory |

The backup produces `base.tar.gz` (the data directory) and `pg_wal.tar.gz` (WAL segments generated during the backup). Inside `base.tar.gz` is a `backup_label` file recording the backup start LSN (Log Sequence Number), the timeline, and the start time. Record this information in your lab log—you need it to confirm recovery.

The replication connection requires a user with the `REPLICATION` privilege, and `pg_hba.conf` must permit it. Verify before running the backup.

Simulating Ongoing Transactions

After the backup, insert rows at intervals to create a known transaction history. A simple bash loop:

```bash

for i in $(seq 1 10); do

psql -c "INSERT INTO test_table(note, ts) VALUES ('batch_$i', now());"

sleep 30

done

```

Record the timestamp after each batch. You will use one of these timestamps as your recovery target.

Point-In-Time Recovery Procedure

Step 1 — Stop the server and remove the data directory.

Stop PostgreSQL cleanly with `pg_ctl stop -m fast`. Move or delete the existing data directory. Never skip a clean shutdown if the server is reachable; it reduces the WAL replay needed and confirms no clients are connected.

Step 2 — Restore the base backup.

Extract `base.tar.gz` into the new data directory. Extract `pg_wal.tar.gz` into `pg_wal/` inside that directory.

Step 3 — Copy archived WAL segments.

Copy your archived WAL segments into `pg_wal/` so the recovery process can replay them. Alternatively, configure `restore_command` to pull them on demand.

Step 4 — Create the recovery signal file.

In PostgreSQL 12 and later, create an empty file named `recovery.signal` in the data directory. Its presence tells the server to enter recovery mode at startup.

Step 5 — Set recovery parameters in postgresql.conf.

Add or uncomment:

```

restore_command = 'cp /mnt/wal_archive/%f %p'

recovery_target_time = '2025-06-10 14:35:00'

recovery_target_action = 'promote'

```

Set `recovery_target_time` to a timestamp that falls between two known insert batches.

Step 6 — Start the server and verify.

Start PostgreSQL. Watch the server log for messages confirming WAL replay and the recovery stopping at the target time. Connect and run `SELECT COUNT(*) FROM test_table;` — the count must exactly match the expected number of rows inserted before your target timestamp.

Safety and Best Practices

Key terms8

Write-Ahead Log (WAL)A sequential log of all changes made to PostgreSQL data files; changes are written here before being applied to data pages, enabling crash recovery and replication.
WAL ArchivingThe process of copying completed WAL segments to a separate location before the server recycles them, preserving the ability to replay transactions for point-in-time recovery.
Base BackupA physical, binary copy of the entire PostgreSQL data directory taken while the server is running, using pg_basebackup; it is the starting point for any PITR restore.
Point-In-Time Recovery (PITR)The ability to restore a PostgreSQL cluster to any specific moment by replaying WAL segments from a base backup up to a designated target time, LSN, or transaction ID.
Log Sequence Number (LSN)A unique identifier representing a byte position within the WAL stream; used to track where a backup started and where recovery should stop.
recovery.signalAn empty file placed in the PostgreSQL data directory (PostgreSQL 12+) that instructs the server to enter archive recovery mode on startup instead of normal operation.
archive_commandA postgresql.conf parameter containing a shell command PostgreSQL executes to copy each completed WAL segment to the archive location; must return exit code 0 only on success.
restore_commandA postgresql.conf parameter containing a shell command used during recovery to fetch archived WAL segments from the archive directory so the server can replay them.
In class: Edit postgresql.conf to set wal_level = replica, archive_mode = on, and archive_command pointing to a local archive directory; reload the server and confirm the first WAL segment is copied by inspecting the archive directory. · Run pg_basebackup -Ft -z -P -Xs to stream and compress a base backup; record the backup start LSN from the backup_label file and simulate ongoing transactions by inserting rows into a test table every 30 seconds using a provided shell loop. · Stop the server, remove the data directory, restore from the base backup, write a recovery signal file and postgresql.conf recovery_target_time set to a specific timestamp between two known insert batches, start the server, and verify only the expected rows are present.
Materials: Lab workstations running PostgreSQL 15 or later; bash shell; pg_basebackup; postgresql.conf and pg_hba.conf; PostgreSQL documentation on WAL archiving and PITR (Sections 26.3–26.4); lab log template
Check: Student demonstrates a live PITR to an instructor-specified timestamp in under 10 minutes during a lab check; recovered row count must exactly match expected value; 100% of required steps must appear in lab log.

Practice check8

Answer each question, then check it. Nothing is recorded; this is your own practice.

PostgreSQL CE — Configuration and Administration
1. Which postgresql.conf setting must be configured to enable WAL archiving in PostgreSQL?
PostgreSQL CE — Backup and Recovery
2. In the archive_command string 'cp %p /mnt/wal_archive/%f', what does %f represent?
PostgreSQL CE — Backup and Recovery
3. What is the purpose of the backup_label file created inside a pg_basebackup archive?
PostgreSQL CE — Backup and Recovery
4. In PostgreSQL 12 and later, how does the administrator signal the server to enter archive recovery mode on startup?
PostgreSQL CE — Backup and Recovery
5. Which pg_basebackup flag causes WAL segments to be streamed during the backup using a second server connection?
PostgreSQL CE — Backup and Recovery
6. After a successful point-in-time recovery stops at the target timestamp, which recovery_target_action value causes the server to become writable and accept new connections?
PostgreSQL CE — Backup and Recovery
7. An administrator's archive_command silently succeeds (exits 0) even when the copy fails due to a full disk. What is the most likely consequence?
DAMA CDMP — Data Storage and Operations
8. Which DAMA DMBOK knowledge area most directly governs the policies and procedures for database backup, recovery testing, and data retention?
Record this lesson on my transcript. Sign in with your key and enrollment email to record lessons (enroll free if you have no key). This page stays open to read and practise.