Last active
June 13, 2026 17:31
-
-
Save rednafi/6812c61fd022715e1d94989d49077324 to your computer and use it in GitHub Desktop.
PostgreSQL 19 beta primary + streaming replica lab for the WAIT FOR LSN post
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/sh | |
| # PostgreSQL 19 beta primary + streaming replica in Docker. | |
| # Companion lab for https://rednafi.com/system/wait-for-lsn/ | |
| # | |
| # The replica streams from the primary but applies every commit a fixed time | |
| # late (recovery_min_apply_delay), so replication lag is real and reproducible. | |
| # Pass the delay as the first argument; it defaults to 10s. | |
| # | |
| # curl -fsSL .../wait_for_lsn_lab.sh | sh # 10s delay | |
| # curl -fsSL .../wait_for_lsn_lab.sh | sh -s 30s # 30s delay | |
| # | |
| # Warning: removes any existing pg-primary / pg-replica containers | |
| # and the pgnet network before starting fresh. | |
| set -eu | |
| DELAY="${1:-10s}" | |
| docker rm -f pg-primary pg-replica 2>/dev/null || true | |
| docker network rm pgnet 2>/dev/null || true | |
| docker network create pgnet | |
| docker run -d --name pg-primary --network pgnet \ | |
| -e POSTGRES_PASSWORD=secret postgres:19beta1 | |
| # The image runs a temporary server on the unix socket during initdb, so probe | |
| # over TCP instead; the temp server has listen_addresses='' and never answers it. | |
| until docker exec pg-primary pg_isready -h 127.0.0.1 -U postgres >/dev/null 2>&1; do | |
| sleep 1 | |
| done | |
| # Allow replication connections on the primary | |
| docker exec pg-primary psql -U postgres \ | |
| -c "CREATE USER replicator WITH REPLICATION PASSWORD 'replpass';" | |
| docker exec pg-primary bash -c \ | |
| 'echo "host replication replicator all scram-sha-256" >> "$PGDATA/pg_hba.conf"' | |
| docker exec pg-primary psql -U postgres -c "SELECT pg_reload_conf();" | |
| # Clone the primary with pg_basebackup and start the replica with the apply delay | |
| docker run -d --name pg-replica --network pgnet -u postgres \ | |
| -e PGPASSWORD=replpass -e APPLY_DELAY="$DELAY" --entrypoint bash postgres:19beta1 -c ' | |
| until pg_basebackup -h pg-primary -U replicator \ | |
| -D /var/lib/postgresql/replica -R -X stream; do | |
| sleep 1 | |
| done | |
| exec postgres -D /var/lib/postgresql/replica -c recovery_min_apply_delay="$APPLY_DELAY"' | |
| until docker exec pg-replica pg_isready -h 127.0.0.1 -U postgres >/dev/null 2>&1; do | |
| sleep 1 | |
| done | |
| echo "" | |
| echo "Primary: docker exec -it pg-primary psql -U postgres" | |
| echo "Replica: docker exec -it pg-replica psql -U postgres (applies commits ${DELAY} late)" | |
| echo "Teardown: docker rm -f pg-primary pg-replica && docker network rm pgnet" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment