Rejoin the old primary as a replica after failover with pg_rewind
PostgreSQLReplicationCommand
# Prerequisite (must be set BEFORE the incident): wal_log_hints = on OR data checksums; full_page_writes = on
pg_controldata $PGDATA | grep -E 'wal_log_hints|checksum'
# 1) The old primary must be stopped:
pg_ctl -D $PGDATA stop -m fast
# 2) Dry run first:
pg_rewind --target-pgdata=$PGDATA --source-server='host=<new_primary_host> port=5432 user=postgres dbname=postgres' --progress --dry-run
# 3) Actual rewind + standby configuration (standby.signal + primary_conninfo):
pg_rewind --target-pgdata=$PGDATA --source-server='host=<new_primary_host> port=5432 user=postgres dbname=postgres' --progress --write-recovery-conf
# 4) Review postgresql.auto.conf copied from the source (port, primary_slot_name), then start:
pg_ctl -D $PGDATA startWhat it does
Makes the old primary's data directory consistent with the new primary by copying the blocks changed after the timeline divergence point from the new primary; turns it into a replica within minutes without a full basebackup.
When to use it
When the old primary comes back after a failover/promote and lags behind the new timeline with diverged changes.
Caution
Transactions left on the old primary after the failover that never reached the new primary are permanently removed. pg_rewind also copies config files (postgresql.conf, postgresql.auto.conf, pg_hba.conf) from the source; fix the port and slot settings before starting. If WAL needed since the divergence point is no longer on the source, fetch it from the archive with -c (--restore-target-wal). The source connection needs a superuser or a role with the function privileges listed in the documentation. In Patroni this is done automatically with use_pg_rewind: true.