Jak si neublížit pomocí Liquibase

Nikdy nebylo, a je to zase tady!

Na dalším projektu jsme se rozhodli použít Liquibase od samého začátku, abychom se vyhnuli problémům v budoucnu. Jak se ukázalo, ne všichni mladí členové týmu umí správně používat.

Tento článek obsahuje užitečné rady a popis tří nejvýraznějších pastí, do kterých se můžete dostat při práci s nástroji pro migraci relačních databází, konkrétně Liquibase. Je určen pro Java vývojáře na úrovni Junior a Middle, pro zkušenější vývojáře může být zajímavý pro strukturalizaci a zopakování toho, co pravděpodobně již znají.

Jak si neublížit pomocí Liquibase

Liquibase a Flyway – hlavní konkurenční technologie pro řešení úloh správy verzí relačních struktur ve světě Java. První z nich je zcela zdarma a ve skutečnosti se častěji vybírá právě ona, proto byla Liquibase zvolena za hlavního hrdinu této publikace. Nicméně některé z popsaných praktik mohou být univerzální, v závislosti na architektuře vaší aplikace.

Migrace relačních struktur je nutná metoda boje se slabou flexibilitou relačních datových úložišť. V době módy na OOP bylo pojetí práce s databází, že jednou popíšeme schéma a více se ho nedotkneme. Ale realita je taková, že vše se mění a změny ve struktuře tabulek jsou potřeba dost často. Samozřejmě, že proces sám o sobě může být bolestivý a nepříjemný.

Nebudu se hlouběji zabývat popisem technologie a návody na přidání knihovny do vašeho projektu, na toto téma bylo napsáno již dost článků:

Kromě toho už byla skvělá zpráva na téma užitečných rad:

Tipy

Chci se podělit o své tipy a komentáře, které se zrodily skrze pot, krev a bolest při řešení problémů s migrací.

1. Před prací je dobré se seznámit s částí nejlepších praktik na webu Liquibase

Tam Jsou zde popsány jednoduché, ale velmi důležité věci, bez kterých může být používání knihovny komplikované. Například nekoherentní přístup k řízení change-setů dříve či později povede k zmatku a porušeným migracím. Pokud dojde k nasazení závislých změn databázové struktury a logiky služeb ne současně, hrozí vysoké riziko, že to povede k chybám v testech nebo porušenému prostředí. Kromě toho doporučení k použití Liquibase na oficiálním webu obsahují bod o vytváření a ověřování rollback skriptů spolu se základními migračními skripty. A také v článku https://habr.com/ru/post/178665/ najdete příklady kódu vztahující se k migracím a mechanismu rollback.

2. Když začnete používat migrační nástroje, nedovolte manuální opravy v databázové struktuře.

Jak se říká: „Jednou Persil, navždy Persil“. Pokud je databáze vaší aplikace řízena prostředky Liquibase — jakékoli ruční změny okamžitě vedou k nekonzistentnímu stavu, a úroveň důvěry v change-sety klesá na nulu. Potenciální rizika zahrnují několik hodin strávených obnovou databáze, v nejhorším případě může být server zničen. Pokud ve vašem týmu je DBA architekt „staré školy“, trpělivě a zamyšleně mu vysvětlete, jak špatně to bude vypadat, pokud jednoduše upraví databázi podle svého uvážení v hypotetickém SQL Developer.

3. Pokud byl change-set již nahrán do repozitáře, vyhněte se jeho úpravám.

Pokud jiný vývojář provedl pull a použil change-set, který bude následně upraven, určitě na vás nezapomene dobře, když obdrží chybu při spuštění aplikace. Pokud se úpravy change-setu nějakým způsobem dostanou do dev, budete muset jít křivolakou cestou hotfixů. Podstata problému spočívá v ověření změn podle hash hodnoty — hlavní mechanismus Liquibase. Při úpravách kódu change-setu se změní hash hodnota. Úpravy change-setů jsou možné pouze tehdy, když existuje možnost bez ztráty dat obnovit celou databázi od nuly. V takovém případě může refaktoring SQL nebo XML kódu naopak usnadnit život a učinit migrace čitelnějšími. Příkladem může být situace, kdy byla na začátku aplikace schválená schéma původní databáze uvnitř týmu.

4. Měj ověřené zálohy databází, pokud je to možné.

Tady je myslím všechno jasné. V případě, že by migrace nevyšla, je možné všechno vrátit zpět. Liquibase má nástroj pro návrat změn, ale skripty pro návrat píše také sám vývojář, a v nich mohou být problémy se stejnou pravděpodobností jako ve skriptech hlavního changetu. To znamená, že být opatrný se zálohami je užitečné v každém případě.

5. Používej ověřené zálohy databází ve vývoji, pokud to je možné.

Pokud to není v rozporu se smlouvami a ochranou soukromí, v databázi nejsou osobní údaje a neváží jako dvě slunce — před aplikací migrací na živých serverech lze ověřit, jak to funguje na stroji vývojáře, a spočítat téměř 100% potenciálních problémů při migraci.

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

V dobře organizovaném vývojovém procesu všichni v týmu vědí, kdo se čím zabývá. V praxi to však často není tak, proto je žádoucí, abys, pokud připravuješ změny ve struktuře databáze, navíc informoval celý tým. Pokud někdo provádí změny paralelně — měl bys se opatrně organizovat. Je dobré komunikovat s kolegy i po dokončení práce, ne pouze na začátku. Mnoho potenciálních problémů s changety se může vyřešit během code review.

7. Přemýšlej, co děláš!

Zdá se to jako samozřejmý rada platná pro jakoukoli situaci. Nicméně mnoha problémům by se dalo vyhnout, kdyby vývojář ještě jednou analyzoval, co dělá a jak to může ovlivnit. Práce s migracemi vždy vyžaduje zvýšenou pozornost a preciznost.

Past

Pojďme se nyní podívat na typické pasti, do kterých se můžete dostat, pokud nebudete následovat výše uvedené rady, a co vlastně dělat?

Situace 1. Dva vývojáři se pokoušejí současně přidávat nové changety.

Jak si neublížit pomocí Liquibase
Váša a Petya chtějí vytvořit changet verze 4, aniž by o sobě věděli. Učinili změny ve struktuře databáze a zaslali pull request s různými soubory changetů. Dále je navrhován následující mechanismus postupu:

Jak řešit

  1. Nějakým způsobem se kolegové musí dohodnout, v jakém pořadí mají jejich changety jít, předpokládejme, že Petin by měl být aplikován jako první.
  2. Někdo by měl přidat druhou ke svému a označit chageSet Vaši verzí 5. To lze provést pomocí Cherry Pick nebo pečlivým sloučením.
  3. Po změnách je vždy nutné zkontrolovat platnost provedených akcí.
    Ve skutečnosti mechanismy Liquibase umožňují mít v repozitáři dva changeSety verze 4, takže je možné nechat vše tak, jak to je. To znamená, že budete mít prostě dvě změny verze 4 s různými názvy. Při takovém přístupu je později v verzích databáze velmi obtížné se orientovat.

Kromě toho, Liquibase, jak u hobitů doma, ukrývá mnoho tajemství. Jedním z nich je klíč validCheckSum, který se objevil ve verzi 1.7 a umožňuje uvést platnou hodnotu hash součtu pro konkrétní changeSet, bez ohledu na to, co je uloženo v databázi. 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 tento changeSet, bez ohledu na to, co je uloženo v databázi. Používá se především v případech, kdy potřebujete změnit changeSet a nechcete, aby na databázích, na kterých již běžel, došlo k chybám (což není doporučovaný postup).

Ano, takový postup se nedoporučuje. Ale někdy mocný světlý čaroděj ovládá také temné techniky.

Situace 2. Migrace, která závisí na datech.

Jak si neublížit pomocí Liquibase

Představte si, že nemáte možnost použít zálohy databází z živých serverů. Pjotr vytvořil changeSet, zkontroloval ho lokálně a s naprostou jistotou své pravdy udělal pull request do vývoje. Vedoucí projektu pro jistotu upřesnil, zda ho Pjotr zkontroloval, a poté sloučil. Ale nasazení na vývojovém serveru selhalo.

Ve skutečnosti je to možné a nikdo není před tím chráněn. K tomu dochází, pokud jsou modifikace struktury tabulek nějakým způsobem vázány na konkrétní data z databáze. Je zřejmé, že pokud je Pjotrova databáze naplněna pouze testovacími daty, nemusí pokrýt všechny problematické případy. Například při odstraňování tabulky se ukazuje, že existují záznamy v jiných tabulkách podle cizího klíče související se záznamy v odstraňované tabulce. Nebo při změně typu sloupce se ukazuje, že ne 100 % dat může být převedeno na nový typ.

Jak řešit

  • Napsat speciální skripty, které budou jednorázově použity spolu s migrací a uvedou data do požadovaného stavu. Toto je obecný způsob řešení problému přenosu dat do nových struktur již po aplikaci migrací, ale něco podobného může být použito i předtím, v některých případech. Takový způsob, samozřejmě, není vždy dostupný, neboť editace dat na živých serverech může být nebezpečná a dokonce destruktivní.
  • Další složitou cestou je upravit existující changset. Složitost spočívá v tom, že všechny databáze, kde byl v existujícím stavu již aplikován, bude nutné obnovit. Je docela možné, že celá backendová skupina bude nucena lokálně obnovit databázi od začátku.
  • A nejuniverzálnější cesta je přenést problém s daty na prostředí vývojáře s rekonstrukcí stejné situace a přidat nový changset, až k poškozenému, který umožní problém obejít.
    Jak si neublížit pomocí Liquibase

Obecně platí, čím více se databáze po složení dat podobá databázi produkčního serveru, tím menší je šance, že problémy s migracemi proběhnou daleko. A samozřejmě, než pošlete changset do repozitáře, stojí za to několikrát zvážit, zda něco neporuší.

Situace 3. Liquibase začíná být aplikován až po uvedení do produkce

Předpokládejme, že týmový vedoucí požádal Petu, aby do projektu připojil Liquibase, avšak projekt již je v produkci a má již existující strukturu databáze.

Tedy problém spočívá v tom, že na jakýchkoli nových serverech nebo strojích vývojářů musí být tabulky znovu vytvořeny od nuly, a již existující prostředí by mělo zůstat v konzistentním stavu a být připraveno přijímat nové changsety.

Jak řešit

Zde je také několik cest:

  • První a nejvíce zřejmá — mít samostatný skript, který musí být ručně aplikován při inicializaci nového prostředí.
  • Druhá — méně zřejmá, mít Liquibase migraci, která se nachází v jiném Liquibase kontextu, a aplikovat ji. Podrobněji o Liquibase kontextu si můžete přečíst zde: https://www.liquibase.org/documentation/contexts.html. Obecně je to zajímavý mechanismus, který může být úspěšně použit, například pro testování.
  • Třetí cesta se skládá z několika kroků. Nejprve je třeba vytvořit migraci pro již existující tabulky. Poté by měla být aplikována na nějakém prostředí, čímž se získá její hash. Dalším krokem je inicializace prázdných tabulek Liquibase na našem nepustém serveru a do tabulky s historií aplikace changelistu lze manuálně vložit záznam o "jakoby aplikovaném" changelistu se změnami, které již jsou v databázi. Tímto způsobem na již existujícím serveru začne historie s verzí 2 a všechna nová prostředí se budou chovat identicky.
    Jak si neublížit pomocí Liquibase

Situace 4. Migrace se stávají obrovskými a nestíhají se provádět.

Na začátku vývoje služby se obvykle Liquibase používá jako externí závislost a všechny migrace se zpracovávají při spuštění aplikace. Nicméně časem se můžete setkat s následujícími scénáři:

  • Migrace se stávají obrovskými a provádějí se dlouhou dobu.
  • Objevuje se potřeba migrace v distribuovaných prostředích, například na několika instancích databázových serverů současně.
    V takovém případě příliš dlouhé použití migrací povede k timeoutu při spuštění aplikace. Kromě toho může použití migrací pro každou instanci aplikace zvlášť vést k tomu, že různé servery se ocitnou v nesynchronizovaném stavu.

Jak řešit

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

V autonomním režimu lze použití migrací přenechat vaší CI/CD prostředí nebo na silná ramena vašich systémových administrátorů specialistů na nasazení. K tomu je třeba příkazového řádku Liquibase. https://www.liquibase.org/documentation/command_line.html. V tomto režimu je možné spustit aplikaci až poté, co byly provedeny všechny potřebné migrace.

Výstup

Při práci s migracemi databází mohou existovat mnohem více nástrah, a mnohé z nich vyžadují kreativní přístup. Je důležité chápat, že pokud se nástroj používá správně, většina těchto nástrah se dá vyhnout. Osobně jsem se ve svých různých zkušenostech setkal se všemi uvedenými problémy, z nichž některé byly výsledkem mých vlastních chyb. Většinou to samozřejmě vzniká z nedbalosti, ale někdy - z důvodu trestuhodné neznalosti použití nástroje.

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster