roulbekTakéROLLBACK, rollback transakce, rollback nasazeníPokročilý

Definice

Rollback je návrat systému do posledního známého konzistentního stavu poté, co změna selhala nebo způsobila problém. V databázi ruší všechny zápisy rozpracované transakce, v nasazení vrací aplikaci na předchozí verzi. Cílem je odstranit následky neúspěšné operace bez ručního dohledávání toho, co se stihlo změnit.

Kategorie: DatabázeAktualizováno

Nezaměňujte: Rollback označuje jak zrušení databázové transakce, tak návrat nasazené aplikace na předchozí verzi; obojí je běžné a významy se nezaměňují jen podle kontextu.

Než se na to spolehnete: Chování rollbacku u DDL příkazů se liší podle databáze (PostgreSQL je transakční, Oracle a MySQL commitují implicitně); v textu je to formulováno obecně. Anglický článek na Wikipedii uvádím podle názvu, který si pamatuji jako stabilní, ověřte prosím dostupnost.

Dvě různé věci, které se obě jmenují rollback

Slovo rollback se běžně používá ve dvou světech. V databázích jde o příkaz, kterým transakce končí neúspěšně a všechny její zápisy zmizí, jako by se nikdy nestaly. V provozu aplikací jde o vrácení nasazení na předchozí verzi kódu, konfigurace nebo image kontejneru. Společný je jen princip: existuje bod, do kterého se lze vrátit, a mechanismus, který návrat provede.

Co rollback v databázi skutečně dělá

Databázový rollback stojí na tom, že systém si během transakce vede záznam původních hodnot (undo log, rollback segment nebo write-ahead log). Příkaz ROLLBACK tyto hodnoty vrátí zpět a uvolní zámky. Je to praktické naplnění atomicity z ACID: transakce proběhne buď celá, nebo vůbec. Rollback nastane i bez explicitního příkazu, například při pádu spojení, vypršení timeoutu nebo porušení omezení.

Pozor na to, co rollback nevrátí. Sekvence a auto-increment čítače se typicky nevracejí, aby nebrzdily souběžné transakce. Odeslaný e-mail, zápis do souboru mimo databázi nebo volání cizího API rollbackem nezmizí, proto se vedlejší efekty odkládají až za úspěšný commit.

Proč je rollback nasazení těžší než git revert

Vrátit kód je snadné. Problém dělá stav, který nová verze mezitím vytvořila. Pokud migrace přejmenovala sloupec nebo změnila formát dat v Redisu, stará verze na nová data nesedí a rollback aplikace ji přivede k pádu. Proto se v CI/CD prosazuje pravidlo zpětně kompatibilních migrací: nejdřív se schéma rozšíří, pak se nasadí kód, a teprve po ustálení se staré sloupce odstraní. Během tohoto okna je rollback bezpečný.

Druhá past jsou nevratné akce. Verze, která během deseti minut rozeslala notifikace nebo strhla platby, po rollbacku sice zmizí z serverů, ale její následky ve světě zůstanou.

Rollback, nebo raději roll forward?

Řada týmů rollback záměrně nepoužívá jako první volbu a preferuje roll forward: rychlou opravu nasazenou dopředu. Argument zní, že návrat na starou verzi je stejně nasazení jako každé jiné, jen méně testované, protože ho nikdo neprocvičuje. Rollback dává největší smysl tam, kde je automatický a rychlý: blue-green nebo canary strategie umožní přepnout provoz zpět během sekund, protože předchozí verze stále běží.

Jak poznat, že rollback funguje

Rollback, který nikdo nezkoušel, je jen předpoklad. Prakticky se ověřuje tím, že se zařadí do rutiny: každé nasazení má definovaný postup návratu, měří se doba do obnovení služby a alespoň ve stagingu se návrat pravidelně provede naostro. Užitečné je také omezit počet verzí zpět, na které rollback zaručujete: garantovat návrat o jednu verzi je splnitelné, o dvacet nikoli.

Příklady z praxe

  1. Převod peněz, který selže uprostřed

    Transakce odečte částku z jednoho účtu a pak narazí na porušení omezení u druhého zápisu. Aplikace zavolá ROLLBACK a odečtení zmizí, takže peníze nikde nechybí ani nepřebývají. Bez rollbacku by zůstal částečný stav, který by musel někdo dohledávat ručně.

    BEGIN;
    UPDATE ucty SET zustatek = zustatek - 5000 WHERE id = 1;
    UPDATE ucty SET zustatek = zustatek + 5000 WHERE id = 999; -- účet neexistuje
    -- aplikace zachytí chybu
    ROLLBACK;
  2. Rollback nasazení v Kubernetes po skoku chybovosti

    Nová verze API se nasadí přes rolling update a monitoring do dvou minut ukáže nárůst odpovědí 500. Tým vrátí Deployment na předchozí revizi, protože stará image je stále v registru a schéma databáze zůstalo zpětně kompatibilní. Provoz se ustálí dřív, než by stihla vzniknout oprava.

    kubectl rollout undo deployment/api
    kubectl rollout status deployment/api

Časté omyly

MýtusRollback vrátí systém přesně do stavu před nasazením.
Ve skutečnostiRollback vrátí kód a konfiguraci, ale ne data a vnější efekty. Odeslané e-maily, zaúčtované platby, změněné řádky v databázi nebo zprávy ve frontě zůstávají. Návrat je proto úplný jen tehdy, když nová verze nestihla nevratně zasáhnout do stavu.
MýtusKdyž mám verzování v Gitu, mám vyřešený rollback.
Ve skutečnostiGit řeší jen zdrojový kód. Rollback v provozu navíc vyžaduje dostupnou předchozí sestavenou verzi, kompatibilní schéma databáze a postup přepnutí provozu. Bez toho je git revert jen začátek dalšího nasazení.
MýtusROLLBACK v databázi vrátí úplně všechno, co transakce udělala.
Ve skutečnostiROLLBACK vrátí datové změny chráněné transakcí, ale ne hodnoty sekvencí a auto-increment čítačů ani operace mimo databázi. V některých systémech navíc část příkazů DDL potvrzuje transakci implicitně.

Časté dotazy

Jak dlouho by měl rollback nasazení trvat?
Rollback nasazení se hodnotí podle doby do obnovení služby, ne podle počtu kroků. U blue-green nebo canary strategie jde o sekundy, protože předchozí verze stále běží a mění se jen směrování provozu. U klasického rolling update jsou to jednotky minut podle rychlosti stahování image a startu podů. Pokud rollback trvá déle než sestavení a nasazení opravy, ztrácí smysl a tým sáhne raději po roll forward. Praktické pravidlo zní: rollback musí být rychlejší než diagnostika příčiny.
Jak udělat rollback, když nová verze změnila schéma databáze?
Rollback při změně schématu je bezpečný jen tehdy, když byla migrace navržena jako zpětně kompatibilní. Postup má tři fáze: nejdřív se schéma rozšíří o nové sloupce nebo tabulky, aniž by se cokoli odstraňovalo, pak se nasadí kód, který nový tvar používá, a teprve po ověření provozu se stará struktura zruší. Mezi druhou a třetí fází funguje stará i nová verze aplikace současně, takže rollback nevyžaduje žádnou zpětnou migraci dat. Down migrace, které mažou sloupce, jsou v produkci nebezpečné, protože ztrácejí data.
Kdy zvolit roll forward místo rollbacku?
Roll forward dává přednost tam, kde je návrat rizikový nebo nemožný: po nevratné migraci dat, po odeslání zpráv externím systémům nebo když se problém týká jen malé části funkcionality. Roll forward také preferují týmy s velmi rychlou pipeline, kde oprava doletí do produkce za pár minut. Naopak při plošném výpadku, prudkém nárůstu chybovosti nebo bezpečnostním incidentu se volí rollback, protože obnovuje známý funkční stav bez nutnosti pochopit příčinu. Rozhodujícím kritériem je čas do obnovení služby a jistota výsledku.
Co se stane, když aplikace transakci neuzavře a spojení spadne?
Nedokončená transakce se při ztrátě spojení automaticky vrátí zpět. Databázový server pozná, že klient zmizel, a provede rollback, takže rozpracované zápisy zmizí a zámky se uvolní. Podobně to funguje po pádu serveru: při startu se z write-ahead logu dokončí potvrzené transakce a nepotvrzené se zruší. Problém nastává spíš u dlouho otevřených nečinných transakcí, které nikdo neukončil. Blokují zámky, brání úklidu starých verzí řádků a nafukují datové soubory, proto se v provozu nastavují časové limity.
Lze rollback v databázi provést po commitu?
Rollback po commitu možný není. Potvrzením transakce se změny stávají trvalými a viditelnými pro ostatní spojení, takže mechanismus rollbacku už nemá co vracet. Návrat ke staršímu stavu se pak řeší jinými prostředky: obnovou ze zálohy, point-in-time recovery pomocí write-ahead logu nebo kompenzační transakcí, která provede opačnou operaci. Ve složitějších systémech se proto plánuje pattern saga, kde má každý krok definovaný kompenzující protějšek. Prevencí je hlavně to, aby commit nastal až po ověření všech podmínek.

Zdroje

  1. PostgreSQL Documentation: ROLLBACK(otevře se v novém okně)PostgreSQL Global Development Group
  2. PostgreSQL Documentation: Transactions(otevře se v novém okně)PostgreSQL Global Development Group
  3. Kubernetes Documentation: Deployments(otevře se v novém okně)Kubernetes
  4. Git Reference: git-revert(otevře se v novém okně)Git
  5. SQLite: Atomic Commit In SQLite(otevře se v novém okně)SQLite

Související pojmy

Potřebujete to vyřešit v praxi?

Poradíme, jak na to ve vašem projektu

Vysvětlit pojem je jedna věc, navrhnout kolem něj funkční řešení druhá. Ozvěte se a probereme, co dává smysl u vás.