Přeskočit obsah

Migrace identifikátoru prostředí — Runbook pro rollback

Rozsah: Provozní postup rollbacku migrací 000121000125, které v databázi převedou každý identifikátor prostředí na kanonický lowercase tvar (prod, staging, ...).

Cílová skupina: DBA, on-call SRE, release engineering.

1. Proč tento runbook existuje

Migrace 000123 (backfill business dat) a 000124 (backfill gateway / control-plane) provádějí ztrátovou transformaci sloupců s identifikátorem prostředí:

UPDATE table SET environment = LOWER(TRIM(environment))

Po jejich spuštění už nelze obnovit původní velikost písmen (PROD, Stage-2, dev) z dotčeného řádku. Soubory *.down.sql pro tyto migrace jsou záměrně no-opmigrate down neobnoví předchozí stav. Pokud potřebujete vrátit data před migraci, postupujte podle tohoto runbooku.

2. Rozhodovací strom

Symptom Akce
Aplikační chyba „invalid environment slug" Nerollbackujte. Klient posílá ne-kanonický identifikátor; opravte volajícího.
Externí systém očekává staré velké písmo Nerollbackujte. Aktualizujte konzumenta.
Pád na CHECK omezení v 000125 při deployi 000123/000124 neproběhly čistě. Spusťte je znovu, pak 000125. Bez PITR.
Potvrzená korupce dat z 000123/000124 PITR (sekce 4).
Chcete vypnout vynucování kanonického zápisu (D8) Nastavte MAZEVAULT_ENV_CANONICAL_ENFORCE=false. Bez DB zásahu.

3. Reverzibilní části (bez PITR)

  • Indexy z 000121/000122 lze odstranit přes migrate down.
  • CHECK omezení z 000125 lze odstranit přes migrate down (obnoví legacy lookup indexy).
  • Vypnutí vynucování přes env proměnnou:
migrate -path backend/migrations -database "$DATABASE_URL" goto 124
export MAZEVAULT_ENV_CANONICAL_ENFORCE=false
# Restartujte backend a gateway.

Tím se chování pro čtení vrátí do stavu před 000125. Uložená data zůstávají v kanonickém tvaru (lowercase).

4. Plný PITR rollback (000123/000124)

VAROVÁNÍ: Point-in-time recovery je destruktivní a může způsobit ztrátu dat zapsaných po migraci. Před zahájením koordinujte se zákazníkem.

4.1 Pre-flight kontroly

  1. Ověřte, že WAL/zálohy pokrývají časový bod těsně před spuštěním 000123 (sloupec applied_at v schema_migrations).
  2. Zastavte všechny zapisující komponenty:
  3. mazevault-backend repliky
  4. mazevault-gateway repliky (nebo je odpojte od primary)
  5. Plánované úlohy (rotation, sync rules, agent pollery)
  6. Forenzní snapshot:
pg_dump --format=custom --file=mazevault-pre-rollback-$(date -u +%Y%m%d-%H%M%S).dump $DATABASE_URL

4.2 Obnova

Spravovaná cloud DB (Azure Flexible Server, RDS, Cloud SQL)

  • V konzoli poskytovatele: Restore to point in time → zvolte applied_at(000123) - 1 minutu.
  • Vznikne nová instance — přesměrujte aplikaci přes DNS / connection string.

Self-hosted (PITR s WAL archivem)

# 1. Zastavit PostgreSQL.
systemctl stop postgresql

# 2. Současný data dir odsunout.
mv $PGDATA $PGDATA.broken

# 3. Obnovit base backup (poslední před applied_at(000123)).
tar -xzf /var/backups/postgres/base-YYYYMMDD.tar.gz -C $PGDATA

# 4. Konfigurace obnovy (PostgreSQL 12+).
cat >> $PGDATA/postgresql.auto.conf <<EOF
restore_command = 'cp /var/backups/postgres/wal/%f %p'
recovery_target_time = 'YYYY-MM-DD HH:MM:SS+00'
recovery_target_action = 'promote'
EOF
touch $PGDATA/recovery.signal

# 5. Spustit a počkat na promotion.
systemctl start postgresql

4.3 Validace po obnově

SELECT version, dirty FROM schema_migrations ORDER BY version DESC LIMIT 5;
-- Očekává se: nejvyšší záznam < 000123.

SELECT slug FROM environments WHERE slug ~ '[A-Z]' LIMIT 5;
SELECT environment, supported_environments FROM gateways LIMIT 10;

4.4 Restart aplikační vrstvy

  1. Aplikujte následné migrace kromě 000123/000124/000125:

migrate -path backend/migrations -database "$DATABASE_URL" goto 122
2. Backend startujte s MAZEVAULT_ENV_CANONICAL_ENFORCE=false. 3. Spusťte gateway. 4. Obnovte scheduled jobs.

4.5 Komunikace se zákazníkem

  • RTO: 60 min (cloud), 4 h (self-hosted PITR).
  • RPO: ≤ 5 min (cloud) nebo poslední archivovaný WAL (self-hosted).
  • Komunikujte ztrátu dat od applied_at(000123).

5. Forward fix (preferovaný postup)

Pokud lze problém opravit bez PITR (např. malformed slug u jednoho tenanta), opravujte na místě:

SELECT id, slug FROM environments WHERE slug <> LOWER(TRIM(slug));

BEGIN;
UPDATE environments
   SET slug = LOWER(TRIM(slug))
 WHERE organization_id = '...' AND slug <> LOWER(TRIM(slug));
COMMIT;

Forward fix je vždy preferovaný před rollbackem.

6. Související odkazy

7. Change log

Datum Autor Změna
2026-04-26 Platforma První publikace pro migraci na kanonický identifikátor prostředí.