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..921958e 100755 --- a/pgcopydb-helpers/preflight-check.sh +++ b/pgcopydb-helpers/preflight-check.sh @@ -247,6 +247,34 @@ if [ -n "$TGT_VER" ]; then else pass "Existing pgcopydb schema" "none" 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_AVAIL_EXTS=$(tgt_query "SELECT name FROM pg_available_extensions ORDER BY name;") + MISSING_EXTS="" + CHECKED_COUNT=0 + while IFS= read -r ext; do + [ -z "$ext" ] && continue + if printf '%s\n' "$FILTER_EXCLUDED_EXTS" | grep -qx "$ext"; then + continue + fi + CHECKED_COUNT=$((CHECKED_COUNT + 1)) + 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" "not available on target: $MISSING_EXTS" + elif [ "$CHECKED_COUNT" -gt 0 ]; then + pass "Extensions" "all $CHECKED_COUNT source extension(s) available on target" + else + pass "Extensions" "no extensions to check" + fi fi # ── MIGRATION INSTANCE ─────────────────────────────────────────────