Praktický návod

Jak bezpečně nasazovat databázové migrace

Změň schéma tak, aby během nasazení fungovala stará i nová verze aplikace. Destruktivní úklid nech až na další release.

25 minut · Doctrine Migrations

Nejdřív stručně

Migrace je součást nasazení, ne jen SQL soubor

Databázová migrace převádí schéma a někdy i uložená data z jednoho známého stavu do dalšího. V produkci přitom mohou chvíli současně běžet staré i nové instance aplikace.

Bezpečný postup proto oddělí rozšíření schématu, přesun dat a odstranění staré struktury. Každá fáze je nasaditelná samostatně, pozorovatelná a kompatibilní se sousední verzí aplikace.

Připrav si

Co budeš potřebovat

Než migraci spustíš, musíš znát její dopad na zámky, data i aplikaci, která během změny přijímá provoz.

  • Verzované migrace a shodnou verzi Doctrine Migrations v testu i produkci.
  • Produkčně podobný objem dat, na kterém změříš dobu běhu a délku databázových zámků.
  • Ověřenou zálohu a konkrétní postup obnovy s odhadem, jak dlouho obnova potrvá.
  • Monitoring chyb aplikace, databázových zámků, latence a volného místa během nasazení.

Kroky 1 až 3

Rozděl změnu na bezpečné releasy

Použij rytmus expand–migrate–contract. Mezi jednotlivými kroky nech prostor na ověření produkčních dat.

1. Expand: přidej kompatibilní strukturu

  1. Přidej nový sloupec jako nullable nebo s bezpečnou výchozí hodnotou. Starý kód musí po této změně dál fungovat.
  2. Novou tabulku nebo index přidávej odděleně od odstranění starých objektů. U velké tabulky zjisti, zda operace blokuje zápisy.
  3. Nasazuj aplikaci, která umí číst starý stav a zapisuje nový stav, případně dočasně zapisuje do obou struktur.
  4. Vygenerovaný diff vždy ručně projdi. Odstraň nečekané DROP nebo ALTER operace a doplň podmínky, které migrace skutečně potřebuje.
php bin/console doctrine:migrations:diff
Oficiální Doctrine dokumentace ke generování migrací

2. Migrate: přesuň data po dávkách

  1. Backfill velkého objemu dat nespouštěj jako jeden dlouhý UPDATE v deploy migraci. Přesuň data restartovatelným příkazem po malých dávkách.
  2. Postupuj podle stabilního klíče a ukládej průběh. Opakované spuštění musí být idempotentní a nesmí již převedená data poškodit.
  3. Mezi dávkami sleduj latenci, replikaci a zámky. Velikost dávky sniž, pokud přesun omezuje běžný provoz.
  4. Po dokončení porovnej počty a kontrolní dotazy. Teprve potom přepni čtení aplikace na novou strukturu.
php bin/console app:backfill-new-column --batch-size=500
Oficiální PostgreSQL dokumentace ke změnám tabulek

3. Contract: ukliď až po ověření

  1. Odstraň dual write a kód pro starý formát až poté, co všechny instance čtou nový stav a data jsou kompletní.
  2. NOT NULL nebo cizí klíč přidávej s ohledem na velikost tabulky a způsob validace v konkrétní databázi.
  3. Starý sloupec či tabulku odstraň v samostatném pozdějším releasu. Tím zachováš možnost rychle vrátit předchozí aplikaci.
  4. Před spuštěním si přečti SQL pomocí dry-run a měj připravený stop, forward-fix a restore plán. Nespoléhej slepě na down migraci.
php bin/console doctrine:migrations:migrate --dry-run
Oficiální Doctrine dokumentace ke správě migrací

Krok 4

Ověř migraci před produkcí i po ní

Kontrola syntaxe nestačí. Otestuj smíšené verze aplikace, skutečný objem dat a provozní dopad.

  1. Spusť migraci na kopii produkčních dat

    Změř čas, zámky a místo. Současně posílej běžné čtení i zápisy, které během produkčního deploye poběží.

    php bin/console doctrine:migrations:migrate --no-interaction
  2. Ověř kompatibilitu obou verzí aplikace

    Po expand fázi spusť smoke test starého i nového buildu. Oba musí umět pracovat se stejným mezistavem schématu.

  3. Po produkčním běhu zkontroluj stav

    Ověř aplikované verze, kontrolní dotazy nad daty, chybovost, latenci a čekající zámky ještě před pokračováním deploye.

    php bin/console doctrine:migrations:status

Když to zlobí

Nejčastější chyby

ALTER TABLE dlouho blokuje provoz

Zastav další kroky deploye, zjisti čekající zámky a použij databázově vhodnou online strategii. Operaci nejdřív změř na stejně velké tabulce.

Nová aplikace očekává sloupec, který ještě neexistuje

Pořadí je obráceně. Nejprve nasaď kompatibilní expand migraci, potom aplikaci a destruktivní contract fázi až v dalším releasu.

Backfill skončil uprostřed

Pokračuj od uloženého stabilního klíče. Backfill navrhni idempotentně, po dávkách a s kontrolou, že už převedený řádek zůstane beze změny.

Down migrace by při rollbacku ztratila data

Destruktivní down nespouštěj automaticky. Vrať kompatibilní aplikaci, připrav forward-fix, nebo obnov data podle předem ověřeného restore plánu.

Hotovo

Migrace je připravená na bezpečný deploy.

Databázová migrace má malé kompatibilní kroky, měřitelný dopad a konkrétní plán obnovy. Stejný checklist používej před každou změnou produkčního schématu.

Zavolejte mi

Zavolám vám následující pracovní den mezi 9:00 a 17:00.

Můžete mi také zavolat rovnou.

+420 605 181 728

Nechte mi telefonní číslo a pošlete žádost o zpětné zavolání.

Odesláním souhlasíte se zpracováním údajů pro vyřízení žádosti.