From 28acbcaa8da954f35429577f8fe27ef84ac100c8 Mon Sep 17 00:00:00 2001 From: souravbiswassanto Date: Tue, 23 Jun 2026 15:36:05 +0600 Subject: [PATCH 1/6] Populate /role_scripts/standby for remote replica coordinator support Signed-off-by: souravbiswassanto --- init_scripts/run.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/init_scripts/run.sh b/init_scripts/run.sh index 20f9e1d..503d541 100755 --- a/init_scripts/run.sh +++ b/init_scripts/run.sh @@ -11,8 +11,9 @@ export remote_replica=${REMOTE_REPLICA:-false} export source_ssl=${SOURCE_SSL:-false} if [[ $remote_replica == "true" ]]; then - mkdir -p /run_scripts/role + mkdir -p /run_scripts/role /role_scripts/standby cp -r /tmp/role_scripts/$MAJOR_PG_VERSION/standby/* /run_scripts/role/ + cp -r /tmp/role_scripts/$MAJOR_PG_VERSION/standby/* /role_scripts/standby/ elif [[ $STANDALONE == "true" ]]; then mkdir -p /run_scripts/role cp -r /tmp/role_scripts/$MAJOR_PG_VERSION/primary/* /run_scripts/role/ From 084b35fc2066e90c4eb7639958df0b74f3cf02d8 Mon Sep 17 00:00:00 2001 From: souravbiswassanto Date: Thu, 25 Jun 2026 15:02:43 +0600 Subject: [PATCH 2/6] primary/start.sh: promote from recovery before writes to fork a new timeline When a former standby is started via the primary role script (most importantly the remote-replica -> standalone-HA promotion), standby.signal is present and pg_ctl start brings postgres up in recovery. Previously start.sh removed standby.signal and then ran CREATE DATABASE / ALTER USER writes before the trailing pg_ctl promote; the writes fail under read-only recovery, so on the loop's retry postgres started directly as a primary on the EXISTING timeline and the trailing promote was a no-op. The new HA primary thus stayed on the same timeline as its old source cluster, which on failback forces a full pg_basebackup instead of pg_rewind (a whole-day op at multi-TB scale). Fix: as soon as postgres has started, if standby.signal is present, run pg_ctl promote (which ends recovery, increments the timeline, and clears standby.signal) and wait until pg_is_in_recovery() is false, BEFORE any write. The writes then run against the promoted primary on the new timeline. Scope: only affects a node started via the primary script with standby.signal present (the promotion case). A normal primary start (no standby.signal) and the live-standby fast-failover path (promoted by the coordinator via gRPC, not start.sh) are unchanged. Signed-off-by: souravbiswassanto --- role_scripts/17/primary/start.sh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/role_scripts/17/primary/start.sh b/role_scripts/17/primary/start.sh index fc05df8..e1e25d3 100755 --- a/role_scripts/17/primary/start.sh +++ b/role_scripts/17/primary/start.sh @@ -95,6 +95,25 @@ export POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-postgres} psql=(psql -v ON_ERROR_STOP=1) +# If standby.signal is present, postgres started in recovery above (this node was a standby being +# promoted). Promote it NOW to fork a NEW timeline BEFORE any write below. This is essential for the +# remote-replica -> standalone-HA transition: without promoting from recovery the node comes up on +# the SAME timeline as its former source cluster, which on failback forces a full pg_basebackup +# instead of pg_rewind. Promotion ends recovery, increments the timeline, and removes standby.signal. +# A normal primary start (no standby.signal) skips this block, so fresh bootstrap and the live-standby +# fast-failover path (which promotes via the coordinator, not start.sh) are unaffected. +if [[ -f "/var/pv/data/standby.signal" ]]; then + echo "standby.signal present -> promoting to fork a new timeline before writes" + pg_ctl -D "$PGDATA" promote || true + for _ in $(seq 1 120); do + if [[ "$("${psql[@]}" --username postgres -tAc "SELECT pg_is_in_recovery();" 2>/dev/null)" == "f" ]]; then + echo "promotion complete; node is now primary on a new timeline" + break + fi + sleep 1 + done +fi + # create database with specified name if [ "$POSTGRES_DB" != "postgres" ]; then "${psql[@]}" --username postgres <<-EOSQL From 3b816f86a3712f62416851bd48d176216d4010d0 Mon Sep 17 00:00:00 2001 From: souravbiswassanto Date: Thu, 25 Jun 2026 15:17:56 +0600 Subject: [PATCH 3/6] primary/start.sh: use pg_controldata (not a DB connection) to await promotion The post-promote wait must not depend on connecting as the postgres superuser: if that role is missing/renamed the psql probe fails and the loop burns its full 120s timeout. Poll pg_controldata's cluster state (in archive recovery -> in production) instead, which needs no DB connection or role. Signed-off-by: souravbiswassanto --- role_scripts/17/primary/start.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/role_scripts/17/primary/start.sh b/role_scripts/17/primary/start.sh index e1e25d3..d636bb6 100755 --- a/role_scripts/17/primary/start.sh +++ b/role_scripts/17/primary/start.sh @@ -105,8 +105,12 @@ psql=(psql -v ON_ERROR_STOP=1) if [[ -f "/var/pv/data/standby.signal" ]]; then echo "standby.signal present -> promoting to fork a new timeline before writes" pg_ctl -D "$PGDATA" promote || true + # Wait until recovery has ended using pg_controldata (no DB connection / role dependency, so a + # missing or renamed superuser role can never stall this loop). State goes from + # "in archive recovery" to "in production" once promotion completes. for _ in $(seq 1 120); do - if [[ "$("${psql[@]}" --username postgres -tAc "SELECT pg_is_in_recovery();" 2>/dev/null)" == "f" ]]; then + state=$(pg_controldata "$PGDATA" 2>/dev/null | grep "Database cluster state" | sed 's/.*:[[:space:]]*//') + if [[ "$state" == "in production" ]]; then echo "promotion complete; node is now primary on a new timeline" break fi From 33df0a80c41ae9606d36affd53c772c642616d3f Mon Sep 17 00:00:00 2001 From: souravbiswassanto Date: Thu, 25 Jun 2026 20:52:17 +0600 Subject: [PATCH 4/6] primary/start.sh: port promote-from-recovery to PG 13-16,18 Apply the same promote-before-writes fix already in PG17 to the other supported major versions (13,14,15,16,18) so the remote-replica -> standalone-HA timeline bump works regardless of PostgreSQL version. When standby.signal is present at startup (a former standby being promoted), pg_ctl promote runs before the CREATE DATABASE / ALTER USER writes, forking a new timeline so failback uses pg_rewind instead of a full pg_basebackup. Versions < 13 are out of scope. Signed-off-by: souravbiswassanto --- role_scripts/13/primary/start.sh | 20 ++++++++++++++++++++ role_scripts/14/primary/start.sh | 20 ++++++++++++++++++++ role_scripts/15/primary/start.sh | 20 ++++++++++++++++++++ role_scripts/16/primary/start.sh | 20 ++++++++++++++++++++ role_scripts/18/primary/start.sh | 20 ++++++++++++++++++++ 5 files changed, 100 insertions(+) diff --git a/role_scripts/13/primary/start.sh b/role_scripts/13/primary/start.sh index c4ab448..0675b8d 100755 --- a/role_scripts/13/primary/start.sh +++ b/role_scripts/13/primary/start.sh @@ -91,6 +91,26 @@ export POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-postgres} psql=(psql -v ON_ERROR_STOP=1) +# If standby.signal is present, postgres started in recovery above (this node was a standby being +# promoted). Promote it NOW to fork a NEW timeline BEFORE any write below. This is essential for the +# remote-replica -> standalone-HA transition: without promoting from recovery the node comes up on +# the SAME timeline as its former source cluster, which on failback forces a full pg_basebackup +# instead of pg_rewind. Promotion ends recovery, increments the timeline, and removes standby.signal. +# A normal primary start (no standby.signal) skips this block, so fresh bootstrap and the live-standby +# fast-failover path (which promotes via the coordinator, not start.sh) are unaffected. +if [[ -f "/var/pv/data/standby.signal" ]]; then + echo "standby.signal present -> promoting to fork a new timeline before writes" + pg_ctl -D "$PGDATA" promote || true + for _ in $(seq 1 120); do + state=$(pg_controldata "$PGDATA" 2>/dev/null | grep "Database cluster state" | sed 's/.*:[[:space:]]*//') + if [[ "$state" == "in production" ]]; then + echo "promotion complete; node is now primary on a new timeline" + break + fi + sleep 1 + done +fi + # create database with specified name if [ "$POSTGRES_DB" != "postgres" ]; then "${psql[@]}" --username postgres <<-EOSQL diff --git a/role_scripts/14/primary/start.sh b/role_scripts/14/primary/start.sh index cf42d90..2202449 100755 --- a/role_scripts/14/primary/start.sh +++ b/role_scripts/14/primary/start.sh @@ -97,6 +97,26 @@ export POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-postgres} psql=(psql -v ON_ERROR_STOP=1) +# If standby.signal is present, postgres started in recovery above (this node was a standby being +# promoted). Promote it NOW to fork a NEW timeline BEFORE any write below. This is essential for the +# remote-replica -> standalone-HA transition: without promoting from recovery the node comes up on +# the SAME timeline as its former source cluster, which on failback forces a full pg_basebackup +# instead of pg_rewind. Promotion ends recovery, increments the timeline, and removes standby.signal. +# A normal primary start (no standby.signal) skips this block, so fresh bootstrap and the live-standby +# fast-failover path (which promotes via the coordinator, not start.sh) are unaffected. +if [[ -f "/var/pv/data/standby.signal" ]]; then + echo "standby.signal present -> promoting to fork a new timeline before writes" + pg_ctl -D "$PGDATA" promote || true + for _ in $(seq 1 120); do + state=$(pg_controldata "$PGDATA" 2>/dev/null | grep "Database cluster state" | sed 's/.*:[[:space:]]*//') + if [[ "$state" == "in production" ]]; then + echo "promotion complete; node is now primary on a new timeline" + break + fi + sleep 1 + done +fi + # create database with specified name if [ "$POSTGRES_DB" != "postgres" ]; then "${psql[@]}" --username postgres <<-EOSQL diff --git a/role_scripts/15/primary/start.sh b/role_scripts/15/primary/start.sh index c628a37..6bc863b 100755 --- a/role_scripts/15/primary/start.sh +++ b/role_scripts/15/primary/start.sh @@ -95,6 +95,26 @@ export POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-postgres} psql=(psql -v ON_ERROR_STOP=1) +# If standby.signal is present, postgres started in recovery above (this node was a standby being +# promoted). Promote it NOW to fork a NEW timeline BEFORE any write below. This is essential for the +# remote-replica -> standalone-HA transition: without promoting from recovery the node comes up on +# the SAME timeline as its former source cluster, which on failback forces a full pg_basebackup +# instead of pg_rewind. Promotion ends recovery, increments the timeline, and removes standby.signal. +# A normal primary start (no standby.signal) skips this block, so fresh bootstrap and the live-standby +# fast-failover path (which promotes via the coordinator, not start.sh) are unaffected. +if [[ -f "/var/pv/data/standby.signal" ]]; then + echo "standby.signal present -> promoting to fork a new timeline before writes" + pg_ctl -D "$PGDATA" promote || true + for _ in $(seq 1 120); do + state=$(pg_controldata "$PGDATA" 2>/dev/null | grep "Database cluster state" | sed 's/.*:[[:space:]]*//') + if [[ "$state" == "in production" ]]; then + echo "promotion complete; node is now primary on a new timeline" + break + fi + sleep 1 + done +fi + # create database with specified name if [ "$POSTGRES_DB" != "postgres" ]; then "${psql[@]}" --username postgres <<-EOSQL diff --git a/role_scripts/16/primary/start.sh b/role_scripts/16/primary/start.sh index 0d1c333..a063073 100755 --- a/role_scripts/16/primary/start.sh +++ b/role_scripts/16/primary/start.sh @@ -94,6 +94,26 @@ export POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-postgres} psql=(psql -v ON_ERROR_STOP=1) +# If standby.signal is present, postgres started in recovery above (this node was a standby being +# promoted). Promote it NOW to fork a NEW timeline BEFORE any write below. This is essential for the +# remote-replica -> standalone-HA transition: without promoting from recovery the node comes up on +# the SAME timeline as its former source cluster, which on failback forces a full pg_basebackup +# instead of pg_rewind. Promotion ends recovery, increments the timeline, and removes standby.signal. +# A normal primary start (no standby.signal) skips this block, so fresh bootstrap and the live-standby +# fast-failover path (which promotes via the coordinator, not start.sh) are unaffected. +if [[ -f "/var/pv/data/standby.signal" ]]; then + echo "standby.signal present -> promoting to fork a new timeline before writes" + pg_ctl -D "$PGDATA" promote || true + for _ in $(seq 1 120); do + state=$(pg_controldata "$PGDATA" 2>/dev/null | grep "Database cluster state" | sed 's/.*:[[:space:]]*//') + if [[ "$state" == "in production" ]]; then + echo "promotion complete; node is now primary on a new timeline" + break + fi + sleep 1 + done +fi + # create database with specified name if [ "$POSTGRES_DB" != "postgres" ]; then "${psql[@]}" --username postgres <<-EOSQL diff --git a/role_scripts/18/primary/start.sh b/role_scripts/18/primary/start.sh index c3ba065..7610a4a 100755 --- a/role_scripts/18/primary/start.sh +++ b/role_scripts/18/primary/start.sh @@ -95,6 +95,26 @@ export POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-postgres} psql=(psql -v ON_ERROR_STOP=1) +# If standby.signal is present, postgres started in recovery above (this node was a standby being +# promoted). Promote it NOW to fork a NEW timeline BEFORE any write below. This is essential for the +# remote-replica -> standalone-HA transition: without promoting from recovery the node comes up on +# the SAME timeline as its former source cluster, which on failback forces a full pg_basebackup +# instead of pg_rewind. Promotion ends recovery, increments the timeline, and removes standby.signal. +# A normal primary start (no standby.signal) skips this block, so fresh bootstrap and the live-standby +# fast-failover path (which promotes via the coordinator, not start.sh) are unaffected. +if [[ -f "/var/pv/data/standby.signal" ]]; then + echo "standby.signal present -> promoting to fork a new timeline before writes" + pg_ctl -D "$PGDATA" promote || true + for _ in $(seq 1 120); do + state=$(pg_controldata "$PGDATA" 2>/dev/null | grep "Database cluster state" | sed 's/.*:[[:space:]]*//') + if [[ "$state" == "in production" ]]; then + echo "promotion complete; node is now primary on a new timeline" + break + fi + sleep 1 + done +fi + # create database with specified name if [ "$POSTGRES_DB" != "postgres" ]; then "${psql[@]}" --username postgres <<-EOSQL From fc10729be70328b87b6db8221c2ba51f4a70ef3b Mon Sep 17 00:00:00 2001 From: Tamal Saha Date: Tue, 4 Aug 2026 19:04:03 +0600 Subject: [PATCH 5/6] remote-replica: seed with pg_basebackup -Xs instead of -X fetch -X fetch collects the WAL only after the data copy finishes, so the source must retain every WAL segment generated during the entire basebackup. For a large database seeded over a WAN that window is hours to days, and a source without a generous wal_keep_size fails the seed at the very end with "requested WAL segment has already been removed". -Xs streams the WAL on a second connection concurrently with the copy, and pg_basebackup backs that stream with a temporary replication slot it creates and drops itself (default since PG 10). The seed therefore needs no WAL retention configuration on the source at all -- important when the source is a customer database we do not manage. Cost: one extra walsender for the duration of the seed. The coordinator's recovery-path basebackup (executePgBasebackup) already uses -Xs; this aligns the init-script seed with it. Signed-off-by: Tamal Saha --- role_scripts/13/standby/remote-replica.sh | 4 ++-- role_scripts/14/standby/remote-replica.sh | 4 ++-- role_scripts/15/standby/remote-replica.sh | 4 ++-- role_scripts/16/standby/remote-replica.sh | 4 ++-- role_scripts/17/standby/remote-replica.sh | 4 ++-- role_scripts/18/standby/remote-replica.sh | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/role_scripts/13/standby/remote-replica.sh b/role_scripts/13/standby/remote-replica.sh index 5ac1c31..d5668a1 100755 --- a/role_scripts/13/standby/remote-replica.sh +++ b/role_scripts/13/standby/remote-replica.sh @@ -73,9 +73,9 @@ if [[ ! -e "$PGDATA/PG_VERSION" ]]; then [[ "${TDE_ENABLED:-false}" == "true" ]] && BASEBACKUP=pg_tde_basebackup echo "pg_tde: seeding standby with '$BASEBACKUP' (TDE_ENABLED=${TDE_ENABLED:-false})" if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - "$BASEBACKUP" -X fetch --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" + "$BASEBACKUP" -Xs --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" else - "$BASEBACKUP" -X fetch --no-password --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" + "$BASEBACKUP" -Xs --no-password --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" fi fi diff --git a/role_scripts/14/standby/remote-replica.sh b/role_scripts/14/standby/remote-replica.sh index 6bc6fee..37a5aec 100755 --- a/role_scripts/14/standby/remote-replica.sh +++ b/role_scripts/14/standby/remote-replica.sh @@ -73,9 +73,9 @@ if [[ ! -e "$PGDATA/PG_VERSION" ]]; then [[ "${TDE_ENABLED:-false}" == "true" ]] && BASEBACKUP=pg_tde_basebackup echo "pg_tde: seeding standby with '$BASEBACKUP' (TDE_ENABLED=${TDE_ENABLED:-false})" if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - "$BASEBACKUP" -X fetch --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" + "$BASEBACKUP" -Xs --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" else - "$BASEBACKUP" -X fetch --no-password --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" + "$BASEBACKUP" -Xs --no-password --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" fi fi diff --git a/role_scripts/15/standby/remote-replica.sh b/role_scripts/15/standby/remote-replica.sh index 6bc6fee..37a5aec 100755 --- a/role_scripts/15/standby/remote-replica.sh +++ b/role_scripts/15/standby/remote-replica.sh @@ -73,9 +73,9 @@ if [[ ! -e "$PGDATA/PG_VERSION" ]]; then [[ "${TDE_ENABLED:-false}" == "true" ]] && BASEBACKUP=pg_tde_basebackup echo "pg_tde: seeding standby with '$BASEBACKUP' (TDE_ENABLED=${TDE_ENABLED:-false})" if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - "$BASEBACKUP" -X fetch --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" + "$BASEBACKUP" -Xs --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" else - "$BASEBACKUP" -X fetch --no-password --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" + "$BASEBACKUP" -Xs --no-password --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" fi fi diff --git a/role_scripts/16/standby/remote-replica.sh b/role_scripts/16/standby/remote-replica.sh index df5ba30..f31063b 100755 --- a/role_scripts/16/standby/remote-replica.sh +++ b/role_scripts/16/standby/remote-replica.sh @@ -73,9 +73,9 @@ if [[ ! -e "$PGDATA/PG_VERSION" ]]; then [[ "${TDE_ENABLED:-false}" == "true" ]] && BASEBACKUP=pg_tde_basebackup echo "pg_tde: seeding standby with '$BASEBACKUP' (TDE_ENABLED=${TDE_ENABLED:-false})" if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - "$BASEBACKUP" -X fetch --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" + "$BASEBACKUP" -Xs --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" else - "$BASEBACKUP" -X fetch --no-password --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" + "$BASEBACKUP" -Xs --no-password --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" fi fi diff --git a/role_scripts/17/standby/remote-replica.sh b/role_scripts/17/standby/remote-replica.sh index fb26d15..7b63371 100755 --- a/role_scripts/17/standby/remote-replica.sh +++ b/role_scripts/17/standby/remote-replica.sh @@ -73,9 +73,9 @@ if [[ ! -e "$PGDATA/PG_VERSION" ]]; then [[ "${TDE_ENABLED:-false}" == "true" ]] && BASEBACKUP=pg_tde_basebackup echo "pg_tde: seeding standby with '$BASEBACKUP' (TDE_ENABLED=${TDE_ENABLED:-false})" if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - "$BASEBACKUP" -X fetch --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" + "$BASEBACKUP" -Xs --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" else - "$BASEBACKUP" -X fetch --no-password --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" + "$BASEBACKUP" -Xs --no-password --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" fi fi diff --git a/role_scripts/18/standby/remote-replica.sh b/role_scripts/18/standby/remote-replica.sh index fb26d15..7b63371 100755 --- a/role_scripts/18/standby/remote-replica.sh +++ b/role_scripts/18/standby/remote-replica.sh @@ -73,9 +73,9 @@ if [[ ! -e "$PGDATA/PG_VERSION" ]]; then [[ "${TDE_ENABLED:-false}" == "true" ]] && BASEBACKUP=pg_tde_basebackup echo "pg_tde: seeding standby with '$BASEBACKUP' (TDE_ENABLED=${TDE_ENABLED:-false})" if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - "$BASEBACKUP" -X fetch --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" + "$BASEBACKUP" -Xs --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" else - "$BASEBACKUP" -X fetch --no-password --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" + "$BASEBACKUP" -Xs --no-password --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" fi fi From ba7ce7ba371697dd6372b1f4905d775873a0eb5e Mon Sep 17 00:00:00 2001 From: Tamal Saha Date: Wed, 5 Aug 2026 10:01:40 +0600 Subject: [PATCH 6/6] remote-replica: honor PRIMARY_PORT for the source connection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All source-facing commands — pg_isready, the liveness psql probe, pg_basebackup, and primary_conninfo — assumed the source listens on 5432. Read PRIMARY_PORT (injected by the operator from the source AppBinding's spec.clientConfig.service.port) and default to 5432 when unset, so existing deployments and older operators are unaffected. Applied to all supported majors (13-18). Signed-off-by: Tamal Saha --- role_scripts/13/standby/remote-replica.sh | 17 +++++++++-------- role_scripts/14/standby/remote-replica.sh | 17 +++++++++-------- role_scripts/15/standby/remote-replica.sh | 17 +++++++++-------- role_scripts/16/standby/remote-replica.sh | 17 +++++++++-------- role_scripts/17/standby/remote-replica.sh | 17 +++++++++-------- role_scripts/18/standby/remote-replica.sh | 17 +++++++++-------- 6 files changed, 54 insertions(+), 48 deletions(-) diff --git a/role_scripts/13/standby/remote-replica.sh b/role_scripts/13/standby/remote-replica.sh index d5668a1..0119920 100755 --- a/role_scripts/13/standby/remote-replica.sh +++ b/role_scripts/13/standby/remote-replica.sh @@ -16,6 +16,7 @@ export PASSWORD set -eou pipefail +export PRIMARY_PORT=${PRIMARY_PORT:-5432} echo "Running as Remote Replica" @@ -27,9 +28,9 @@ while true; do echo "Attempting pg_isready on primary" if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - pg_isready --host="$PRIMARY_HOST" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" --username=$PRIMARY_USER_NAME --timeout=2 &>/dev/null && break + pg_isready --host="$PRIMARY_HOST" --port="$PRIMARY_PORT" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" --username=$PRIMARY_USER_NAME --timeout=2 &>/dev/null && break else - pg_isready --host="$PRIMARY_HOST" --username=$PRIMARY_USER_NAME --timeout=2 &>/dev/null && break + pg_isready --host="$PRIMARY_HOST" --port="$PRIMARY_PORT" --username=$PRIMARY_USER_NAME --timeout=2 &>/dev/null && break fi sleep 2 done @@ -37,9 +38,9 @@ done while true; do echo "Attempting query on primary" if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - psql -h "$PRIMARY_HOST" --username=$PRIMARY_USER_NAME -d "dbname=postgres sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" --command="select now();" &>/dev/null && break + psql -h "$PRIMARY_HOST" -p "$PRIMARY_PORT" --username=$PRIMARY_USER_NAME -d "dbname=postgres sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" --command="select now();" &>/dev/null && break else - psql -h "$PRIMARY_HOST" --username=$PRIMARY_USER_NAME -d postgres --no-password --command="select now();" &>/dev/null && break + psql -h "$PRIMARY_HOST" -p "$PRIMARY_PORT" --username=$PRIMARY_USER_NAME -d postgres --no-password --command="select now();" &>/dev/null && break fi sleep 2 @@ -73,9 +74,9 @@ if [[ ! -e "$PGDATA/PG_VERSION" ]]; then [[ "${TDE_ENABLED:-false}" == "true" ]] && BASEBACKUP=pg_tde_basebackup echo "pg_tde: seeding standby with '$BASEBACKUP' (TDE_ENABLED=${TDE_ENABLED:-false})" if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - "$BASEBACKUP" -Xs --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" + "$BASEBACKUP" -Xs --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" --port="$PRIMARY_PORT" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" else - "$BASEBACKUP" -Xs --no-password --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" + "$BASEBACKUP" -Xs --no-password --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" --port="$PRIMARY_PORT" fi fi @@ -142,9 +143,9 @@ fi echo "recovery_target_timeline = 'latest'" >>/tmp/postgresql.conf # primary_conninfo is used for streaming replication if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - echo "primary_conninfo = 'application_name=$HOSTNAME host=$PRIMARY_HOST user=$PRIMARY_USER_NAME password=$PRIMARY_PASSWORD sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key'" >>/tmp/postgresql.conf + echo "primary_conninfo = 'application_name=$HOSTNAME host=$PRIMARY_HOST port=$PRIMARY_PORT user=$PRIMARY_USER_NAME password=$PRIMARY_PASSWORD sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key'" >>/tmp/postgresql.conf else - echo "primary_conninfo = 'application_name=$HOSTNAME host=$PRIMARY_HOST user=$PRIMARY_USER_NAME password=$PRIMARY_PASSWORD'" >>/tmp/postgresql.conf + echo "primary_conninfo = 'application_name=$HOSTNAME host=$PRIMARY_HOST port=$PRIMARY_PORT user=$PRIMARY_USER_NAME password=$PRIMARY_PASSWORD'" >>/tmp/postgresql.conf fi echo "promote_trigger_file = '/run_scripts/tmp/pg-failover-trigger'" >>/tmp/postgresql.conf # [ name whose presence ends recovery] diff --git a/role_scripts/14/standby/remote-replica.sh b/role_scripts/14/standby/remote-replica.sh index 37a5aec..ce4385c 100755 --- a/role_scripts/14/standby/remote-replica.sh +++ b/role_scripts/14/standby/remote-replica.sh @@ -16,6 +16,7 @@ export PASSWORD set -eou pipefail +export PRIMARY_PORT=${PRIMARY_PORT:-5432} echo "Running as Remote Replica" @@ -27,9 +28,9 @@ while true; do echo "Attempting pg_isready on primary" if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - pg_isready --host="$PRIMARY_HOST" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" --username=$PRIMARY_USER_NAME --timeout=2 &>/dev/null && break + pg_isready --host="$PRIMARY_HOST" --port="$PRIMARY_PORT" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" --username=$PRIMARY_USER_NAME --timeout=2 &>/dev/null && break else - pg_isready --host="$PRIMARY_HOST" --username=$PRIMARY_USER_NAME --timeout=2 &>/dev/null && break + pg_isready --host="$PRIMARY_HOST" --port="$PRIMARY_PORT" --username=$PRIMARY_USER_NAME --timeout=2 &>/dev/null && break fi sleep 2 done @@ -37,9 +38,9 @@ done while true; do echo "Attempting query on primary" if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - psql -h "$PRIMARY_HOST" --username=$PRIMARY_USER_NAME -d "dbname=postgres sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" --command="select now();" &>/dev/null && break + psql -h "$PRIMARY_HOST" -p "$PRIMARY_PORT" --username=$PRIMARY_USER_NAME -d "dbname=postgres sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" --command="select now();" &>/dev/null && break else - psql -h "$PRIMARY_HOST" --username=$PRIMARY_USER_NAME -d postgres --no-password --command="select now();" &>/dev/null && break + psql -h "$PRIMARY_HOST" -p "$PRIMARY_PORT" --username=$PRIMARY_USER_NAME -d postgres --no-password --command="select now();" &>/dev/null && break fi sleep 2 @@ -73,9 +74,9 @@ if [[ ! -e "$PGDATA/PG_VERSION" ]]; then [[ "${TDE_ENABLED:-false}" == "true" ]] && BASEBACKUP=pg_tde_basebackup echo "pg_tde: seeding standby with '$BASEBACKUP' (TDE_ENABLED=${TDE_ENABLED:-false})" if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - "$BASEBACKUP" -Xs --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" + "$BASEBACKUP" -Xs --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" --port="$PRIMARY_PORT" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" else - "$BASEBACKUP" -Xs --no-password --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" + "$BASEBACKUP" -Xs --no-password --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" --port="$PRIMARY_PORT" fi fi @@ -142,9 +143,9 @@ fi echo "recovery_target_timeline = 'latest'" >>/tmp/postgresql.conf # primary_conninfo is used for streaming replication if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - echo "primary_conninfo = 'application_name=$HOSTNAME host=$PRIMARY_HOST user=$PRIMARY_USER_NAME password=$PRIMARY_PASSWORD sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key'" >>/tmp/postgresql.conf + echo "primary_conninfo = 'application_name=$HOSTNAME host=$PRIMARY_HOST port=$PRIMARY_PORT user=$PRIMARY_USER_NAME password=$PRIMARY_PASSWORD sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key'" >>/tmp/postgresql.conf else - echo "primary_conninfo = 'application_name=$HOSTNAME host=$PRIMARY_HOST user=$PRIMARY_USER_NAME password=$PRIMARY_PASSWORD'" >>/tmp/postgresql.conf + echo "primary_conninfo = 'application_name=$HOSTNAME host=$PRIMARY_HOST port=$PRIMARY_PORT user=$PRIMARY_USER_NAME password=$PRIMARY_PASSWORD'" >>/tmp/postgresql.conf fi echo "promote_trigger_file = '/run_scripts/tmp/pg-failover-trigger'" >>/tmp/postgresql.conf # [ name whose presence ends recovery] diff --git a/role_scripts/15/standby/remote-replica.sh b/role_scripts/15/standby/remote-replica.sh index 37a5aec..ce4385c 100755 --- a/role_scripts/15/standby/remote-replica.sh +++ b/role_scripts/15/standby/remote-replica.sh @@ -16,6 +16,7 @@ export PASSWORD set -eou pipefail +export PRIMARY_PORT=${PRIMARY_PORT:-5432} echo "Running as Remote Replica" @@ -27,9 +28,9 @@ while true; do echo "Attempting pg_isready on primary" if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - pg_isready --host="$PRIMARY_HOST" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" --username=$PRIMARY_USER_NAME --timeout=2 &>/dev/null && break + pg_isready --host="$PRIMARY_HOST" --port="$PRIMARY_PORT" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" --username=$PRIMARY_USER_NAME --timeout=2 &>/dev/null && break else - pg_isready --host="$PRIMARY_HOST" --username=$PRIMARY_USER_NAME --timeout=2 &>/dev/null && break + pg_isready --host="$PRIMARY_HOST" --port="$PRIMARY_PORT" --username=$PRIMARY_USER_NAME --timeout=2 &>/dev/null && break fi sleep 2 done @@ -37,9 +38,9 @@ done while true; do echo "Attempting query on primary" if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - psql -h "$PRIMARY_HOST" --username=$PRIMARY_USER_NAME -d "dbname=postgres sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" --command="select now();" &>/dev/null && break + psql -h "$PRIMARY_HOST" -p "$PRIMARY_PORT" --username=$PRIMARY_USER_NAME -d "dbname=postgres sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" --command="select now();" &>/dev/null && break else - psql -h "$PRIMARY_HOST" --username=$PRIMARY_USER_NAME -d postgres --no-password --command="select now();" &>/dev/null && break + psql -h "$PRIMARY_HOST" -p "$PRIMARY_PORT" --username=$PRIMARY_USER_NAME -d postgres --no-password --command="select now();" &>/dev/null && break fi sleep 2 @@ -73,9 +74,9 @@ if [[ ! -e "$PGDATA/PG_VERSION" ]]; then [[ "${TDE_ENABLED:-false}" == "true" ]] && BASEBACKUP=pg_tde_basebackup echo "pg_tde: seeding standby with '$BASEBACKUP' (TDE_ENABLED=${TDE_ENABLED:-false})" if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - "$BASEBACKUP" -Xs --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" + "$BASEBACKUP" -Xs --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" --port="$PRIMARY_PORT" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" else - "$BASEBACKUP" -Xs --no-password --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" + "$BASEBACKUP" -Xs --no-password --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" --port="$PRIMARY_PORT" fi fi @@ -142,9 +143,9 @@ fi echo "recovery_target_timeline = 'latest'" >>/tmp/postgresql.conf # primary_conninfo is used for streaming replication if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - echo "primary_conninfo = 'application_name=$HOSTNAME host=$PRIMARY_HOST user=$PRIMARY_USER_NAME password=$PRIMARY_PASSWORD sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key'" >>/tmp/postgresql.conf + echo "primary_conninfo = 'application_name=$HOSTNAME host=$PRIMARY_HOST port=$PRIMARY_PORT user=$PRIMARY_USER_NAME password=$PRIMARY_PASSWORD sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key'" >>/tmp/postgresql.conf else - echo "primary_conninfo = 'application_name=$HOSTNAME host=$PRIMARY_HOST user=$PRIMARY_USER_NAME password=$PRIMARY_PASSWORD'" >>/tmp/postgresql.conf + echo "primary_conninfo = 'application_name=$HOSTNAME host=$PRIMARY_HOST port=$PRIMARY_PORT user=$PRIMARY_USER_NAME password=$PRIMARY_PASSWORD'" >>/tmp/postgresql.conf fi echo "promote_trigger_file = '/run_scripts/tmp/pg-failover-trigger'" >>/tmp/postgresql.conf # [ name whose presence ends recovery] diff --git a/role_scripts/16/standby/remote-replica.sh b/role_scripts/16/standby/remote-replica.sh index f31063b..2d55270 100755 --- a/role_scripts/16/standby/remote-replica.sh +++ b/role_scripts/16/standby/remote-replica.sh @@ -16,6 +16,7 @@ export PASSWORD set -eou pipefail +export PRIMARY_PORT=${PRIMARY_PORT:-5432} echo "Running as Remote Replica" @@ -27,9 +28,9 @@ while true; do echo "Attempting pg_isready on primary" if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - pg_isready --host="$PRIMARY_HOST" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" --username=$PRIMARY_USER_NAME --timeout=2 &>/dev/null && break + pg_isready --host="$PRIMARY_HOST" --port="$PRIMARY_PORT" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" --username=$PRIMARY_USER_NAME --timeout=2 &>/dev/null && break else - pg_isready --host="$PRIMARY_HOST" --username=$PRIMARY_USER_NAME --timeout=2 &>/dev/null && break + pg_isready --host="$PRIMARY_HOST" --port="$PRIMARY_PORT" --username=$PRIMARY_USER_NAME --timeout=2 &>/dev/null && break fi sleep 2 done @@ -37,9 +38,9 @@ done while true; do echo "Attempting query on primary" if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - psql -h "$PRIMARY_HOST" --username=$PRIMARY_USER_NAME -d "dbname=postgres sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" --command="select now();" &>/dev/null && break + psql -h "$PRIMARY_HOST" -p "$PRIMARY_PORT" --username=$PRIMARY_USER_NAME -d "dbname=postgres sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" --command="select now();" &>/dev/null && break else - psql -h "$PRIMARY_HOST" --username=$PRIMARY_USER_NAME -d postgres --no-password --command="select now();" &>/dev/null && break + psql -h "$PRIMARY_HOST" -p "$PRIMARY_PORT" --username=$PRIMARY_USER_NAME -d postgres --no-password --command="select now();" &>/dev/null && break fi sleep 2 @@ -73,9 +74,9 @@ if [[ ! -e "$PGDATA/PG_VERSION" ]]; then [[ "${TDE_ENABLED:-false}" == "true" ]] && BASEBACKUP=pg_tde_basebackup echo "pg_tde: seeding standby with '$BASEBACKUP' (TDE_ENABLED=${TDE_ENABLED:-false})" if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - "$BASEBACKUP" -Xs --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" + "$BASEBACKUP" -Xs --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" --port="$PRIMARY_PORT" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" else - "$BASEBACKUP" -Xs --no-password --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" + "$BASEBACKUP" -Xs --no-password --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" --port="$PRIMARY_PORT" fi fi @@ -142,9 +143,9 @@ fi echo "recovery_target_timeline = 'latest'" >>/tmp/postgresql.conf # primary_conninfo is used for streaming replication if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - echo "primary_conninfo = 'application_name=$HOSTNAME host=$PRIMARY_HOST user=$PRIMARY_USER_NAME password=$PRIMARY_PASSWORD sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key'" >>/tmp/postgresql.conf + echo "primary_conninfo = 'application_name=$HOSTNAME host=$PRIMARY_HOST port=$PRIMARY_PORT user=$PRIMARY_USER_NAME password=$PRIMARY_PASSWORD sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key'" >>/tmp/postgresql.conf else - echo "primary_conninfo = 'application_name=$HOSTNAME host=$PRIMARY_HOST user=$PRIMARY_USER_NAME password=$PRIMARY_PASSWORD'" >>/tmp/postgresql.conf + echo "primary_conninfo = 'application_name=$HOSTNAME host=$PRIMARY_HOST port=$PRIMARY_PORT user=$PRIMARY_USER_NAME password=$PRIMARY_PASSWORD'" >>/tmp/postgresql.conf fi cat /run_scripts/role/postgresql.conf >>/tmp/postgresql.conf diff --git a/role_scripts/17/standby/remote-replica.sh b/role_scripts/17/standby/remote-replica.sh index 7b63371..8346c26 100755 --- a/role_scripts/17/standby/remote-replica.sh +++ b/role_scripts/17/standby/remote-replica.sh @@ -16,6 +16,7 @@ export PASSWORD set -eou pipefail +export PRIMARY_PORT=${PRIMARY_PORT:-5432} echo "Running as Remote Replica" @@ -27,9 +28,9 @@ while true; do echo "Attempting pg_isready on primary" if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - pg_isready --host="$PRIMARY_HOST" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" --username=$PRIMARY_USER_NAME --timeout=2 &>/dev/null && break + pg_isready --host="$PRIMARY_HOST" --port="$PRIMARY_PORT" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" --username=$PRIMARY_USER_NAME --timeout=2 &>/dev/null && break else - pg_isready --host="$PRIMARY_HOST" --username=$PRIMARY_USER_NAME --timeout=2 &>/dev/null && break + pg_isready --host="$PRIMARY_HOST" --port="$PRIMARY_PORT" --username=$PRIMARY_USER_NAME --timeout=2 &>/dev/null && break fi sleep 2 done @@ -37,9 +38,9 @@ done while true; do echo "Attempting query on primary" if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - psql -h "$PRIMARY_HOST" --username=$PRIMARY_USER_NAME -d "dbname=postgres sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" --command="select now();" &>/dev/null && break + psql -h "$PRIMARY_HOST" -p "$PRIMARY_PORT" --username=$PRIMARY_USER_NAME -d "dbname=postgres sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" --command="select now();" &>/dev/null && break else - psql -h "$PRIMARY_HOST" --username=$PRIMARY_USER_NAME -d postgres --no-password --command="select now();" &>/dev/null && break + psql -h "$PRIMARY_HOST" -p "$PRIMARY_PORT" --username=$PRIMARY_USER_NAME -d postgres --no-password --command="select now();" &>/dev/null && break fi sleep 2 @@ -73,9 +74,9 @@ if [[ ! -e "$PGDATA/PG_VERSION" ]]; then [[ "${TDE_ENABLED:-false}" == "true" ]] && BASEBACKUP=pg_tde_basebackup echo "pg_tde: seeding standby with '$BASEBACKUP' (TDE_ENABLED=${TDE_ENABLED:-false})" if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - "$BASEBACKUP" -Xs --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" + "$BASEBACKUP" -Xs --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" --port="$PRIMARY_PORT" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" else - "$BASEBACKUP" -Xs --no-password --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" + "$BASEBACKUP" -Xs --no-password --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" --port="$PRIMARY_PORT" fi fi @@ -147,9 +148,9 @@ if [[ "$WAL_LIMIT_POLICY" == "ReplicationSlot" ]]; then fi if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - echo "primary_conninfo = 'application_name=$HOSTNAME host=$PRIMARY_HOST user=$PRIMARY_USER_NAME password=$PRIMARY_PASSWORD sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key$CONNINFO_DBNAME'" >>/tmp/postgresql.conf + echo "primary_conninfo = 'application_name=$HOSTNAME host=$PRIMARY_HOST port=$PRIMARY_PORT user=$PRIMARY_USER_NAME password=$PRIMARY_PASSWORD sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key$CONNINFO_DBNAME'" >>/tmp/postgresql.conf else - echo "primary_conninfo = 'application_name=$HOSTNAME host=$PRIMARY_HOST user=$PRIMARY_USER_NAME password=$PRIMARY_PASSWORD$CONNINFO_DBNAME'" >>/tmp/postgresql.conf + echo "primary_conninfo = 'application_name=$HOSTNAME host=$PRIMARY_HOST port=$PRIMARY_PORT user=$PRIMARY_USER_NAME password=$PRIMARY_PASSWORD$CONNINFO_DBNAME'" >>/tmp/postgresql.conf fi cat /run_scripts/role/postgresql.conf >>/tmp/postgresql.conf diff --git a/role_scripts/18/standby/remote-replica.sh b/role_scripts/18/standby/remote-replica.sh index 7b63371..8346c26 100755 --- a/role_scripts/18/standby/remote-replica.sh +++ b/role_scripts/18/standby/remote-replica.sh @@ -16,6 +16,7 @@ export PASSWORD set -eou pipefail +export PRIMARY_PORT=${PRIMARY_PORT:-5432} echo "Running as Remote Replica" @@ -27,9 +28,9 @@ while true; do echo "Attempting pg_isready on primary" if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - pg_isready --host="$PRIMARY_HOST" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" --username=$PRIMARY_USER_NAME --timeout=2 &>/dev/null && break + pg_isready --host="$PRIMARY_HOST" --port="$PRIMARY_PORT" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" --username=$PRIMARY_USER_NAME --timeout=2 &>/dev/null && break else - pg_isready --host="$PRIMARY_HOST" --username=$PRIMARY_USER_NAME --timeout=2 &>/dev/null && break + pg_isready --host="$PRIMARY_HOST" --port="$PRIMARY_PORT" --username=$PRIMARY_USER_NAME --timeout=2 &>/dev/null && break fi sleep 2 done @@ -37,9 +38,9 @@ done while true; do echo "Attempting query on primary" if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - psql -h "$PRIMARY_HOST" --username=$PRIMARY_USER_NAME -d "dbname=postgres sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" --command="select now();" &>/dev/null && break + psql -h "$PRIMARY_HOST" -p "$PRIMARY_PORT" --username=$PRIMARY_USER_NAME -d "dbname=postgres sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" --command="select now();" &>/dev/null && break else - psql -h "$PRIMARY_HOST" --username=$PRIMARY_USER_NAME -d postgres --no-password --command="select now();" &>/dev/null && break + psql -h "$PRIMARY_HOST" -p "$PRIMARY_PORT" --username=$PRIMARY_USER_NAME -d postgres --no-password --command="select now();" &>/dev/null && break fi sleep 2 @@ -73,9 +74,9 @@ if [[ ! -e "$PGDATA/PG_VERSION" ]]; then [[ "${TDE_ENABLED:-false}" == "true" ]] && BASEBACKUP=pg_tde_basebackup echo "pg_tde: seeding standby with '$BASEBACKUP' (TDE_ENABLED=${TDE_ENABLED:-false})" if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - "$BASEBACKUP" -Xs --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" + "$BASEBACKUP" -Xs --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" --port="$PRIMARY_PORT" -d "sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key" else - "$BASEBACKUP" -Xs --no-password --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" + "$BASEBACKUP" -Xs --no-password --pgdata "$PGDATA" --username=$PRIMARY_USER_NAME --progress --host="$PRIMARY_HOST" --port="$PRIMARY_PORT" fi fi @@ -147,9 +148,9 @@ if [[ "$WAL_LIMIT_POLICY" == "ReplicationSlot" ]]; then fi if [[ "${SOURCE_SSL:-0}" == "ON" ]]; then - echo "primary_conninfo = 'application_name=$HOSTNAME host=$PRIMARY_HOST user=$PRIMARY_USER_NAME password=$PRIMARY_PASSWORD sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key$CONNINFO_DBNAME'" >>/tmp/postgresql.conf + echo "primary_conninfo = 'application_name=$HOSTNAME host=$PRIMARY_HOST port=$PRIMARY_PORT user=$PRIMARY_USER_NAME password=$PRIMARY_PASSWORD sslmode=$SOURCE_SSL_MODE sslrootcert=/tls/certs/remote/ca.crt sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key$CONNINFO_DBNAME'" >>/tmp/postgresql.conf else - echo "primary_conninfo = 'application_name=$HOSTNAME host=$PRIMARY_HOST user=$PRIMARY_USER_NAME password=$PRIMARY_PASSWORD$CONNINFO_DBNAME'" >>/tmp/postgresql.conf + echo "primary_conninfo = 'application_name=$HOSTNAME host=$PRIMARY_HOST port=$PRIMARY_PORT user=$PRIMARY_USER_NAME password=$PRIMARY_PASSWORD$CONNINFO_DBNAME'" >>/tmp/postgresql.conf fi cat /run_scripts/role/postgresql.conf >>/tmp/postgresql.conf