Lab 02: PostgreSQL Streaming Replication

Time: 45 minutes | Level: Advanced | DB: PostgreSQL 15

Overview

Configure PostgreSQL streaming replication where the standby continuously receives WAL (Write-Ahead Log) segments from the primary. This is the basis for PostgreSQL HA setups using tools like Patroni, repmgr, and Stolon.


Step 1: Launch PostgreSQL Primary

docker network create pg-replication

# Start primary with WAL streaming enabled
docker run -d \
  --name pg-primary \
  --network pg-replication \
  -e POSTGRES_PASSWORD=rootpass \
  -e POSTGRES_DB=testdb \
  postgres:15 \
  -c wal_level=replica \
  -c max_wal_senders=5 \
  -c max_replication_slots=5 \
  -c hot_standby=on \
  -c archive_mode=on \
  -c archive_command='cp %p /tmp/pg_archive/%f'

sleep 10
docker exec pg-primary psql -U postgres -c "SELECT version();"

💡 wal_level=replica enables streaming replication. hot_standby=on allows read queries on the standby. max_wal_senders limits concurrent replication connections.

📸 Verified Output:


Step 2: Configure Primary — Create Replication User and Slot

📸 Verified Output:


Step 3: Configure pg_hba.conf for Replication Connections

📸 Verified Output:

💡 pg_reload_conf() reloads pg_hba.conf and postgresql.conf without restarting. For parameters marked "requires restart", you must restart PostgreSQL.


Step 4: Take Base Backup with pg_basebackup

💡 -R flag automatically creates standby.signal and writes primary_conninfo to postgresql.auto.conf. This is the modern way (PostgreSQL 12+) — no more recovery.conf.

📸 Verified Output:


Step 5: Launch the Standby with Replication Signal

📸 Verified Output:


Step 6: Monitor Streaming Replication

📸 Verified Output:

💡 When sent_lsn = replay_lsn the standby is fully caught up. write_lag/flush_lag/replay_lag = NULL means zero lag.


Step 7: Verify WAL File Generation

📸 Verified Output:


Step 8: Capstone — Promote Standby to Primary

📸 Verified Output:


Summary

Component
Setting
Purpose

wal_level

replica

Enable WAL streaming

max_wal_senders

5

Max concurrent replication connections

hot_standby

on

Allow reads on standby

Replication slot

pg_create_physical_replication_slot()

Prevent WAL cleanup before replica reads

pg_basebackup

-R --slot

Take base backup + auto-configure standby

standby.signal

File existence

Marks server as standby

pg_stat_replication

Primary view

Monitor replication lag

pg_is_in_recovery()

true on standby

Distinguish primary from standby

pg_promote()

PostgreSQL 12+

Promote standby without restart

Key Takeaways

  • Replication slots prevent WAL cleanup — critical but can fill disk if replica falls far behind

  • hot_standby=on enables read offloading — send SELECTs to standby

  • pg_basebackup -R auto-generates standby config — simplest setup path

  • pg_stat_replication is your replication dashboard — check replay_lag regularly

  • Modern failover tools (Patroni, repmgr) automate the promote + reconfigure-other-replicas flow

Last updated