Jak se nestřílet do nohy pomocí Liquibase

Nikdy se to nestalo a je to tady znovu!

Na dalším projektu jsme se rozhodli použít Liquibase od samého začátku, abychom předešli problémům v budoucnu. Jak se ukázalo, ne všichni mladí členové týmu vědí, jak jej správně používat. Udělal jsem si interní workshop, ze kterého jsem se pak rozhodl udělat článek.

Tento článek obsahuje užitečné tipy a popisy tří nejzjevnějších úskalí, do kterých se můžete dostat při práci s nástroji pro migraci relačních databází, zejména s Liquibase. Určeno pro Java vývojáře úrovně Junior a Middle, pro zkušenější vývojáře může být zajímavé pro strukturování a opakování toho, co je pravděpodobně již známé.

Jak se nestřílet do nohy pomocí Liquibase

Liquibase a Flyway jsou hlavními konkurenčními technologiemi pro řešení problémů správy verzí relačních struktur ve světě Java. První je zcela zdarma, v praxi je častěji volena pro použití, proto byla jako hrdina publikace vybrána Liquibase. Některé popsané postupy však mohou být obecné v závislosti na architektuře vaší aplikace.

Relační migrace jsou nuceným způsobem, jak se vypořádat se slabou flexibilitou relačních datových úložišť. V éře módy pro OOP styl práce s databází znamenal, že schéma popíšeme jednou a už se ho nedotkneme. Ale realita je vždy taková, že věci se mění a změny ve struktuře tabulek jsou vyžadovány poměrně často. Samotný proces je přirozeně bolestivý a nepříjemný.

Nebudu se pouštět do popisu technologie a pokynů pro přidání knihovny do vašeho projektu, článků na toto téma bylo napsáno dost:

Navíc už tu byl skvělý článek na téma užitečných tipů:

Советы

Chci se podělit o své rady a připomínky, které se zrodily potem, krví a bolestí při řešení problémů s migrací.

1. Než začnete, měli byste si přečíst sekci o doporučených postupech webové stránky Liquibase

Tam jsou popsány jednoduché, ale velmi důležité věci, bez kterých vám používání knihovny může zkomplikovat život. Například nestrukturální přístup ke správě sad změn dříve nebo později povede ke zmatkům a nefunkčním migracím. Pokud zároveň nezavedete vzájemně závislé změny ve struktuře databáze a logice služeb, pak je velká pravděpodobnost, že to povede k červeným testům nebo rozbitému prostředí. Kromě toho doporučení pro používání Liquibase na oficiálních stránkách obsahují odstavec o vývoji a ověřování rollback skriptů spolu s hlavními migračními skripty. No, v článku https://habr.com/ru/post/178665/ existují příklady kódu souvisejícího s migrací a mechanismem vrácení zpět.

2. Pokud jste začali používat nástroje pro migraci, nepovolujte ruční opravy ve struktuře databáze

Jak se říká: "Jednou Persil, navždy Persil." Pokud základ vaší aplikace začaly spravovat nástroje Liquibase, jakékoli ruční změny okamžitě vedou k nekonzistentnímu stavu a úroveň důvěry v sady změn se stane nulovou. Potenciální rizika – několik hodin strávených obnovou databáze, v nejhorším případě mrtvý server. Pokud má váš tým „starou školu“ DBA Architect, trpělivě a promyšleně mu vysvětlete, jak špatné věci budou, když si jen upraví databázi po svém z podmíněného SQL Developeru.

3. Pokud byla sada změn již odeslána do úložiště, vyhněte se úpravám

Pokud jiný vývojář vytáhl a použil changeset, který bude později upravován, určitě si na vás vzpomene laskavým slovem, když při spuštění aplikace obdrží chybu. Pokud editace changesetu nějak unikne do vývoje, budete muset jít dolů po kluzkém svahu hotfixů. Podstata problému spočívá ve validaci změn pomocí hash sum - hlavního mechanismu Liquibase. Při úpravě kódu changesetu se změní hašovací součet. Editace changesetů je možná pouze tehdy, když je možné nasadit celou databázi od začátku bez ztráty dat. V tomto případě může refaktoring SQL nebo XML kódu naopak usnadnit život, učinit migrace čitelnějšími. Příkladem může být situace, kdy při startu aplikace bylo v rámci týmu koordinováno schéma zdrojové databáze.

4. Pokud je to možné, nechte si ověřit zálohy databáze

Tady je, myslím, vše jasné. Pokud byla migrace náhle neúspěšná, lze vše vrátit zpět. Liquibase má rollback nástroj, ale rollback skripty píše i sám vývojář a ty mohou mít problémy se stejnou pravděpodobností jako ve skriptech hlavních changesetů. To znamená, že hrát na jistotu se zálohami je v každém případě užitečné.

5. Pokud je to možné, používejte ve vývoji ověřené zálohy databáze

Pokud to není v rozporu se smlouvami a soukromím, v databázi nejsou žádné osobní údaje a neváží to jako dvě slunce - před použitím na serverech živé migrace si můžete zkontrolovat, jak to funguje na vývojářském stroji a vypočítat téměř 100% potenciálních problémů během migrace.

6. Chatujte s ostatními vývojáři v týmu

V dobře organizovaném procesu vývoje každý v týmu ví, kdo co dělá. Ve skutečnosti tomu tak často není, proto pokud v rámci svého úkolu připravujete změny ve struktuře databáze, je vhodné na to dodatečně upozornit celý tým. Pokud někdo provádí změny souběžně, měli byste se pečlivě zorganizovat. S kolegy se vyplatí komunikovat i na konci práce, nejen na jejím začátku. Mnoho potenciálních problémů se sadami změn lze vyřešit ve fázi revize kódu.

7. Mysli na to, co děláš!

Zdánlivě samozřejmé rady použitelné v každé situaci. Mnoha problémům by se však dalo předejít, kdyby vývojář ještě jednou analyzoval, co dělá a co by to mohlo ovlivnit. Práce s migracemi vždy vyžaduje zvláštní pozornost a přesnost.

Pasti

Pojďme se nyní podívat na typické pasti, do kterých se můžete dostat, pokud se nebudete řídit výše uvedenými radami, a co byste vlastně měli dělat?

Situace 1. Dva vývojáři se pokoušejí přidat nové sady změn současně

Jak se nestřílet do nohy pomocí Liquibase
Vasya a Petya chtějí vytvořit sadu změn verze 4, aniž by o sobě věděli. Provedli změny ve struktuře databáze a zavedli požadavek na stažení s různými soubory changesetů. Níže je navržen následující mechanismus:

Jak vyřešit

  1. Kolegové se nějak musí dohodnout na pořadí, v jakém by jejich changesety měly jít, řekněme, že by se měl nejdříve aplikovat Petin.
  2. Jedna osoba by měla nalít druhou a označit Vasyin changeset s verzí 5. To lze provést pomocí Cherry Pick nebo úhledným sloučením.
  3. Po změnách nezapomeňte zkontrolovat platnost provedených akcí.
    Mechanismy Liquibase vám ve skutečnosti umožní mít v úložišti dvě sady změn verze 4, takže můžete nechat vše tak, jak je. To znamená, že budete mít jednoduše dvě revize verze 4 s různými názvy. S tímto přístupem je později velmi obtížné se orientovat ve verzích databáze.

Navíc Liquibase, stejně jako domovy hobitů, uchovává spoustu tajemství. Jedním z nich je klíč validCheckSum, který se objevuje od verze 1.7 a umožňuje zadat platnou hodnotu hash pro konkrétní changeset bez ohledu na to, co je v databázi uloženo. Dokumentace https://www.liquibase.org/documentation/changeset.html říká následující:

Přidejte kontrolní součet, který je považován za platný pro tuto sadu změn, bez ohledu na to, co je uloženo v databázi. Používá se především, když potřebujete změnit changeSet a nechcete, aby se na databázích, na kterých již běžel, vyhazovaly chyby (není doporučený postup)

Ano, toto se nedoporučuje. Někdy ale silný světelný mág ovládá i temné techniky.

Případ 2: Migrace řízená daty

Jak se nestřílet do nohy pomocí Liquibase

Řekněme, že nemůžete použít zálohy databáze z živých serverů. Péťa vytvořil changeset, otestoval jej lokálně a s plnou jistotou, že má pravdu, podal vývojáři požadavek na stažení. Pro jistotu vedoucí projektu upřesnil, zda to Péťa zkontroloval, a pak to nasypal. Ale nasazení na vývojovém serveru kleslo.

Ve skutečnosti je to možné a nikdo proti tomu není imunní. K tomu dochází, pokud jsou úpravy struktury tabulky nějak vázány na konkrétní data z databáze. Je zřejmé, že pokud je databáze Petya naplněna pouze testovacími daty, nemusí pokrývat všechny problémové případy. Například při mazání tabulky se ukáže, že existují záznamy v jiných tabulkách podle cizího klíče spojené se záznamy v té, která se odstraňuje. Nebo se při změně typu sloupce ukáže, že nelze převést na nový typ 100 % dat.

Jak vyřešit

  • Napište speciální skripty, které budou aplikovány jednou spolu s migrací a převedou data do správné podoby. Toto je obecný způsob, jak vyřešit problém přenosu dat do nových struktur po aplikaci migrací, ale něco podobného lze ve zvláštních případech použít dříve. Tato cesta samozřejmě není vždy dostupná, protože úpravy dat na živých serverech mohou být nebezpečné a dokonce fatální.
  • Dalším ošemetným způsobem je upravit existující changeset. Potíž je v tom, že všechny databáze, kde již byl aplikován ve své stávající podobě, budou muset být obnoveny. Je docela možné, že celý backendový tým bude nucen lokálně srolovat databázi od nuly.
  • A nejuniverzálnější způsob je přenést problém s daty do vývojářského prostředí, znovu vytvořit stejnou situaci a přidat nový changeset, k nefunkčnímu, který problém obejde.
    Jak se nestřílet do nohy pomocí Liquibase

Obecně platí, že čím více je databáze svým složením podobná databázi produkčního serveru, tím menší je pravděpodobnost, že problémy s migrací zajdou daleko. A samozřejmě, než odešlete changeset do úložiště, měli byste se několikrát zamyslet, jestli to něco nepokazí.

Situace 3. Liquibase se začne používat po uvedení do výroby

Předpokládejme, že vedoucí týmu požádal Petyu, aby do projektu zahrnula Liquibase, ale projekt je již ve výrobě a existuje již existující struktura databáze.

Problém je tedy v tom, že na všech nových serverech nebo vývojářských počítačích musí být data tabulky znovu vytvořena od nuly a již existující prostředí musí zůstat v konzistentním stavu a musí být připraveno přijímat nové sady změn.

Jak vyřešit

Existuje také několik způsobů:

  • První a nejzřejmější je mít samostatný skript, který je nutné použít ručně při inicializaci nového prostředí.
  • Druhým, méně zřejmým, je mít migraci Liquibase, která je v jiném kontextu Liquibase, a použít ji. Více o Liquibase Context si můžete přečíst zde: https://www.liquibase.org/documentation/contexts.html. Obecně se jedná o zajímavý mechanismus, který lze s úspěchem aplikovat například pro testování.
  • Třetí cesta se skládá z několika kroků. Nejprve je třeba vytvořit migraci pro existující tabulky. Pak se musí aplikovat na nějaké prostředí a tím se získá jeho hash součet. Dalším krokem je inicializace prázdných tabulek Liquibase na našem neprázdném serveru a záznam o „jakoby aplikovaném“ changesetu se změnami již v databázi můžete ručně vložit do tabulky s historií použití changesetů. Na již existujícím serveru tedy historie začne od verze 2 a všechna nová prostředí se budou chovat identicky.
    Jak se nestřílet do nohy pomocí Liquibase

Scénář 4: Migrace je obrovská a nemůže držet krok

Na začátku vývoje služby se zpravidla používá Liquibase jako externí závislost a všechny migrace jsou zpracovávány při spuštění aplikace. Postupem času však můžete narazit na následující případy:

  • Migrace jsou obrovské a jejich dokončení trvá dlouho.
  • Je potřeba migrovat v distribuovaných prostředích, například na několika instancích databázových serverů současně.
    V tomto případě aplikace migrace příliš dlouho povede k vypršení časového limitu při spuštění aplikace. Použití migrací na základě instance aplikace může také vést k tomu, že různé servery budou ve stavu mimo synchronizaci.

Jak vyřešit

V takových případech je váš projekt již velký, možná i dospělý, a Liquibase začíná fungovat jako samostatný externí nástroj. Faktem je, že Liquibase je jako knihovna sestavena do souboru jar a může fungovat jako závislost v rámci projektu i jako samostatná.

Offline můžete ponechat aplikaci migrací do prostředí CI/CD nebo na silná ramena vašich systémových administrátorů/nasazovatelů. K tomu potřebujete příkazový řádek Liquibase https://www.liquibase.org/documentation/command_line.html. V tomto režimu je možné spustit aplikaci po dokončení všech nezbytných migrací.

Výkon

Ve skutečnosti je při práci s migrací databází mnohem více úskalí a mnoho z nich vyžaduje kreativní přístup. Je důležité pochopit, že pokud používáte nástroj správně, lze se většině těchto pastí vyhnout. Konkrétně jsem musel čelit všem uvedeným problémům v různých podobách a některé z nich byly výsledkem mých jambů. V zásadě se to děje, samozřejmě, kvůli nepozornosti, ale někdy - kvůli trestné neschopnosti používat nástroj.

Zdroj: www.habr.com

Přidat komentář