Kako ne pucati sebi u nogu koristeći Liquibase

Nikad se nije dogodilo, a evo ga opet!

Na sljedećem projektu odlučili smo koristiti Liquibase od samog početka kako bismo izbjegli probleme u budućnosti. Kako se pokazalo, ne znaju svi mladi članovi tima kako ga pravilno koristiti. Napravio sam internu radionicu, koju sam potom odlučio pretvoriti u članak.

Ovaj članak uključuje korisne savjete i opise tri najočiglednije zamke u koje možete upasti kada radite s alatima za migraciju relacijskih baza podataka, posebno Liquibaseom. Dizajniran za Java programere mlađeg i srednjeg nivoa, za iskusnije programere može biti zanimljiv za strukturiranje i ponavljanje onoga što je najvjerovatnije već poznato.

Kako ne pucati sebi u nogu koristeći Liquibase

Liquibase i Flyway su glavne konkurentske tehnologije za rješavanje problema kontrole verzija relacijskih struktura u svijetu Java. Prvi je potpuno besplatan, u praksi se češće bira za upotrebu, zbog čega je Liquibase izabran za junaka publikacije. Međutim, neke od opisanih praksi mogu biti generičke, ovisno o arhitekturi vaše aplikacije.

Relacijske migracije su prisilan način rješavanja slabe fleksibilnosti relacijskih skladišta podataka. U eri mode za OOP, stil rada sa bazom podataka je značio da ćemo shemu opisati jednom i da je više ne dodirujemo. Ali stvarnost je uvijek da se stvari mijenjaju, a promjene u strukturi tabela su potrebne prilično često. Naravno, sam proces je bolan i neprijatan.

Neću ulaziti u opis tehnologije i uputstva za dodavanje biblioteke u vaš projekat, dovoljno je članaka na ovu temu:

Osim toga, već je postojao sjajan članak na temu korisnih savjeta:

Savjeti

Želim podijeliti svoje savjete i komentare, koji su se rodili kroz znoj, krv i bol rješavanja problema s migracijama.

1. Prije nego što počnete, trebali biste pročitati odjeljak o najboljim praksama site Liquibase

Eto opisane su jednostavne, ali vrlo važne stvari, bez kojih korištenje biblioteke može zakomplikovati vaš život. Na primjer, nestrukturalni pristup upravljanju skupovima promjena prije ili kasnije će dovesti do zabune i pokvarenih migracija. Ako istovremeno ne uvedete međusobno zavisne promjene u strukturi baze podataka i logici usluga, postoji velika vjerovatnoća da će to dovesti do crvenih testova ili pokvarenog okruženja. Osim toga, preporuke za korištenje Liquibase-a na službenoj web stranici sadrže paragraf o razvoju i verifikaciji skripti za vraćanje, zajedno sa glavnim skriptama za migraciju. Pa, u članku https://habr.com/ru/post/178665/ postoje primjeri koda koji se odnose na migracije i mehanizam vraćanja.

2. Ako ste počeli koristiti alate za migraciju, nemojte dozvoliti ručne ispravke u strukturi baze podataka

Kako se kaže: "Jednom Persil, uvek Persil." Ako osnovom vaše aplikacije počnu upravljati Liquibase alati, sve ručne promjene trenutno dovode do nekonzistentnog stanja, a nivo povjerenja u skupove promjena postaje nula. Potencijalni rizici - nekoliko sati utrošenih na obnavljanje baze podataka, u najgorem slučaju - mrtav server. Ako vaš tim ima DBA arhitektu "stare škole", strpljivo i promišljeno mu objasnite koliko će loše stvari biti ako samo uređuje bazu podataka na svoj način iz uvjetnog SQL Developera.

3. Ako je skup promjena već gurnut u spremište, izbjegavajte uređivanje

Ako je neki drugi programer povukao i primijenio set izmjena koji će se naknadno uređivati, sigurno će vas se sjetiti lijepom riječi kada dobije grešku kada se aplikacija pokrene. Ako uređivanje skupa promjena nekako procuri u razvoj, morat ćete se spustiti niz klizav niz hitnih popravki. Suština problema počiva na validaciji promjena heš sumom - glavni mehanizam Liquibase-a. Prilikom uređivanja koda skupa izmjena, heš suma se mijenja. Uređivanje skupova izmjena je moguće samo kada je moguće implementirati cijelu bazu podataka od nule bez gubitka podataka. U ovom slučaju, refaktoriranje SQL ili XML koda može, naprotiv, olakšati život, učiniti migracije čitljivijim. Primjer bi bila situacija kada je, na početku aplikacije, shema izvorne baze podataka bila koordinirana unutar tima.

4. Imajte provjerene sigurnosne kopije baze podataka ako je moguće

Ovdje je, mislim, sve jasno. Ako iznenada migracija nije bila uspješna, sve se može vratiti nazad. Liquibase ima alat za vraćanje nazad, ali skripte za vraćanje takođe piše sam programer i mogu imati problema sa istom verovatnoćom kao u glavnim skriptama skupa izmena. To znači da je igranje na sigurno sa rezervnim kopijama korisno u svakom slučaju.

5. Koristite provjerene sigurnosne kopije baze podataka u razvoju ako je moguće

Ako to nije u suprotnosti s ugovorima i privatnošću, nema ličnih podataka u bazi podataka i ne teži kao dva sunca - prije nego što ga primijenite na servere za migraciju uživo, možete provjeriti kako radi na mašini programera i izračunati skoro 100% potencijalnih problema tokom migracije.

6. Razgovarajte s drugim programerima u timu

U dobro organizovanom procesu razvoja, svi u timu znaju ko šta radi. U stvarnosti to često nije slučaj, stoga, ako u sklopu svog zadatka pripremate promjene u strukturi baze podataka, preporučljivo je o tome dodatno obavijestiti cijeli tim. Ako neko paralelno radi promjene, treba se pažljivo organizirati. Vrijedi komunicirati sa kolegama i na kraju posla, ne samo na početku. Mnogi potencijalni problemi sa skupovima izmjena mogu se riješiti u fazi pregleda koda.

7. Razmisli šta radiš!

Naizgled samorazumljiv savjet primjenjiv u svakoj situaciji. Međutim, mnogi problemi su se mogli izbjeći da je programer još jednom analizirao šta radi i na šta bi to moglo uticati. Rad sa migracijama uvijek zahtijeva dodatnu pažnju i preciznost.

Lovci

Pogledajmo sada tipične zamke u koje možete upasti ako ne slijedite gore navedene savjete, a šta bi, u stvari, trebalo učiniti?

Situacija 1. Dva programera pokušavaju dodati nove skupove izmjena u isto vrijeme

Kako ne pucati sebi u nogu koristeći Liquibase
Vasya i Petya žele napraviti set promjena verzije 4, a da ne znaju jedno za drugo. Napravili su promjene u strukturi baze podataka i uveli zahtjev za povlačenjem, s različitim datotekama skupa izmjena. U nastavku se predlaže sljedeći mehanizam:

Kako riješiti

  1. Nekako se kolege moraju dogovoriti o redoslijedu kojim bi njihovi setovi promjena trebali ići, recimo Petin prvo treba primijeniti.
  2. Jedna osoba treba uliti drugu i označiti Vasyin set izmjena sa verzijom 5. To se može uraditi putem Cherry Pick-a ili urednog spajanja.
  3. Nakon izmjena obavezno provjerite valjanost poduzetih radnji.
    U stvari, Liquibase mehanizmi će vam omogućiti da imate dva seta izmjena verzije 4 u spremištu, tako da možete ostaviti sve kako jeste. To jest, jednostavno ćete imati dvije revizije verzije 4 sa različitim imenima. Sa ovim pristupom, kasnije postaje vrlo teško navigirati verzijama baze podataka.

Osim toga, Liquibase, kao i domovi hobita, čuva mnogo tajni. Jedan od njih je validCheckSum ključ, koji se pojavljuje od verzije 1.7 i omogućava vam da navedete ispravnu heš vrijednost za određeni skup promjena, bez obzira na to što je pohranjeno u bazi podataka. Dokumentacija https://www.liquibase.org/documentation/changeset.html kaže sljedeće:

Dodajte kontrolni zbroj koji se smatra važećim za ovaj skup promjena, bez obzira na to što je pohranjeno u bazi podataka. Koristi se prvenstveno kada trebate promijeniti changeSet i ne želite da se pojave greške na bazama podataka na kojima je već pokrenut (nije preporučena procedura)

Da, ovo se ne preporučuje. Ali ponekad jaki magičar svetlosti savladava i tamne tehnike.

Slučaj 2: Migracija vođena podacima

Kako ne pucati sebi u nogu koristeći Liquibase

Recimo da ne možete koristiti sigurnosne kopije baze podataka sa živih servera. Petya je napravio set promjena, testirao ga lokalno i s punim povjerenjem da je bio u pravu, uputio je zahtjev za povlačenje programeru. Za svaki slučaj, voditelj projekta je pojasnio da li ga je Petya provjerio, a zatim ga ulio. Ali implementacija na razvojnom serveru je pala.

U stvari, to je moguće i niko nije imun od toga. Ovo se dešava ako su modifikacije strukture tabele na neki način vezane za određene podatke iz baze podataka. Očigledno, ako je Petyina baza podataka popunjena samo podacima testa, onda možda neće pokriti sve slučajeve problema. Na primjer, prilikom brisanja tabele, ispostavlja se da postoje zapisi u drugim tabelama po stranom ključu koji su povezani sa zapisima u onoj koja se briše. Ili kada se promijeni tip stupca, ispada da se ne može 100% podataka konvertirati u novi tip.

Kako riješiti

  • Napišite posebne skripte koje će se primijeniti jednom uz migraciju i dovedite podatke u odgovarajući oblik. Ovo je opći način rješavanja problema prijenosa podataka u nove strukture nakon primjene migracija, ali nešto slično se može primijeniti i prije, u posebnim slučajevima. Ovaj put, naravno, nije uvijek dostupan, jer uređivanje podataka na živim serverima može biti opasno, pa čak i fatalno.
  • Još jedan lukav način je uređivanje postojećeg skupa izmjena. Poteškoća je u tome što će sve baze podataka u kojima je već primijenjen u postojećem obliku morati da se restauriraju. Sasvim je moguće da će cijeli backend tim biti primoran da lokalno namota bazu podataka od nule.
  • A najuniverzalniji način je prebaciti problem sa podacima u okruženje programera, ponovo kreirati istu situaciju i dodati novi skup promjena, u pokvareni, koji će zaobići problem.
    Kako ne pucati sebi u nogu koristeći Liquibase

Općenito, što je baza podataka sličnija po sastavu bazi podataka proizvodnog servera, manja je vjerovatnoća da će problemi s migracijama otići daleko. I, naravno, prije nego što pošaljete skup promjena u spremište, trebali biste nekoliko puta razmisliti da li će nešto pokvariti.

Situacija 3. Liquibase počinje da se koristi nakon što krene u proizvodnju

Pretpostavimo da je vođa tima zamolio Petyu da uključi Liquibase u projekat, ali projekat je već u produkciji i već postoji struktura baze podataka.

Shodno tome, problem je u tome što na svim novim serverima ili mašinama za razvojne programere, podaci tabele moraju biti ponovo kreirani od nule, a već postojeće okruženje mora ostati u konzistentnom stanju, spremno da prihvati nove skupove izmena.

Kako riješiti

Postoji i nekoliko načina:

  • Prvi i najočitiji je imati zasebnu skriptu koja se mora primijeniti ručno prilikom inicijalizacije novog okruženja.
  • Drugi, manje očigledan, je imati Liquibase migraciju koja je u drugom Liquibase kontekstu i primijeniti je. Više o Liquibase kontekstu možete pročitati ovdje: https://www.liquibase.org/documentation/contexts.html. Općenito, ovo je zanimljiv mehanizam koji se može uspješno primijeniti, na primjer, za testiranje.
  • Treći put se sastoji od nekoliko koraka. Prvo, mora se kreirati migracija za postojeće tabele. Zatim se mora primijeniti na neko okruženje i tako će se dobiti njegov hash zbroj. Sljedeći korak je inicijalizacija praznih Liquibase tabela na našem nepraznom serveru, a možete ručno staviti zapis „kao primijenjenog“ skupa izmjena sa promjenama koje su već u bazi podataka u tablicu s istorijom primjene skupova izmjena. Dakle, na već postojećem serveru istorija će početi od verzije 2, a sva nova okruženja će se ponašati identično.
    Kako ne pucati sebi u nogu koristeći Liquibase

Scenario 4: Migracije postaju ogromne i ne mogu pratiti korak

Na početku razvoja servisa, po pravilu, Liquibase se koristi kao eksterna zavisnost, a sve migracije se obrađuju kada se aplikacija pokrene. Međutim, s vremenom možete naići na sljedeće slučajeve:

  • Migracije postaju ogromne i potrebno im je mnogo vremena da se završe.
  • Postoji potreba za migracijom u distribuiranim okruženjima, na primjer, na nekoliko instanci servera baze podataka u isto vrijeme.
    U ovom slučaju, predugo primjena migracija rezultirat će timeoutom kada se aplikacija pokrene. Također, primjena migracija na osnovu instance aplikacije može dovesti do toga da različiti serveri budu u nesinhroniziranom stanju.

Kako riješiti

U takvim slučajevima, vaš projekt je već veliki, možda čak i odrasla osoba, a Liquibase počinje djelovati kao poseban vanjski alat. Činjenica je da je Liquibase, kao biblioteka, sastavljena u jar fajl, i može da radi kao zavisnost u okviru projekta, ali i samostalno.

Offline, možete prepustiti primjenu migracija na vaše CI/CD okruženje ili na jaka ramena vaših sysadmina/deployera. Da biste to učinili, potrebna vam je komandna linija Liquibase https://www.liquibase.org/documentation/command_line.html. U ovom načinu rada postaje moguće pokrenuti aplikaciju nakon što su sve potrebne migracije završene.

zaključak

U stvari, postoji mnogo više zamki pri radu s migracijama baze podataka, a mnoge od njih zahtijevaju kreativan pristup. Važno je razumjeti da ako pravilno koristite alat, većina ovih zamki se može izbjeći. Konkretno, morao sam se suočiti sa svim navedenim problemima u različitim oblicima, a neki od njih su bili rezultat mojih zaglavljivanja. U osnovi, to se događa, naravno, zbog nepažnje, ali ponekad - zbog kriminalne nemogućnosti korištenja alata.

izvor: www.habr.com

Dodajte komentar