Files
ems/scripts/import_ems_db.sh
Dusan Vojacek dd47a22d61
Some checks failed
deploy / deploy (push) Failing after 14s
test / smoke-test (push) Has been cancelled
tune timescale import db
2026-04-05 10:29:30 +02:00

124 lines
4.6 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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 V032V034)
# 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"