Како да избегнете пукање во стапалото користејќи Liquibase

Никогаш порано не се случило, и еве одиме повторно!

На нашиот следен проект, решивме да го користиме Liquibase од самиот почеток за да избегнеме проблеми во иднина. Како што се испоставува, не сите млади членови на тимот знаат како правилно да го користат. Одржав интерна работилница, која потоа решив да ја претворам во статија.

Статијата вклучува корисни совети и опис на трите најочигледни замки на кои може да западнете кога работите со алатките за миграција на релациона база на податоци, особено Liquibase. Дизајниран за Java програмери на помлади и средни нивоа; за поискусните програмери може да биде од интерес за структурирање и повторување на она што најверојатно е веќе познато.

Како да избегнете пукање во стапалото користејќи Liquibase

Liquibase и Flyway се главните конкурентни технологии за решавање на проблемите за контрола на верзијата на релационите структури во светот на Јава. Првиот е потполно бесплатен, во пракса најчесто се избира за употреба, поради што е избран Liquibase за херој на публикацијата. Сепак, некои од опишаните практики може да бидат универзални, во зависност од архитектурата на вашата апликација.

Миграциите на релационите структури се принуден начин за справување со слабата флексибилност на складиштата на релациони податоци. Во ерата на модата на OOP, стилот на работа со бази на податоци значеше дека еднаш ќе ја опишеме шемата и нема да ја допираме повторно. Но, реалноста е секогаш дека работите се менуваат, а промените во структурата на табелата се бараат доста често. Секако, самиот процес може да биде болен и непријатен.

Нема да навлегувам подлабоко во описот на технологијата и упатствата за додавање библиотека во вашиот проект; на оваа тема се напишани доста статии:

Покрај тоа, веќе имаше одлична статија на тема корисни совети:

Советы

Сакам да ги споделам моите совети и коментари, кои се родени низ пот, крв и болка во решавањето на проблемите со миграцијата.

1. Пред да започнете со работа, треба да се запознаете со делот за најдобри практики Онлајн Liquibase

Таму се опишани едноставни, но многу важни работи, без кои користењето на библиотеката може да ви го комплицира животот. На пример, неструктурираниот пристап за управување со промените порано или подоцна ќе доведе до конфузија и прекинати миграции. Ако во исто време не внесете меѓусебно зависни промени во структурата на базата на податоци и логиката на услугата, постои голема веројатност тоа да доведе до црвени тестови или до скршена околина. Дополнително, препораките за користење на Liquibase на официјалната веб-страница содржат клаузула за развој и тестирање на скрипти за враќање заедно со главните скрипти за миграција. Па, во статијата https://habr.com/ru/post/178665/ Постојат примери на код во врска со миграциите и механизмот за враќање назад.

2. Ако почнете да користите алатки за миграција, не дозволувајте рачни корекции во структурата на базата на податоци

Како што вели поговорката: „Еднаш Персил, секогаш Персил“. Ако основата на вашата апликација почне да ја управува Liquibase, сите рачни промени веднаш доведуваат до неконзистентна состојба, а нивото на доверба во сетовите за промени станува нула. Потенцијалните ризици вклучуваат неколку часа потрошени за обновување на базата на податоци; во најлошото сценарио, мртов сервер. Ако имате „старата школа“ DBA архитект во вашиот тим, трпеливо и смислено објаснете му колку лоши ќе бидат работите ако тој едноставно ја уредува базата на податоци според сопственото разбирање од условен SQL Developer.

3. Ако сетот за промени е веќе втурнат во складиштето, избегнувајте уредување

Ако некој друг програмер направи влечење и примени сет за промени, кој подоцна ќе биде уреден, тој дефинитивно ќе ве памети со љубезен збор кога ќе добие грешка при стартување на апликацијата. Ако уредувањето на сетот за промени некако протекува во развојот, ќе мора да ја следите лизгавата патека на жешките поправки. Суштината на проблемот почива на валидацијата на промените со хаш сума - главниот механизам на Liquibase. При уредување на кодот за смени, се менува количината на хаш. Уредувањето на збирките на промени е можно само кога е можно да се распореди целата база на податоци од нула без губење податоци. Во овој случај, рефакторирањето на SQL или XML кодот може, напротив, да го олесни животот и да ги направи миграциите почитливи. Пример би била ситуација кога, на почетокот на апликацијата, шемата на изворната база на податоци била договорена во тимот.

4. Потврдете ги резервните копии на базата на податоци ако е можно

Тука, мислам, сè е јасно. Ако одеднаш миграцијата беше неуспешна, сè може да се врати назад. Liquibase има алатка за враќање на промените, но скриптите за враќање се напишани од самиот развивач и тие може да имаат проблеми со истата веројатност како скриптите на главниот менувач. Ова значи дека е корисно да се игра безбедно со резервни копии во секој случај.

5. Користете докажани резервни копии на базата на податоци во развојот, ако е можно

Ако ова не е во спротивност со договорите и приватноста, нема лични податоци во базата на податоци и не тежи колку две сонца - пред да го користите на серверите за миграција во живо, можете да проверите како ќе работи на машината на развивачот и да пресметате речиси 100% од потенцијалните проблеми за време на миграцијата.

6. Комуницирајте со други програмери во тимот

Во добро организиран процес на развој, секој од тимот знае кој што прави. Во реалноста, тоа често не е случај, затоа, ако подготвувате промени во структурата на базата на податоци како дел од вашата задача, препорачливо е дополнително да го известите целиот тим за ова. Ако некој прави промени паралелно, треба внимателно да се организирате. Вреди да се комуницира со колегите по завршувањето на работата, не само на почетокот. Многу потенцијални проблеми со сетовите на промени може да се решат во фазата на преглед на кодот.

7. Размислете што правите!

Тоа би изгледало како очигледен совет кој важи за секоја ситуација. Сепак, многу проблеми можеа да се избегнат доколку развивачот уште еднаш анализираше што прави и што може да влијае. Работата со миграции секогаш бара дополнително внимание и точност.

Замки

Ајде сега да ги погледнеме типичните стапици во кои може да паднете ако не го следите советот погоре, и што, точно, треба да направите?

Ситуација 1: Двајца програмери се обидуваат да додадат нови промени во исто време

Како да избегнете пукање во стапалото користејќи Liquibase
Васија и Петја сакаат да создадат верзија 4 за промени, без да знаат еден за друг. Тие направија промени во структурата на базата на податоци и издадоа барање за повлекување со различни датотеки со промени. Се предлага следниов механизам на дејство:

Како да се реши

  1. Некако, колегите мора да се договорат по кој редослед треба да одат нивните промени, на пример, прво треба да се примени Петин.
  2. Некој треба да го додаде вториот на себе и да го означи менувачот на Vasya со верзија 5. Ова може да се направи преку Cherry Pick или уредно спојување.
  3. По промените, дефинитивно треба да ја проверите валидноста на преземените дејства.
    Всушност, механизмите на Liquibase ќе ви овозможат да имате две верзии на 4 промени во складиштето, за да можете да оставите сè како што е. Тоа е, едноставно ќе имате две промени во верзијата 4 со различни имиња. Со овој пристап, подоцна станува многу тешко да се движите низ верзиите на базата на податоци.

Покрај тоа, Liquibase, како домот на хобитите, чува многу тајни. Еден од нив е клучот validCheckSum, кој се појави во верзијата 1.7 и ви овозможува да наведете валидна хаш вредност за одреден сет на промени, без оглед на тоа што е зачувано во базата на податоци. Документација https://www.liquibase.org/documentation/changeset.html го вели следново:

Додадете контролна сума што се смета за валидна за овој сет на промени, без оглед на тоа што е зачувано во базата на податоци. Се користи првенствено кога треба да промените множество промени и не сакате грешки да се фрлаат на базите на податоци на кои веќе е извршено (не е препорачана процедура)

Да, да, оваа постапка не се препорачува. Но, понекогаш силен светлински волшебник исто така владее со темни техники

Ситуација 2: Миграција која зависи од податоците

Како да избегнете пукање во стапалото користејќи Liquibase

Да претпоставиме дека немате можност да користите резервни копии на базата на податоци од живи сервери. Петја создаде сет за промени, го тестираше локално и, со целосна доверба дека е во право, поднесе барање за повлекување до развивачот. За секој случај, раководителот на проектот појасни дали Петја го проверил, а потоа го додал. Но, распоредувањето на серверот за развој падна.

Всушност, ова е можно, и никој не е имун од ова. Ова се случува ако модификациите на структурата на табелата се некако врзани за конкретни податоци од базата на податоци. Очигледно, ако базата на податоци на Петја е исполнета само со податоци од тестот, тогаш таа може да не ги покрие сите проблематични случаи. На пример, при бришење табела, излегува дека има записи во други табели по Странски клуч кои се поврзани со записите во онаа што се брише. Или кога менувате тип на колона, излегува дека не може 100% од податоците да се претворат во нов тип.

Како да се реши

  • Напишете специјални скрипти кои ќе се користат еднаш заедно со миграцијата и внесете ги податоците во соодветна форма. Ова е општ начин да се реши проблемот со пренос на податоци во нови структури по примена на миграции, но нешто слично може да се примени и претходно, во посебни случаи. Овој пат, се разбира, не е секогаш достапен, бидејќи уредувањето податоци на серверите во живо може да биде опасно, па дури и деструктивно.
  • Друг тежок начин е да се уреди постоечка гарнитура за промени. Тешкотијата е што сите бази на податоци каде што е веќе применета во постоечка форма ќе треба да се обноват. Сосема е можно целиот тим на задниот дел да биде принуден локално да ја отвори базата на податоци од нула.
  • И најуниверзалниот начин е да се пренесе проблемот со податоците во околината на развивачот, повторно да се создаде истата ситуација и да се додаде нов сет на промени, на скршениот, што ќе го заобиколи проблемот.
    Како да избегнете пукање во стапалото користејќи Liquibase

Општо земено, колку повеќе базата е слична во составот на базата на податоци на серверот за производство, толку помали се шансите проблемите со миграциите да одат далеку. И, се разбира, пред да испратите промени во складиштето, треба неколку пати да размислите дали ќе скрши нешто.

Ситуација 3. Liquibase започнува да се користи откако ќе влезе во производство

Да претпоставиме дека раководителот на тимот побарал од Petya да го вклучи Liquibase во проектот, но проектот е веќе во производство и постои постоечка структура на база на податоци.

Соодветно на тоа, проблемот е што на сите нови сервери или машини за развивачи, овие табели мора да се рекреираат од нула, а постоечката околина мора да остане во конзистентна состојба, подготвена да прифати нови групи за промени.

Како да се реши

Исто така, постојат неколку начини:

  • Првото и најочигледно е да имате посебна скрипта што мора да се примени рачно при иницијализирање на нова средина.
  • Вториот е помалку очигледен, имајте миграција на Liquibase што е во друг контекст на Liquibase и применете ја. Можете да прочитате повеќе за Liquibase Context овде: https://www.liquibase.org/documentation/contexts.html. Во принцип, ова е интересен механизам кој може успешно да се користи, на пример, за тестирање.
  • Третиот пат се состои од неколку чекори. Прво, мора да се креира миграција за постоечките табели. Потоа мора да се примени на некоја средина и на тој начин ќе се добие нејзиниот хаш збир. Следниот чекор е да се иницијализираат празни табели Liquibase на нашиот непразен сервер, а во табелата со историја на употреба на сет на промени, можете рачно да ставите запис за множеството промени „како да се применува“ со веќе постоечки промени во базата на податоци. . Така, на постоечки сервер, одбројувањето на историјата ќе започне од верзијата 2, а сите нови средини ќе се однесуваат идентично.
    Како да избегнете пукање во стапалото користејќи Liquibase

Ситуација 4. Миграциите стануваат огромни и немаат време да завршат

На почетокот на развојот на услугата, по правило, Liquibase се користи како надворешна зависност, а сите миграции се обработуваат кога ќе започне апликацијата. Сепак, со текот на времето, може да се сопнете на следниве случаи:

  • Миграциите стануваат огромни и бараат долго време за да се завршат.
  • Има потреба од миграција во дистрибуирани средини, на пример, на неколку примероци на сервери на бази на податоци истовремено.
    Во овој случај, примената на миграции предолго ќе резултира со истек на време кога ќе започне апликацијата. Дополнително, примената на миграции на секој примерок на апликација одделно може да резултира со тоа што различни сервери не се синхронизираат.

Како да се реши

Во такви случаи, вашиот проект е веќе голем, можеби дури и возрасен, а Liquibase почнува да дејствува како посебна надворешна алатка. Факт е дека Liquibase како библиотека се компајлира во датотека jar и може да работи како зависност во рамките на проектот или самостојно.

Во самостоен режим, можете да ја оставите имплементацијата на миграциите во вашата околина CI/CD или на силните раменици на вашите системски администратори и специјалисти за распоредување. За да го направите ова, ќе ви треба командната линија Liquibase https://www.liquibase.org/documentation/command_line.html. Во овој режим, станува возможно да се стартува апликацијата откако ќе се извршат сите потребни миграции.

Излез

Всушност, може да има многу повеќе замки при работа со миграции на бази на податоци, а многу од нив бараат креативен пристап. Важно е да се разбере дека ако ја користите алатката правилно, повеќето од овие стапици може да се избегнат. Поточно, морав да се справам со сите наведени проблеми во различни форми, а некои од нив беа резултат на мои грешки. Најчесто тоа се случува, се разбира, поради невнимание, но понекогаш поради криминална неспособност да се користи алатката.

Извор: www.habr.com

Додадете коментар