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

195 lines
5.9 KiB
Markdown
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.
# 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](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`:
```bash
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):
```bash
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:
```bash
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
```bash
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:
```bash
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):
```bash
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
```bash
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`.
```bash
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):
```bash
cd /opt/ems-deploy
docker compose --env-file .env run --rm flyway migrate
```
---
## 7. Celý stack
```bash
cd /opt/ems-deploy
docker compose --env-file .env up -d
```
Nebo jednorázový deploy z aplikace:
```bash
/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
```bash
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`):
```bash
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**):
```bash
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)
```bash
# 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
```