diff --git a/pgcopydb-helpers/AGENTS.md b/pgcopydb-helpers/AGENTS.md index adc80d5..17e4a96 100644 --- a/pgcopydb-helpers/AGENTS.md +++ b/pgcopydb-helpers/AGENTS.md @@ -308,26 +308,21 @@ Cleans up pgcopydb replication artifacts on both source and target databases. #### `stop-cdc.sh` -Sets the CDC endpoint LSN so pgcopydb stops streaming after reaching a specific position. This is how you initiate cutover. +Sets the CDC endpoint LSN so pgcopydb stops streaming after reaching a specific position. This is how you initiate cutover. The script fetches the current WAL LSN from the source automatically, displays it, and prompts for confirmation before writing it to the sentinel. ```bash -# Get the current source LSN -psql "$PGCOPYDB_SOURCE_PGURI" -t -A -c "SELECT pg_current_wal_lsn();" - -# Set the endpoint -~/stop-cdc.sh 41EBA/7C7A1AD8 -MIGRATION_DIR=~/migration_YYYYMMDD-HHMMSS ~/stop-cdc.sh 41EBA/7C7A1AD8 # explicit dir +~/stop-cdc.sh +MIGRATION_DIR=~/migration_YYYYMMDD-HHMMSS ~/stop-cdc.sh # explicit dir ``` **Cutover procedure:** 1. Stop writes to the source database (maintenance mode, read-only, etc.) -2. Get the current WAL LSN from the source -3. Run `stop-cdc.sh` with that LSN -4. Wait for `check-cdc-status.sh` to show the apply LSN has reached the endpoint -5. pgcopydb exits cleanly -6. Verify data on the target -7. Switch application to the target -8. Run `drop-replication-slots.sh` to clean up +2. Run `stop-cdc.sh` — it fetches the current WAL LSN, shows it, and asks you to confirm +3. Wait for `check-cdc-status.sh` to show the apply LSN has reached the endpoint +4. pgcopydb exits cleanly +5. Verify data on the target +6. Switch application to the target +7. Run `drop-replication-slots.sh` to clean up **Requires:** `PGCOPYDB_SOURCE_PGURI`, `PGCOPYDB_TARGET_PGURI` @@ -430,7 +425,7 @@ sqlite3 ~/migration_*/schema/filter.db \ 3. CUTOVER (when CDC is caught up) - Stop writes to source - - Run ~/stop-cdc.sh to set the endpoint + - Run ~/stop-cdc.sh — to set the endpoint - Wait for pgcopydb to finish applying and exit - Verify data on target - Switch application to target diff --git a/pgcopydb-helpers/README.md b/pgcopydb-helpers/README.md index ff51cac..8938398 100644 --- a/pgcopydb-helpers/README.md +++ b/pgcopydb-helpers/README.md @@ -176,17 +176,11 @@ When `check-cdc-status.sh` reports **"CDC IS CAUGHT UP"** (apply backlog < 100 M 1. **Stop writes** to the source database (maintenance mode, read-only, connection drain, etc.). -2. **Get the current WAL position** on the source: +2. **Set the CDC endpoint** — the script fetches the current WAL LSN from the source, displays it, and asks for confirmation before applying: ```bash - psql "$PGCOPYDB_SOURCE_PGURI" -t -A -c "SELECT pg_current_wal_lsn();" - ``` - -3. **Set the CDC endpoint** so pgcopydb stops after reaching that position: - - ```bash - ~/stop-cdc.sh - MIGRATION_DIR=~/migration_YYYYMMDD-HHMMSS ~/stop-cdc.sh # explicit dir + ~/stop-cdc.sh + MIGRATION_DIR=~/migration_YYYYMMDD-HHMMSS ~/stop-cdc.sh # explicit dir ``` 4. **Wait** for pgcopydb to apply all remaining changes and exit. Monitor with `check-cdc-status.sh`. diff --git a/pgcopydb-helpers/stop-cdc.sh b/pgcopydb-helpers/stop-cdc.sh index f827760..9373d0c 100644 --- a/pgcopydb-helpers/stop-cdc.sh +++ b/pgcopydb-helpers/stop-cdc.sh @@ -1,11 +1,11 @@ #!/bin/bash -# Usage: ~/stop-cdc.sh -# Example: ~/stop-cdc.sh 41EBA/7C7A1AD8 -# Example: MIGRATION_DIR=~/migration_YYYYMMDD-HHMMSS ~/stop-cdc.sh 41EBA/7C7A1AD8 +# Usage: ~/stop-cdc.sh +# Example: MIGRATION_DIR=~/migration_YYYYMMDD-HHMMSS ~/stop-cdc.sh # -# Sets the CDC endpos sentinel so pgcopydb stops streaming -# after reaching the given LSN. Uses MIGRATION_DIR env var if set, +# Fetches the current WAL LSN from the source, asks for confirmation, +# then sets the CDC endpos sentinel so pgcopydb stops streaming after +# reaching that LSN. Uses MIGRATION_DIR env var if set, # otherwise the most recent ~/migration_*/ directory. # Use the sqlite3 method (more reliable than the pgcopydb CLI sentinel command). @@ -23,23 +23,29 @@ if [ -z "${PGCOPYDB_SOURCE_PGURI:-}" ] || [ -z "${PGCOPYDB_TARGET_PGURI:-}" ]; t fi # --- loaded --- -if [ -z "${1:-}" ]; then - echo "Usage: $0 " - echo "Example: $0 41EBA/7C7A1AD8" - echo "" - echo "Get current source LSN with:" - echo " psql \"\$PGCOPYDB_SOURCE_PGURI\" -t -A -c \"SELECT pg_current_wal_lsn();\"" +echo "Fetching current WAL LSN from source..." +ENDPOS_LSN=$(psql "$PGCOPYDB_SOURCE_PGURI" -t -A -c "SELECT pg_current_wal_lsn();" 2>&1) +if [ $? -ne 0 ] || [ -z "$ENDPOS_LSN" ]; then + echo "ERROR: Failed to fetch LSN from source database:" + echo " $ENDPOS_LSN" exit 1 fi -ENDPOS_LSN="$1" +echo "" +echo "Current source LSN: $ENDPOS_LSN" +echo "" +read -r -p "Stop CDC at this LSN? [y/N] " CONFIRM +if [[ ! "$CONFIRM" =~ ^[Yy]$ ]]; then + echo "Aborted." + exit 0 +fi # Find the most recent migration directory MIGRATION_DIR="${MIGRATION_DIR:-$(ls -dt ~/migration_*/ 2>/dev/null | head -1 || true)}" if [ -z "$MIGRATION_DIR" ] || [ ! -d "$MIGRATION_DIR" ]; then - echo "ERROR: No migration directory found. Pass the path as second argument:" - echo " $0 ~/migration_YYYYMMDD-HHMMSS" + echo "ERROR: No migration directory found. Set MIGRATION_DIR explicitly:" + echo " MIGRATION_DIR=~/migration_YYYYMMDD-HHMMSS $0" exit 1 fi