diff --git a/scripts/import_ems_db.sh b/scripts/import_ems_db.sh index 6f9e1b4..76dee06 100755 --- a/scripts/import_ems_db.sh +++ b/scripts/import_ems_db.sh @@ -9,17 +9,28 @@ # 2) docker compose -f /opt/ems-deploy/docker-compose.yml --env-file /opt/ems-deploy/.env up -d db # 3) Počkej na healthy: docker compose ... ps # 4) bash app/scripts/import_ems_db.sh /tmp/ems.dump -# 5) Celý stack: /opt/ems-deploy/deploy.sh (nebo docker compose up -d) +# 5) flyway migrate (doplní PK / FK po problematickém restore – V032–V034) +# 6) Celý stack: /opt/ems-deploy/deploy.sh (nebo docker compose up -d) # # Volby prostředí: # EMS_DEPLOY_ROOT=/opt/ems-deploy (výchozí) # COMPOSE_FILE, ENV_FILE – přepíšou cesty k souborům +# EMS_SKIP_TIMESCALE_RESTORE_HOOKS=1 – přeskočí timescaledb_pre_restore / post_restore (jen výjimečně) # -# Poznámky: -# - Záloha musí být z podobného stacku (Postgres 16 + Timescale). Jiná major verze může selhat. -# - Dump by měl obsahovat i Flyway metadata (tabulku historie), jinak při dalším startu Flyway znovu spustí migrace a může spadnout. -# - TimescaleDB: u pg_restore nepoužívejte paralelizaci (-j); může zůstat nekonzistentní katalog chunků -# (chyba „chunk not found“ / selhání ADD PK na hypertable). Viz dokumentace Timescale backup/restore. +# TimescaleDB – doporučení z dokumentace (full restore): +# - Cílová DB má mít rozšíření timescaledb před restore. +# - Před pg_restore: SELECT timescaledb_pre_restore(); +# - Po pg_restore: SELECT timescaledb_post_restore(); +# - Stejná major verze Postgres + Timescale jako u zálohy. +# - Bez paralelního pg_restore (-j) – může rozbít pořadí objektů a chunky. +# +# pg_restore z běžného pg_dump i tak může u hypertable vygenerovat nevhodné DDL (např. ALTER TABLE ONLY +# u FK). Po importu proto spusťte flyway migrate (V034 doplní chybějící FK). +# +# Robustnější varianta (schema + data zvlášť) – viz oficiální návod Timescale / Tiger Data: +# pg_dump -Fc --section=pre-data --exclude-schema='_timescaledb*' … +# na cíli znovu create_hypertable(...) (např. přes Flyway), data COPY / parallel-copy. +# Tento skript řeší klasický jednosouborový -Fc restore, ne oddělené sekce. set -euo pipefail @@ -64,16 +75,49 @@ if ! docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" ps --status runnin exit 1 fi +compose_db() { + docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" exec -T \ + -e "PGPASSWORD=${DB_PASSWORD}" \ + db \ + "$@" +} + CID="$(docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" ps -q db)" echo "Kopíruji dump do kontejneru..." docker cp "$DUMP" "${CID}:/tmp/ems_import.dump" -echo "Obnovuji databázi ems (--clean smaže existující objekty ve schématech ze zálohy)..." -docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" exec -T \ - -e "PGPASSWORD=${DB_PASSWORD}" \ - db \ - pg_restore -U "$DB_USER" -d ems --clean --if-exists --no-owner --no-acl --verbose /tmp/ems_import.dump +if [[ "${EMS_SKIP_TIMESCALE_RESTORE_HOOKS:-0}" != "1" ]]; then + echo "Timescale: CREATE EXTENSION + timescaledb_pre_restore()…" + compose_db psql -U "$DB_USER" -d ems -v ON_ERROR_STOP=1 \ + -c "CREATE EXTENSION IF NOT EXISTS timescaledb;" + compose_db psql -U "$DB_USER" -d ems -v ON_ERROR_STOP=1 \ + -c "SELECT timescaledb_pre_restore();" +else + echo "WARN: EMS_SKIP_TIMESCALE_RESTORE_HOOKS=1 – přeskakuji pre_restore" +fi + +echo "Obnovuji databázi ems (--clean smaže existující objekty ve schématech ze zálohy)…" +set +e +compose_db pg_restore -U "$DB_USER" -d ems --clean --if-exists --no-owner --no-acl --verbose /tmp/ems_import.dump +RESTORE_EXIT=$? +set -e + +if [[ "${EMS_SKIP_TIMESCALE_RESTORE_HOOKS:-0}" != "1" ]]; then + echo "Timescale: timescaledb_post_restore()…" + if ! compose_db psql -U "$DB_USER" -d ems -v ON_ERROR_STOP=1 \ + -c "SELECT timescaledb_post_restore();"; then + echo "ERROR: timescaledb_post_restore() selhal" >&2 + RESTORE_EXIT=1 + fi +else + echo "WARN: EMS_SKIP_TIMESCALE_RESTORE_HOOKS=1 – přeskakuji post_restore" +fi docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" exec -T db rm -f /tmp/ems_import.dump -echo "Import dokončen. Spusť zbytek stacku (deploy.sh nebo docker compose up -d)." +if [[ "$RESTORE_EXIT" -ne 0 ]]; then + echo "WARN: pg_restore skončil s kódem $RESTORE_EXIT (časté u FK na hypertable). Spusť flyway migrate." >&2 +fi + +echo "Import dokončen (exit pg_restore=$RESTORE_EXIT). Doporučeno: flyway migrate, pak deploy.sh / docker compose up -d." +exit "$RESTORE_EXIT"