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.
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
- 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.
- Novou tabulku nebo index přidávej odděleně od odstranění starých objektů. U velké tabulky zjisti, zda operace blokuje zápisy.
- Nasazuj aplikaci, která umí číst starý stav a zapisuje nový stav, případně dočasně zapisuje do obou struktur.
- 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
- 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.
- 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.
- Mezi dávkami sleduj latenci, replikaci a zámky. Velikost dávky sniž, pokud přesun omezuje běžný provoz.
- 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í
- Odstraň dual write a kód pro starý formát až poté, co všechny instance čtou nový stav a data jsou kompletní.
- NOT NULL nebo cizí klíč přidávej s ohledem na velikost tabulky a způsob validace v konkrétní databázi.
- Starý sloupec či tabulku odstraň v samostatném pozdějším releasu. Tím zachováš možnost rychle vrátit předchozí aplikaci.
- 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.
-
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 -
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.
-
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.