#!/usr/bin/env bash # Import zálohy EMS (pg_dump -Fc) do Postgresu v Dockeru na serveru. # # Předpoklad: čerstvý volume nebo vědomá obnova přes existující data. # Spouštěj na serveru z /opt/ems-deploy (nebo nastav EMS_DEPLOY_ROOT). # # Postup (nová instance, ještě bez plného stacku): # 1) /opt/ems-deploy/.env vyplněné (DB_USER, DB_PASSWORD stejné jako v cílové DB – po initu db) # 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) 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ě) # # 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 ROOT="${EMS_DEPLOY_ROOT:-/opt/ems-deploy}" COMPOSE_FILE="${COMPOSE_FILE:-$ROOT/docker-compose.yml}" ENV_FILE="${ENV_FILE:-$ROOT/.env}" if [[ $# -lt 1 ]]; then echo "Usage: $0 /cesta/k/ems.dump" >&2 exit 1 fi DUMP="$(readlink -f "$1")" if [[ ! -f "$DUMP" ]]; then echo "ERROR: soubor neexistuje: $DUMP" >&2 exit 1 fi if [[ ! -f "$COMPOSE_FILE" ]]; then echo "ERROR: compose not found: $COMPOSE_FILE" >&2 exit 1 fi if [[ ! -f "$ENV_FILE" ]]; then echo "ERROR: .env not found: $ENV_FILE" >&2 exit 1 fi set -a # shellcheck disable=SC1090 source "$ENV_FILE" set +a : "${DB_USER:?DB_USER missing in $ENV_FILE}" : "${DB_PASSWORD:?DB_PASSWORD missing in $ENV_FILE}" cd "$ROOT" if ! docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" ps --status running -q db | grep -q .; then echo "ERROR: db neběží. Spusť jen databázi, např.:" >&2 echo " docker compose -f \"$COMPOSE_FILE\" --env-file \"$ENV_FILE\" up -d db" >&2 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" 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 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"