Hogyan ne lődd lábon magad a Liquibase segítségével

Soha nem történt meg, és újra itt van!

A következő projektnél a kezdetektől fogva a Liquibase használata mellett döntöttünk, hogy elkerüljük a jövőbeni problémákat. Mint kiderült, nem minden fiatal csapattag tudja, hogyan kell helyesen használni. Csináltam egy belső workshopot, amit aztán úgy döntöttem, hogy cikkté alakítom.

Ez a cikk hasznos tippeket és leírásokat tartalmaz a három legnyilvánvalóbb buktatóról, amelyekbe a relációs adatbázis-áttelepítési eszközökkel, különösen a Liquibase-sel való munka során beleeshet. Junior és Közép szintű Java fejlesztők számára készült, tapasztaltabb fejlesztők számára érdekes lehet a valószínűleg már ismert strukturálása és megismétlése.

Hogyan ne lődd lábon magad a Liquibase segítségével

A Liquibase és a Flyway a fő versengő technológiák a relációs struktúrák verziókezelési problémáinak megoldásában a Java világban. Az első teljesen ingyenes, a gyakorlatban gyakrabban választják felhasználásra, ezért a Liquibase-t választották a kiadvány hősének. Néhány leírt gyakorlat azonban általános lehet, az alkalmazás architektúrájától függően.

A relációs migráció kényszerített módja a relációs adattárak gyenge rugalmasságának kezelésére. Az OOP divatos korszakában az adatbázissal való munka stílusa azt jelentette, hogy egyszer leírjuk a sémát, és többé nem nyúlunk hozzá. De a valóság mindig az, hogy a dolgok változnak, és a táblázatok szerkezetének módosítására gyakran van szükség. Természetesen maga a folyamat fájdalmas és kellemetlen.

Nem fogok belemenni a technológia leírásába és a könyvtár projekthez való hozzáadására vonatkozó utasításokba, elég cikk született ebben a témában:

Ezen kívül már volt egy remek cikk a hasznos tippek témában:

Советы

Szeretném megosztani tanácsaimat és észrevételeimet, amelyek a migrációval kapcsolatos problémák megoldásának verejtékén, vérén és fájdalmán születtek.

1. Mielőtt elkezdené, olvassa el a bevált gyakorlatok című részt Online Liquibase

ott egyszerű, de nagyon fontos dolgokat írnak le, amelyek nélkül a könyvtár használata megnehezítheti az életét. Például a változáskészlet-kezelés nem strukturális megközelítése előbb-utóbb zűrzavarhoz és megszakadt migrációkhoz vezet. Ha nem hajt végre kölcsönösen függő változtatásokat az adatbázis szerkezetében és a szolgáltatások logikájában egyszerre, akkor nagy a valószínűsége annak, hogy ez piros tesztekhez vagy meghibásodott környezethez vezet. Ezenkívül a Liquibase használatára vonatkozó ajánlások a hivatalos webhelyen tartalmaznak egy bekezdést a visszaállítási szkriptek fejlesztéséről és ellenőrzéséről, valamint a fő migrációs szkriptekről. Nos, a cikkben https://habr.com/ru/post/178665/ vannak példák a migrációval és a visszaállítási mechanizmussal kapcsolatos kódra.

2. Ha elkezdte használni az áttelepítési eszközöket, ne engedélyezze a kézi javításokat az adatbázis-struktúrában

Ahogy a mondás tartja: "Egyszer Persil, mindig Persil." Ha az alkalmazás alapját a Liquibase eszközök kezdték kezelni, minden kézi módosítás azonnal inkonzisztens állapothoz vezet, és a változáskészletekbe vetett bizalom szintje nulla lesz. Lehetséges kockázatok - több óra az adatbázis helyreállításával, legrosszabb esetben - egy halott szerver. Ha a csapatnak van egy "régi iskola" DBA-építész, türelmesen és megfontoltan magyarázza el neki, milyen rossz lesz a dolog, ha csak a maga módján szerkeszti az adatbázist a feltételes SQL-fejlesztőtől.

3. Ha a változtatási készletet már elküldték a tárolóba, kerülje a szerkesztést

Ha egy másik fejlesztő kihúzott és alkalmazott egy módosításkészletet, amelyet később szerkesztenek, akkor biztosan egy kedves szóval emlékezik Önre, amikor hibaüzenetet kap az alkalmazás indításakor. Ha a módosításkészlet szerkesztése valahogyan beszivárog a fejlesztésbe, akkor le kell mennie a gyorsjavítások csúszós lejtőjén. A probléma lényege a változások hash összeggel történő érvényesítésén nyugszik – ez a Liquibase fő mechanizmusa. A Changeset kód szerkesztésekor a hash összege megváltozik. A változáskészletek szerkesztése csak akkor lehetséges, ha lehetséges a teljes adatbázis üzembe helyezése a semmiből adatvesztés nélkül. Ebben az esetben az SQL vagy XML kód refaktorálása éppen ellenkezőleg, megkönnyítheti az életet, olvashatóbbá teheti a migrációkat. Példa erre egy olyan helyzet, amikor az alkalmazás indításakor a forrásadatbázis sémáját koordinálták a csapaton belül.

4. Ha lehetséges, készítsen ellenőrzött adatbázis-mentést

Itt szerintem minden világos. Ha a migráció hirtelen sikertelen volt, mindent vissza lehet küldeni. A Liquibase-nek van egy visszaállítási eszköze, de a visszagörgetési szkripteket is maga a fejlesztő írja, és ugyanolyan valószínűséggel adódhatnak problémák, mint a fő Changeset szkriptekben. Ez azt jelenti, hogy a biztonsági mentésekkel való játék minden esetben hasznos.

5. Ha lehetséges, használjon ellenőrzött adatbázis-mentéseket a fejlesztés során

Ha ez nem mond ellent a szerződéseknek és a magánéletnek, akkor nincs személyes adat az adatbázisban, és nem is olyan súlyú, mint két nap - mielőtt élő migrációs szervereken alkalmazná, ellenőrizheti, hogyan működik a fejlesztő gépén, és kiszámolhatja majdnem 100%-át. a migráció során felmerülő lehetséges problémákról.

6. Csevegés a csapat többi fejlesztőjével

Egy jól szervezett fejlesztési folyamat során a csapat minden tagja tudja, hogy ki mit csinál. A valóságban ez gyakran nem így van, ezért ha a feladat részeként változtatásokat készítünk az adatbázis struktúrájában, akkor erről érdemes a teljes csapatot külön értesíteni. Ha valaki párhuzamosan változtatásokat hajt végre, akkor óvatosan kell szerveznie. Munkavégzéskor is érdemes kommunikálni a kollégákkal, nem csak a kezdéskor. A módosításkészletekkel kapcsolatos sok lehetséges probléma megoldható a kód áttekintési szakaszában.

7. Gondold meg, mit csinálsz!

Magától értetődőnek tűnő tanácsok minden helyzetben alkalmazhatók. Sok probléma azonban elkerülhető lett volna, ha a fejlesztő még egyszer elemezte volna, hogy mit csinál, és ez mit érinthet. Az áttelepítésekkel végzett munka mindig fokozott figyelmet és pontosságot igényel.

csapdák

Lássuk most azokat a tipikus csapdákat, amelyekbe eshet, ha nem követi a fenti tanácsot, és mit kell tenni valójában?

1. szituáció. Két fejlesztő egyszerre próbál új módosításkészletet hozzáadni

Hogyan ne lődd lábon magad a Liquibase segítségével
Vasya és Petya úgy akarnak létrehozni egy 4-es verziójú módosításkészletet, hogy nem tudnak egymásról. Változtattak az adatbázis-struktúrán, és lekérést indítottak el, különböző Changeset fájlokkal. Az alábbiakban a következő mechanizmust javasoljuk:

Hogyan kell megoldani

  1. Valahogy a kollégáknak meg kell állapodniuk abban, hogy milyen sorrendben menjenek a változtatások, tegyük fel, hogy először a Petint kell alkalmazni.
  2. Az egyik embernek be kell töltenie a másikat, és meg kell jelölnie Vasya változtatási készletét az 5-ös verzióval. Ez megtehető a Cherry Pick segítségével vagy egy ügyes összevonással.
  3. A változtatások után feltétlenül ellenőrizze a végrehajtott műveletek érvényességét.
    Valójában a Liquibase mechanizmusok lehetővé teszik, hogy két 4-es verziójú változáskészlet legyen az adattárban, így mindent úgy hagyhat, ahogy van. Vagyis egyszerűen csak a 4-es verzió két változata lesz különböző néven. Ezzel a megközelítéssel az adatbázis-verziók később nagyon nehezen navigálhatók.

Ráadásul a Liquibase a hobbitok otthonaihoz hasonlóan sok titkot őriz. Ezek egyike a validCheckSum kulcs, amely az 1.7-es verzió óta jelent meg, és lehetővé teszi egy érvényes hash érték megadását egy adott változáskészlethez, függetlenül attól, hogy mit tárolunk az adatbázisban. Dokumentáció https://www.liquibase.org/documentation/changeset.html a következőket mondja:

Adjon hozzá egy ellenőrző összeget, amely érvényesnek tekinthető ehhez a changeSethez, függetlenül attól, hogy mi van az adatbázisban tárolva. Elsősorban akkor használatos, ha módosítani kell egy changeSet-et, és nem szeretné, hogy hibák jelenjenek meg azokban az adatbázisokban, amelyeken már fut (nem ajánlott eljárás)

Igen, ez nem ajánlott. De néha egy erős fénymágus is elsajátítja a sötét technikákat.

2. eset: Adatvezérelt migráció

Hogyan ne lődd lábon magad a Liquibase segítségével

Tegyük fel, hogy nem használhat adatbázis-mentéseket élő szerverekről. Petya létrehozott egy változtatási készletet, helyben tesztelte, és teljes bizalommal, hogy igaza van, lekérést intézett a fejlesztőhöz. A projektvezető minden esetre tisztázta, hogy Petya ellenőrizte-e, majd beleöntötte. De a telepítés a fejlesztői szerveren visszaesett.

Valójában ez lehetséges, és senki sincs immunis ez ellen. Ez akkor fordul elő, ha a táblaszerkezet módosításai valamilyen módon az adatbázis bizonyos adataihoz vannak kötve. Nyilvánvaló, hogy ha Petya adatbázisa csak tesztadatokkal van feltöltve, akkor lehet, hogy nem fedi le az összes problémás esetet. Például egy tábla törlésekor kiderül, hogy más táblákban is vannak rekordok idegen kulcs alapján a törölni kívánt rekordokhoz társítva. Illetve az oszloptípus megváltoztatásakor kiderül, hogy az adatok nem 100%-a konvertálható az új típusba.

Hogyan kell megoldani

  • Írjon speciális szkripteket, amelyeket a migrációval együtt egyszer alkalmaz, és hozza az adatokat a megfelelő formába. Ez egy általános módja annak, hogy megoldjuk az adatok új struktúrákba való átvitelének problémáját az áttelepítések alkalmazása után, de valami hasonlót alkalmazhatunk korábban is, speciális esetekben. Ez az út természetesen nem mindig elérhető, mert az élő szervereken végzett adatok szerkesztése veszélyes és akár végzetes is lehet.
  • Egy másik trükkös módszer egy meglévő módosításkészlet szerkesztése. A nehézséget az okozza, hogy minden adatbázist vissza kell állítani, ahol a meglévő formában már alkalmazták. Elképzelhető, hogy a teljes háttércsapat kénytelen lesz helyileg a semmiből felgöngyölíteni az adatbázist.
  • A leguniverzálisabb módja pedig az, hogy az adatproblémát átvisszük a fejlesztői környezetbe, újra létrehozzuk ugyanazt a helyzetet, és új változtatásokat adunk hozzá, egy hibáshoz, amely megkerüli a problémát.
    Hogyan ne lődd lábon magad a Liquibase segítségével

Általánosságban elmondható, hogy minél jobban hasonlít az adatbázis összetételében az éles kiszolgáló adatbázisához, annál kevésbé valószínű, hogy a migrációval kapcsolatos problémák messzire mennek. És persze mielőtt elküldené a változtatásokat a repositoryba, többször is meg kell gondolnia, hogy eltör-e valamit.

3. helyzet. A Liquibase-t a gyártás megkezdése után kezdik használni

Tegyük fel, hogy a csapat vezetője megkérte Petyát, hogy vegye be a Liquibase-t a projektbe, de a projekt már éles állapotban van, és már létezik adatbázis-struktúra.

Ennek megfelelően az a probléma, hogy minden új szerveren vagy fejlesztői gépen a tábla adatait a nulláról kell újra létrehozni, és a már meglévő környezetnek konzisztens állapotban kell maradnia, készen kell állnia az új módosítások fogadására.

Hogyan kell megoldani

Több módja is van:

  • Az első és legnyilvánvalóbb, hogy külön szkriptet kell alkalmazni, amelyet manuálisan kell alkalmazni egy új környezet inicializálása során.
  • A második, kevésbé nyilvánvaló, hogy rendelkezzen egy Liquibase-áttelepítéssel, amely más Liquibase-kontextusban van, és alkalmazza azt. A Liquibase Contextről itt olvashat bővebben: https://www.liquibase.org/documentation/contexts.html. Általában véve ez egy érdekes mechanizmus, amely sikeresen alkalmazható például tesztelésre.
  • A harmadik út több lépésből áll. Először is létre kell hozni egy áttelepítést a meglévő táblákhoz. Ezután valamilyen környezetre kell alkalmazni, és így megkapjuk a hash összegét. A következő lépés az üres Liquibase táblák inicializálása a nem üres szerverünkön, és manuálisan behelyezheti egy „mintha alkalmazott” változáskészlet rekordját a már az adatbázisban lévő változtatásokkal a változáskészletek alkalmazásának előzményeit tartalmazó táblába. Így egy már meglévő szerveren az előzmények a 2-es verziótól indulnak, és minden új környezet ugyanúgy fog viselkedni.
    Hogyan ne lődd lábon magad a Liquibase segítségével

4. forgatókönyv: A migrációk hatalmasak, és nem tudnak lépést tartani

A szolgáltatásfejlesztés kezdetén általában a Liquibase-t külső függőségként használják, és minden migráció feldolgozásra kerül az alkalmazás indításakor. Idővel azonban a következő esetekbe ütközhet:

  • A migráció hatalmassá válik, és hosszú ideig tart.
  • Elosztott környezetekben, például egyszerre több adatbázis-kiszolgálón is át kell költözni.
    Ebben az esetben az áttelepítések túl hosszú alkalmazása időtúllépést eredményez az alkalmazás indításakor. Ezenkívül az alkalmazáspéldányonkénti áttelepítések azt eredményezhetik, hogy a különböző kiszolgálók nem szinkronizálódnak.

Hogyan kell megoldani

Ilyen esetekben a projektje már nagy, talán még felnőtt is, és a Liquibase önálló külső eszközként kezd működni. A helyzet az, hogy a Liquibase, mint könyvtár, egy jar fájlba van összeállítva, és függőségként is működhet a projekten belül, de önállóan is.

Offline módban az áttelepítések alkalmazását a CI/CD-környezetre vagy a rendszergazdák/telepítők erős vállára hagyhatja. Ehhez a Liquibase parancssorra van szükség https://www.liquibase.org/documentation/command_line.html. Ebben a módban lehetővé válik az alkalmazás elindítása az összes szükséges migráció befejezése után.

Teljesítmény

Valójában sokkal több buktató is adódik az adatbázis-áttelepítések során, és sok közülük kreatív megközelítést igényel. Fontos megérteni, hogy ha helyesen használja az eszközt, akkor ezeknek a csapdáknak a többsége elkerülhető. Konkrétan az összes felsorolt ​​problémával kellett szembenéznem különböző formában, és ezek egy része az én jambaim eredménye volt. Alapvetően ez természetesen a figyelmetlenség miatt történik, de néha - az eszköz használatának bűnös képtelensége miatt.

Forrás: will.com

Hozzászólás