DB replication + pgpool routing verification (runbook)
Path convention: $REPO_ROOT = monorepo clone (DEVELOPMENT.md).
Prerequisites
- Stack is up:
cd $REPO_ROOTdocker compose ps
- Services expected:
postgres,postgres-replica,pgpool,db-guard,api
Commands
1) Replication health (primary + replica)
-
Replica is a standby:
docker compose exec -T postgres-replica psql -U postgres -d postgres -c "SELECT pg_is_in_recovery() AS is_replica;"- Expect:
t
-
Primary sees a streaming standby:
docker compose exec -T postgres psql -U postgres -d postgres -c "SELECT application_name, state, sync_state, replay_lag FROM pg_stat_replication;"- Expect at least one row with
state=streaming
-
Replication slot exists (prevents WAL recycling while standby is behind):
docker compose exec -T postgres psql -U postgres -d postgres -c "SELECT slot_name, slot_type, active, restart_lsn FROM pg_replication_slots;"- Expect:
replica1(or your configured slot name),slot_type=physical
2) WAL archive (catch-up beyond streaming)
- Confirm WAL segments are being archived by the primary:
docker compose exec -T postgres sh -lc "ls -la /wal-archive | head"- Expect: files like
000000010000....
3) pgpool node status (read-splitting eligibility)
- From the primary container (psql client available), query pgpool:
docker compose exec -T postgres sh -lc 'PGPASSWORD=postgres psql -h pgpool -p 5432 -U postgres -d postgres -c \"show pool_nodes;\"'- Expect:
- node 0 role
primary - node 1 role
standby load_balance_nodeistruefor the standby when healthy
- node 0 role
4) Sync + auto-degrade mode (db-guard)
-
Check current sync settings (primary):
docker compose exec -T postgres psql -U postgres -d postgres -c "SHOW synchronous_commit;"docker compose exec -T postgres psql -U postgres -d postgres -c "SHOW synchronous_standby_names;"
-
Watch db-guard for mode transitions:
docker compose logs -f db-guard
Manual simulation (optional, disruptive):
- Stop replica and confirm degrade:
docker compose stop postgres-replica- Expect db-guard logs: “detaching replica” and
synchronous_standby_namesbecomes empty.
- Start replica and confirm recovery:
docker compose up -d postgres-replica- Expect db-guard logs: “attaching replica” and
synchronous_standby_namesbecomes non-empty.
Stop conditions
- Replica is
streamingagain and (when healthy)sync_state=sync. show pool_nodes;shows standby nodeupand eligible for load balancing.- WAL archive is receiving segments and replication slot exists.