Com no disparar-se al peu amb Liquibase

No va passar mai, i aquí està de nou!

En el següent projecte, vam decidir utilitzar Liquibase des del principi per evitar problemes en el futur. Com a resultat, no tots els membres de l'equip joves saben com utilitzar-lo correctament. Vaig fer un taller intern, que després vaig decidir convertir en un article.

Aquest article inclou consells útils i descripcions de tres dels inconvenients més evidents en els quals podeu caure quan treballeu amb eines de migració de bases de dades relacionals, Liquibase en particular. Dissenyat per a desenvolupadors Java de nivell Júnior i Mitjà, per a desenvolupadors més experimentats pot ser interessant per estructurar i repetir allò que probablement ja se sap.

Com no disparar-se al peu amb Liquibase

Liquibase i Flyway són les principals tecnologies competidores per resoldre els problemes de control de versions d'estructures relacionals al món Java. El primer és completament gratuït, a la pràctica s'escull més sovint per al seu ús, per això Liquibase va ser escollit com l'heroi de la publicació. Tanmateix, algunes de les pràctiques descrites poden ser genèriques, depenent de l'arquitectura de la vostra aplicació.

Les migracions relacionals són una manera forçada de fer front a la feble flexibilitat dels magatzems de dades relacionals. A l'era de la moda per a la POO, l'estil de treballar amb la base de dades significava que descrivíem l'esquema una vegada i no el tornaríem a tocar. Però la realitat sempre és que les coses canvien, i es requereixen canvis en l'estructura de les taules amb força freqüència. Naturalment, el procés en si és dolorós i desagradable.

No aprofundiré en la descripció de la tecnologia i les instruccions per afegir la biblioteca al vostre projecte, s'han escrit prou articles sobre aquest tema:

A més, ja hi havia un gran article sobre el tema dels consells útils:

Советы

Vull compartir els meus consells i comentaris, que van néixer de la suor, la sang i el dolor de resoldre problemes amb la migració.

1. Abans de començar, hauríeu de llegir la secció de pràctiques recomanades sobre Online Liquibase

Allà Es descriuen coses senzilles però molt importants, sense les quals l'ús de la biblioteca et pot complicar la vida. Per exemple, un enfocament no estructural de la gestió del conjunt de canvis, tard o d'hora, generarà confusió i migracions trencades. Si no introduïu canvis mútuament dependents en l'estructura de la base de dades i la lògica dels serveis al mateix temps, hi ha una gran probabilitat que això condueixi a proves vermelles o a un entorn trencat. A més, les recomanacions per utilitzar Liquibase al lloc web oficial contenen un paràgraf sobre el desenvolupament i la verificació dels scripts de rollback juntament amb els principals scripts de migració. Bé, a l'article https://habr.com/ru/post/178665/ hi ha exemples de codi relacionats amb les migracions i el mecanisme de rollback.

2. Si vau començar a utilitzar les eines de migració, no permeteu correccions manuals a l'estructura de la base de dades

Com diu la dita: "Un cop Persil, sempre Persil". Si les eines de Liquibase han començat a gestionar la base de la vostra aplicació, qualsevol canvi manual condueix instantàniament a un estat inconsistent i el nivell de confiança en els conjunts de canvis esdevé zero. Riscos potencials: diverses hores dedicades a restaurar la base de dades, en el pitjor dels casos, un servidor mort. Si el vostre equip té un arquitecte DBA de la "vella escola", explica-li amb paciència i reflexió com de dolentes seran les coses si només edita la base de dades a la seva manera des del desenvolupador SQL condicional.

3. Si el conjunt de canvis ja s'ha enviat al dipòsit, eviteu editar-lo

Si un altre desenvolupador va treure i va aplicar un conjunt de canvis que s'editarà més tard, sens dubte us recordarà amb una paraula amable quan rebi un error quan s'iniciï l'aplicació. Si l'edició del conjunt de canvis d'alguna manera es filtra al desenvolupament, haureu de baixar pel pendent relliscós de les correccions. L'essència del problema es basa en la validació dels canvis per suma hash, el mecanisme principal de Liquibase. En editar el codi del conjunt de canvis, la suma hash canvia. L'edició de conjunts de canvis només és possible quan és possible desplegar tota la base de dades des de zero sense perdre dades. En aquest cas, refactoritzar codi SQL o XML pot, per contra, facilitar la vida, fer que les migracions siguin més llegibles. Un exemple seria una situació en què, a l'inici de l'aplicació, l'esquema de la base de dades d'origen es coordinava dins de l'equip.

4. Teniu còpies de seguretat verificades de la base de dades si és possible

Aquí, crec, tot està clar. Si de sobte la migració no va tenir èxit, tot es pot tornar. Liquibase té una eina de retrocés, però els scripts de rollback també els ha escrit el mateix desenvolupador, i poden tenir problemes amb la mateixa probabilitat que en els scripts de canvis principals. Això vol dir que jugar amb seguretat amb còpies de seguretat és útil en qualsevol cas.

5. Utilitzeu còpies de seguretat de bases de dades verificades en desenvolupament si és possible

Si això no contradiu els contractes i la privadesa, no hi ha dades personals a la base de dades i no pesa com dos sols; abans d'aplicar-lo als servidors de migració en directe, podeu comprovar com funciona a la màquina del desenvolupador i calcular gairebé el 100% de possibles problemes durant la migració.

6. Xateja amb altres desenvolupadors de l'equip

En un procés de desenvolupament ben organitzat, tots els membres de l'equip saben qui fa què. En realitat, sovint no és així, per tant, si esteu preparant canvis a l'estructura de la base de dades com a part de la vostra tasca, és recomanable que ho notifiqueu a tot l'equip. Si algú està fent canvis en paral·lel, hauríeu d'organitzar-vos amb cura. Val la pena comunicar-se amb els companys fins i tot al final del treball, no només al començament. Molts problemes potencials amb els conjunts de canvis es poden resoldre en l'etapa de revisió del codi.

7. Pensa què estàs fent!

Consells aparentment evidents aplicables a qualsevol situació. Tanmateix, molts problemes s'haurien pogut evitar si el desenvolupador hagués tornat a analitzar què estava fent i què podria afectar. Treballar amb migracions sempre requereix més atenció i precisió.

Trampes

Vegem ara les típiques trampes en què pots caure si no segueixes els consells anteriors i, de fet, què s'ha de fer?

Situació 1. Dos desenvolupadors intenten afegir nous canvis alhora

Com no disparar-se al peu amb Liquibase
Vasya i Petya volen crear un conjunt de canvis de la versió 4 sense saber-se l'un de l'altre. Van fer canvis a l'estructura de la base de dades i van llançar una sol·licitud d'extracció, amb diferents fitxers de canvis. A continuació es proposa el següent mecanisme:

Com resoldre

  1. D'alguna manera, els companys han de posar-se d'acord en l'ordre en què han d'anar els seus canvis, diguem que primer s'ha d'aplicar Petin.
  2. Una persona hauria d'abocar l'altra i marcar el conjunt de canvis de Vasya amb la versió 5. Això es pot fer mitjançant Cherry Pick o una combinació ordenada.
  3. Després dels canvis, assegureu-vos de comprovar la validesa de les accions realitzades.
    De fet, els mecanismes de Liquibase us permetran tenir dos conjunts de canvis de la versió 4 al repositori, de manera que podreu deixar-ho tot tal com està. És a dir, simplement tindreu dues revisions de la versió 4 amb noms diferents. Amb aquest enfocament, les versions de la base de dades es tornen molt difícils de navegar més endavant.

A més, Liquibase, com les cases dels hòbbits, guarda molts secrets. Un d'ells és la clau validCheckSum, que apareix des de la versió 1.7 i que permet especificar un valor hash vàlid per a un conjunt de canvis específic, independentment del que s'emmagatzemi a la base de dades. Documentació https://www.liquibase.org/documentation/changeset.html diu el següent:

Afegiu una suma de comprovació que es consideri vàlida per a aquest conjunt de canvis, independentment del que s'emmagatzemi a la base de dades. S'utilitza principalment quan necessiteu canviar un conjunt de canvis i no voleu que es produeixin errors a les bases de dades en què ja s'ha executat (no és un procediment recomanat)

Sí, això no es recomana. Però de vegades un mag de llum fort també domina les tècniques fosques.

Cas 2: migració basada en dades

Com no disparar-se al peu amb Liquibase

Suposem que no podeu utilitzar còpies de seguretat de bases de dades des de servidors en directe. Petya va crear un conjunt de canvis, el va provar localment i, amb plena confiança que tenia raó, va fer una sol·licitud d'extracció al desenvolupador. Per si de cas, el líder del projecte va aclarir si Petya ho va comprovar i després el va abocar. Però el desplegament al servidor de desenvolupament ha caigut.

De fet, això és possible, i ningú n'és immune. Això passa si les modificacions a l'estructura de la taula estan d'alguna manera lligades a dades específiques de la base de dades. Òbviament, si la base de dades de Petya només s'omple amb dades de prova, és possible que no cobreixi tots els casos problemàtics. Per exemple, en suprimir una taula, resulta que hi ha registres en altres taules per clau estrangera associats amb registres de la que s'està suprimint. O quan es canvia el tipus de columna, resulta que no es poden convertir el 100% de les dades al nou tipus.

Com resoldre

  • Escriviu scripts especials que s'aplicaran una vegada juntament amb la migració i poseu les dades a la forma adequada. Aquesta és una manera general de resoldre el problema de transferir dades a noves estructures després d'aplicar les migracions, però alguna cosa semblant es pot aplicar abans, en casos especials. Aquest camí, per descomptat, no sempre està disponible, perquè editar dades en servidors en directe pot ser perillós i fins i tot fatal.
  • Una altra manera complicada és editar un conjunt de canvis existent. La dificultat és que s'hauran de restaurar totes les bases de dades on ja s'ha aplicat en la seva forma existent. És molt possible que tot l'equip de backend es vegi obligat a enrollar la base de dades localment des de zero.
  • I la manera més universal és transferir el problema de dades a l'entorn del desenvolupador, recrear la mateixa situació i afegir un nou conjunt de canvis, a un de trencat, que evitarà el problema.
    Com no disparar-se al peu amb Liquibase

En general, com més composició sigui similar la base de dades a la base de dades del servidor de producció, menys probable és que els problemes amb les migracions arribin lluny. I, per descomptat, abans d'enviar el conjunt de canvis al repositori, hauríeu de pensar diverses vegades si trencarà alguna cosa.

Situació 3. Liquibase comença a utilitzar-se després d'entrar en producció

Suposem que el líder de l'equip va demanar a Petya que inclogués Liquibase al projecte, però el projecte ja està en producció i ja hi ha una estructura de base de dades existent.

En conseqüència, el problema és que en qualsevol servidor nou o màquina de desenvolupament, les dades de la taula s'han de recrear des de zero i l'entorn ja existent s'ha de mantenir en un estat coherent, preparat per acceptar nous canvis.

Com resoldre

També hi ha diverses maneres:

  • El primer i més obvi és tenir un script separat que s'ha d'aplicar manualment quan s'inicialitzi un nou entorn.
  • La segona, menys evident, és tenir una migració de Liquibase que es trobi en un context de Liquibase diferent i aplicar-la. Podeu llegir més sobre Liquibase Context aquí: https://www.liquibase.org/documentation/contexts.html. En general, aquest és un mecanisme interessant que es pot aplicar amb èxit, per exemple, per fer proves.
  • El tercer camí consta de diversos passos. En primer lloc, s'ha de crear una migració per a les taules existents. Després s'ha d'aplicar en algun entorn i així s'obtindrà la seva suma de hash. El següent pas és inicialitzar les taules Liquibase buides al nostre servidor no buit, i podeu posar manualment un registre d'un conjunt de canvis "com si s'aplica" amb els canvis que ja hi ha a la base de dades a la taula amb l'historial d'aplicacions de conjunts de canvis. Així, en un servidor ja existent, l'historial començarà a partir de la versió 2 i tots els entorns nous es comportaran de manera idèntica.
    Com no disparar-se al peu amb Liquibase

Escenari 4: les migracions són enormes i no poden seguir el ritme

Al començament del desenvolupament del servei, per regla general, Liquibase s'utilitza com a dependència externa i totes les migracions es processen quan s'inicia l'aplicació. Tanmateix, amb el pas del temps, podeu trobar-vos amb els casos següents:

  • Les migracions es fan grans i triguen molt de temps a completar-se.
  • Hi ha una necessitat de migrar en entorns distribuïts, per exemple, en diverses instàncies de servidors de bases de dades alhora.
    En aquest cas, aplicar migracions durant massa temps comportarà un temps d'espera quan s'iniciï l'aplicació. A més, l'aplicació de migracions per instància d'aplicació pot provocar que diferents servidors estiguin en un estat de sincronització.

Com resoldre

En aquests casos, el vostre projecte ja és gran, potser fins i tot un adult, i Liquibase comença a actuar com una eina externa independent. El fet és que Liquibase, com a biblioteca, està muntat en un fitxer jar i pot funcionar com a dependència dins del projecte, així com de manera autònoma.

Fora de línia, podeu deixar l'aplicació de les migracions al vostre entorn CI/CD o a les espatlles fortes dels vostres administradors/desplegadors de sistemes. Per fer-ho, necessiteu la línia d'ordres de Liquibase https://www.liquibase.org/documentation/command_line.html. En aquest mode, és possible iniciar l'aplicació un cop s'hagin completat totes les migracions necessàries.

Sortida

De fet, hi ha molts més inconvenients quan es treballa amb migracions de bases de dades, i molts d'ells requereixen un enfocament creatiu. És important entendre que si feu servir l'eina correctament, la majoria d'aquestes trampes es poden evitar. Concretament, vaig haver d'afrontar tots els problemes enumerats de diferents formes, i alguns d'ells van ser fruit dels meus brancals. Bàsicament, això passa, per descomptat, a causa de la falta d'atenció, però de vegades, a causa de la incapacitat criminal d'utilitzar l'eina.

Font: www.habr.com

Afegeix comentari