Files
ems/docs/database-reset-and-restore.md
Dusan Vojacek 2f7d3c2770
Some checks failed
deploy / deploy (push) Failing after 0s
test / smoke-test (push) Has been cancelled
upgrade na pg18
2026-04-05 10:45:39 +02:00

5.9 KiB
Raw Blame History

Reset PostgreSQL / Timescale (Docker) a obnova z dumpu

Přesný postup pro smazání dat databáze (volume) a nový import pg_dump -Fc na serveru typu /opt/ems-deploy. Po resetu zmizí veškerá data v DB EMS.

Související skripty v repu: scripts/import_ems_db.sh, scripts/export_ems_db.sh.

Obecný kontext self-hosted deploye: deployment-self-hosted.md.


0. Před začátkem

  • Máš zálohu .dump (custom format), ideálně z scripts/export_ems_db.sh nebo ekvivalentního pg_dump -Fc.
  • DB_USER / DB_PASSWORD v .env na cíli odpovídají tomu, co očekává init kontejneru db (po smazání volume se DB vytvoří znovu se stejnými údaji z .env).
  • Timescale: image timescale/timescaledb:latest-pg16 se v čase mění. Záloha ze staršího Timescale na novější imagi vyžaduje po restore ALTER EXTENSION timescaledb UPDATE — to už dělá import_ems_db.sh. Při problémech zvaž pin imagi (např. :2.25.2-pg16) stejně jako u zdroje dumpu.
  • pg_restore nikdy s -j (paralelní restore) u Timescale.

1. (Volitelně) Export z vývojového stroje

Z kořene repa, kde běží lokální docker compose a .env s DB_USER / DB_PASSWORD:

cd /cesta/k/ems-cursor
./scripts/export_ems_db.sh ~/ems_zaloha_$(date +%Y%m%d_%H%M%S).dump

Přenos na server (příklad):

scp ~/ems_zaloha_*.dump root@server:/tmp/ems.dump

2. Na serveru: zastavit služby, které píší do DB

Aby při mazání volume a restore nebyl konflikt:

cd /opt/ems-deploy
docker compose --env-file .env stop backend postgrest frontend

(db nech může běžet do kroku 4, nebo všechno zastavit — viz krok 3.)


3. Zastavit stack a smazat datový volume Postgresu

cd /opt/ems-deploy
docker compose --env-file .env down

Jméno volume závisí na názvu Compose projektu (složka nebo COMPOSE_PROJECT_NAME). Zjisti ho:

docker volume ls | grep -E 'db_data|ems'

Typicky u deploye z /opt/ems-deploy uvidíš něco jako ems-deploy_db_data (prefix {project}_db_data k klíči db_data: z compose).

Smaž volume (doplň přesný název z výpisu):

docker volume rm ems-deploy_db_data

Tím zmizí celý obsah dat Postgresu v tom projektu. Ostatní Docker volume (pokud nějaké máš) se nedotknou.


4. Naběhnout jen databázi

cd /opt/ems-deploy
docker compose --env-file .env up -d db
docker compose --env-file .env ps

Počkej, až je služba db healthy (pg_isready v healthchecku).

Init image vytvoří prázdnou databázi ems a uživatele z POSTGRES_USER / POSTGRES_PASSWORD.


5. Import dumpu (Timescale hooks + restore)

Dump musí být na serveru, např. /tmp/ems.dump.

cd /opt/ems-deploy
bash app/scripts/import_ems_db.sh /tmp/ems.dump

Skript v kontejneru db postupně:

  1. CREATE EXTENSION IF NOT EXISTS timescaledb
  2. SELECT timescaledb_pre_restore();
  3. pg_restore bez -j (--clean --if-exists --no-owner --no-acl)
  4. ALTER EXTENSION timescaledb UPDATE; (srovnání katalogu se verzí v imagi)
  5. SELECT timescaledb_post_restore();

Výjimky: EMS_SKIP_TIMESCALE_RESTORE_HOOKS=1 v prostředí přeskočí body 2 a 5 (jen výjimečně).

Časté jevy:

  • pg_restore: warning: errors ignored — často kvůli FK na hypertable (ALTER TABLE ONLY). Po importu vždy Flyway (migrace V034 doplní chybějící FK).
  • Selhání catalog version mismatch — typicky vyřeší ALTER EXTENSION ve skriptu; jinak pin Timescale imagi nebo nový dump po upgrade zdroje.

6. Flyway migrace

Doplní schéma oproti dumpu (včetně oprav PK/chunků/FK z V032V034 podle verze repa):

cd /opt/ems-deploy
docker compose --env-file .env run --rm flyway migrate

7. Celý stack

cd /opt/ems-deploy
docker compose --env-file .env up -d

Nebo jednorázový deploy z aplikace:

/opt/ems-deploy/deploy.sh

(deploy.sh dělá git sync, flyway migrate, build, up -d — pokud už jsi Flyway spustil v kroku 6, znovu obvykle jen doplní repeatable migrace.)


8. Rychlá kontrola

docker compose -f /opt/ems-deploy/docker-compose.yml --env-file /opt/ems-deploy/.env ps

Volitelně SQL (z hosta přes docker compose exec):

docker compose --env-file .env exec -T -e PGPASSWORD="$DB_PASSWORD" db \
  psql -U "$DB_USER" -d ems -c "SELECT count(*) FROM ems.site;"

9. Slabší varianta bez mazání volume

Pokud nechceš mazat celý volume, lze zkusit přepnout databázi uvnitř (méně typické u Timescale; u poškozeného katalogu chunků je spolehlivější smazat volume):

docker compose --env-file .env exec -T -e PGPASSWORD="$DB_PASSWORD" db \
  psql -U "$DB_USER" -d postgres -c "DROP DATABASE IF EXISTS ems WITH (FORCE);"
docker compose --env-file .env exec -T -e PGPASSWORD="$DB_PASSWORD" db \
  psql -U "$DB_USER" -d postgres -c "CREATE DATABASE ems OWNER \"${DB_USER}\";"

Pak znovu import_ems_db.sh a Flyway.


10. Robustnější strategie (odkaz)

Plný „schema odděleně od dat“ a obnova hypertable přes create_hypertable popisuje Tiger Data / Timescale v dokumentaci k backupu a restore. Tento repozitář používá praktický jednokrokový -Fc restore přes import_ems_db.sh; u opakovaných problémů zvaž jejich oficiální postup (pre-data dump bez _timescaledb*, data zvlášť).


11. Shrnutí příkazů (kostra)

# server
cd /opt/ems-deploy
docker compose --env-file .env stop backend postgrest frontend
docker compose --env-file .env down
docker volume rm <JMÉNO_db_data>   # z docker volume ls

docker compose --env-file .env up -d db
# počkat healthy

bash app/scripts/import_ems_db.sh /tmp/ems.dump
docker compose --env-file .env run --rm flyway migrate
docker compose --env-file .env up -d