From 4c1882b1490aeac51eb7d4cf00ca343f8f788836 Mon Sep 17 00:00:00 2001 From: DmitriiAn Date: Fri, 24 Apr 2026 14:04:49 +0200 Subject: [PATCH 1/3] preflight: add extension compatibility check --- pgcopydb-helpers/AGENTS.md | 2 +- pgcopydb-helpers/README.md | 4 ++-- pgcopydb-helpers/preflight-check.sh | 20 ++++++++++++++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/pgcopydb-helpers/AGENTS.md b/pgcopydb-helpers/AGENTS.md index adc80d5..46b0959 100644 --- a/pgcopydb-helpers/AGENTS.md +++ b/pgcopydb-helpers/AGENTS.md @@ -86,7 +86,7 @@ Validates all migration prerequisites before starting `pgcopydb clone --follow`. **Checks performed:** - **Source:** connectivity, `wal_level = logical`, replication permission (REPLICATION, SUPERUSER, or rds_replication), available replication slots, available WAL senders, leftover pgcopydb slot, FOR ALL TABLES publications, `wal_sender_timeout`, prepared transactions -- **Target:** connectivity, replication permission, leftover pgcopydb schema +- **Target:** connectivity, replication permission, leftover pgcopydb schema, extension compatibility (FAILs if any source extension is absent on target — add missing ones to `[exclude-extension]` in `filters.ini` if the exclusion is intentional) - **Instance:** `~/filters.ini` exists, pgcopydb binary on PATH **When to use:** Before every migration attempt. Run after setting up `~/.env` and `~/filters.ini` but before `~/start-migration-screen.sh`. Fix all FAILs before proceeding. Review WARNs — especially `wal_sender_timeout` (should be `0` for large migrations) and leftover state from previous attempts. diff --git a/pgcopydb-helpers/README.md b/pgcopydb-helpers/README.md index ff51cac..c23dc3f 100644 --- a/pgcopydb-helpers/README.md +++ b/pgcopydb-helpers/README.md @@ -125,7 +125,7 @@ Before starting the migration, compare PostgreSQL parameters between source and ~/compare-pg-params.sh ``` -Run the preflight check to validate that both databases and the migration instance are ready. This checks connectivity, WAL level, replication permissions, available slots/senders, conflicting publications, and local prerequisites: +Run the preflight check to validate that both databases and the migration instance are ready. This checks connectivity, WAL level, replication permissions, available slots/senders, conflicting publications, extension compatibility (source extensions present on target), and local prerequisites: ```bash ~/preflight-check.sh @@ -391,7 +391,7 @@ sqlite3 ~/migration_*/schema/filter.db "SELECT COUNT(*) FROM s_depend;" | Script | Phase | Description | |--------|-------|-------------| | `compare-pg-params.sh` | Prepare | Compare PostgreSQL parameters between source and target | -| `preflight-check.sh` | Prepare | Validate migration prerequisites (connectivity, WAL level, permissions, slots) | +| `preflight-check.sh` | Prepare | Validate migration prerequisites (connectivity, WAL level, permissions, slots, extension compatibility) | | `fix-replica-identity.sh` | Prepare | Set REPLICA IDENTITY FULL on tables without primary keys | | `filters.ini` | Prepare | pgcopydb filter configuration | | `run-migration.sh` | Migrate | Start a pgcopydb clone --follow migration | diff --git a/pgcopydb-helpers/preflight-check.sh b/pgcopydb-helpers/preflight-check.sh index cbb8e5e..4eae17d 100755 --- a/pgcopydb-helpers/preflight-check.sh +++ b/pgcopydb-helpers/preflight-check.sh @@ -247,6 +247,26 @@ if [ -n "$TGT_VER" ]; then else pass "Existing pgcopydb schema" "none" fi + + # 14. Extension compatibility + SRC_EXTS=$(src_query "SELECT extname FROM pg_extension ORDER BY extname;") + TGT_EXTS=$(tgt_query "SELECT extname FROM pg_extension ORDER BY extname;") + MISSING_EXTS="" + SRC_EXT_COUNT=0 + while IFS= read -r ext; do + [ -z "$ext" ] && continue + SRC_EXT_COUNT=$((SRC_EXT_COUNT + 1)) + if ! printf '%s\n' "$TGT_EXTS" | grep -qx "$ext"; then + MISSING_EXTS="${MISSING_EXTS:+$MISSING_EXTS, }$ext" + fi + done <<< "$SRC_EXTS" + if [ -n "$MISSING_EXTS" ]; then + fail "Extensions" "missing on target: $MISSING_EXTS" + elif [ "$SRC_EXT_COUNT" -gt 0 ]; then + pass "Extensions" "all $SRC_EXT_COUNT source extension(s) present on target" + else + pass "Extensions" "no extensions on source" + fi fi # ── MIGRATION INSTANCE ───────────────────────────────────────────── From ddbac58f5ffab3df0def378c238b9ee4598ad91e Mon Sep 17 00:00:00 2001 From: DmitriiAn Date: Fri, 24 Apr 2026 15:02:04 +0200 Subject: [PATCH 2/3] feat preflight-check.sh: add filters.ini check --- pgcopydb-helpers/preflight-check.sh | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/pgcopydb-helpers/preflight-check.sh b/pgcopydb-helpers/preflight-check.sh index 4eae17d..df1be1f 100755 --- a/pgcopydb-helpers/preflight-check.sh +++ b/pgcopydb-helpers/preflight-check.sh @@ -249,23 +249,31 @@ if [ -n "$TGT_VER" ]; then fi # 14. Extension compatibility + FILTER_EXCLUDED_EXTS="" + if [ -f ~/filters.ini ]; then + FILTER_EXCLUDED_EXTS=$(awk '/^\[exclude-extension\]/{found=1; next} /^\[/{found=0} found && /[^[:space:]]/{gsub(/^[[:space:]]+|[[:space:]]+$/, ""); print}' ~/filters.ini) + fi + SRC_EXTS=$(src_query "SELECT extname FROM pg_extension ORDER BY extname;") TGT_EXTS=$(tgt_query "SELECT extname FROM pg_extension ORDER BY extname;") MISSING_EXTS="" - SRC_EXT_COUNT=0 + CHECKED_COUNT=0 while IFS= read -r ext; do [ -z "$ext" ] && continue - SRC_EXT_COUNT=$((SRC_EXT_COUNT + 1)) + if printf '%s\n' "$FILTER_EXCLUDED_EXTS" | grep -qx "$ext"; then + continue + fi + CHECKED_COUNT=$((CHECKED_COUNT + 1)) if ! printf '%s\n' "$TGT_EXTS" | grep -qx "$ext"; then MISSING_EXTS="${MISSING_EXTS:+$MISSING_EXTS, }$ext" fi done <<< "$SRC_EXTS" if [ -n "$MISSING_EXTS" ]; then fail "Extensions" "missing on target: $MISSING_EXTS" - elif [ "$SRC_EXT_COUNT" -gt 0 ]; then - pass "Extensions" "all $SRC_EXT_COUNT source extension(s) present on target" + elif [ "$CHECKED_COUNT" -gt 0 ]; then + pass "Extensions" "all $CHECKED_COUNT extension(s) present on target" else - pass "Extensions" "no extensions on source" + pass "Extensions" "no extensions to check" fi fi From c42d7bbb8b0682a20ac581098361b8227334337c Mon Sep 17 00:00:00 2001 From: DmitriiAn Date: Fri, 8 May 2026 12:27:48 +0200 Subject: [PATCH 3/3] fix preflight-check.sh: check available extensions on target (pg_available_extensions) instead of installed ones --- pgcopydb-helpers/preflight-check.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pgcopydb-helpers/preflight-check.sh b/pgcopydb-helpers/preflight-check.sh index df1be1f..921958e 100755 --- a/pgcopydb-helpers/preflight-check.sh +++ b/pgcopydb-helpers/preflight-check.sh @@ -255,7 +255,7 @@ if [ -n "$TGT_VER" ]; then fi SRC_EXTS=$(src_query "SELECT extname FROM pg_extension ORDER BY extname;") - TGT_EXTS=$(tgt_query "SELECT extname FROM pg_extension ORDER BY extname;") + TGT_AVAIL_EXTS=$(tgt_query "SELECT name FROM pg_available_extensions ORDER BY name;") MISSING_EXTS="" CHECKED_COUNT=0 while IFS= read -r ext; do @@ -264,14 +264,14 @@ if [ -n "$TGT_VER" ]; then continue fi CHECKED_COUNT=$((CHECKED_COUNT + 1)) - if ! printf '%s\n' "$TGT_EXTS" | grep -qx "$ext"; then + if ! printf '%s\n' "$TGT_AVAIL_EXTS" | grep -qx "$ext"; then MISSING_EXTS="${MISSING_EXTS:+$MISSING_EXTS, }$ext" fi done <<< "$SRC_EXTS" if [ -n "$MISSING_EXTS" ]; then - fail "Extensions" "missing on target: $MISSING_EXTS" + fail "Extensions" "not available on target: $MISSING_EXTS" elif [ "$CHECKED_COUNT" -gt 0 ]; then - pass "Extensions" "all $CHECKED_COUNT extension(s) present on target" + pass "Extensions" "all $CHECKED_COUNT source extension(s) available on target" else pass "Extensions" "no extensions to check" fi