upgrade na pg18
This commit is contained in:
@@ -176,6 +176,7 @@ Specifikace z `docs/02-architecture.md`, modulových docs a komentářů v `plan
|
||||
| Audit 15min | `db/routines/R__fn_fill_audit_interval.sql`, `docs/04-modules/telemetry.md` |
|
||||
| Nové sloupce / tabulky | nový `db/migration/V00x__*.sql` + případně `db/routines` / `db/views` |
|
||||
| Self-hosted deploy (Gitea, Caddy, `/opt/ems-deploy`) | `docs/deployment-self-hosted.md`, `deploy/deploy.sh` |
|
||||
| Reset DB / restore z dumpu (Docker volume, Timescale) | `docs/database-reset-and-restore.md`, `scripts/import_ems_db.sh` |
|
||||
| Nespecifikované chování | `docs/06-open-questions.md` (přidat otázku, neimpl. naslepo) |
|
||||
|
||||
---
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
services:
|
||||
|
||||
db:
|
||||
image: timescale/timescaledb:latest-pg16
|
||||
image: timescale/timescaledb:2.26.1-pg18
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_DB: ems
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
services:
|
||||
|
||||
db:
|
||||
image: timescale/timescaledb:latest-pg16
|
||||
#image: timescale/timescaledb:2.26.1-pg18
|
||||
image: timescale/timescaledb:2.26.1-pg16
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_DB: ems
|
||||
|
||||
194
docs/database-reset-and-restore.md
Normal file
194
docs/database-reset-and-restore.md
Normal file
@@ -0,0 +1,194 @@
|
||||
# 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 V032–V034 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
|
||||
```
|
||||
@@ -153,8 +153,15 @@ curl -sf http://127.0.0.1:8080/ >/dev/null && echo frontend OK
|
||||
|
||||
---
|
||||
|
||||
## 10. Odkazy v repu
|
||||
## 10. Reset DB a obnova z dumpu
|
||||
|
||||
Kompletní postup (zastavení služeb, `down`, smazání volume `db_data`, jen `db`, `import_ems_db.sh`, Flyway, `up`): **[database-reset-and-restore.md](database-reset-and-restore.md)**.
|
||||
|
||||
---
|
||||
|
||||
## 11. Odkazy v repu
|
||||
|
||||
- `deploy/deploy.sh` — jediný produkční vstup „co se na serveru spouští“.
|
||||
- `deploy/docker-compose.yml` — šablona runtime Compose (kopíruje se do `/opt/ems-deploy`).
|
||||
- `.gitea/workflows/deploy.yml` — napojení na runner + job kontejner.
|
||||
- `docs/database-reset-and-restore.md` — zahození dat Postgres/Timescale a import zálohy.
|
||||
|
||||
@@ -20,8 +20,11 @@
|
||||
# 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.
|
||||
# - Po pg_restore: ALTER EXTENSION timescaledb UPDATE; (srovná katalog zálohy s verzí v imagi –
|
||||
# jinak post_restore hlásí „catalog version mismatch expected … seen …“)
|
||||
# - Pak: SELECT timescaledb_post_restore();
|
||||
# - Ideálně stejná major verze Postgres + Timescale jako u zálohy; jinak pin imagí
|
||||
# (např. timescale/timescaledb:2.25.2-pg16 místo latest-pg16).
|
||||
# - 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
|
||||
@@ -103,10 +106,18 @@ 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
|
||||
echo "Timescale: ALTER EXTENSION timescaledb UPDATE (katalog ze zálohy → verze v imagi)…"
|
||||
if compose_db psql -U "$DB_USER" -d ems -v ON_ERROR_STOP=1 \
|
||||
-c "ALTER EXTENSION timescaledb UPDATE;"; 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 (zkontroluj verze PG/Timescale vs. záloha)." >&2
|
||||
RESTORE_EXIT=1
|
||||
fi
|
||||
else
|
||||
echo "ERROR: ALTER EXTENSION timescaledb UPDATE selhalo – nespouštím post_restore." >&2
|
||||
echo " Zkus v compose stejný Timescale tag jako u zdroje dumpu (např. :2.25.2-pg16), nebo nový dump po upgrade zdroje." >&2
|
||||
RESTORE_EXIT=1
|
||||
fi
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user