Flyway для автоматизації міграцій БД: налаштування та впровадження в CI/CD

Ручні міграції схеми рано чи пізно розходяться між контурами, і реліз починає залежати від пам'яті розробника. Ми налаштовуємо автоматизацію міграцій баз даних під ключ: єдиний порядок змін, перевірки на кожному кроці, передбачувані розгортання. Час на підготовку релізу скорочується в рази, а розходження схем зникають зі списку причин відкату.
Часті запитання

Ручні міграції ламають релізи: де розсипається налаштування Flyway

Поки зміни схеми застосовуються руками, порядок і склад міграцій живе в голові реліз-інженера, а не в репозиторії. На стендах накочують різний набір файлів: десь пропустили індекс, десь застосували чуже виправлення «на майбутнє» — і контури тихо розходяться. Розходження схеми виявляється вже в бою, коли запит із свіжого коду падає через відсутню колонку.

Гірше, коли міграція застосовується частково. Скрипт із кількох змін без транзакційної обгортки падає на середині: половина виправлень уже в базі, половина ні, а службова таблиця про такий стан нічого не знає.

Відкат коду схему не повертає, повторний прогін упирається в «об'єкт уже існує», і далі все відновлюється вручну за логами та резервною копією.

Наступним приходить блокування викату: реліз готовий, але чекає, поки зміни внесе черговий адміністратор, вікно розгортання розтягується, а сумісність версії застосунку й версії схеми тримається на домовленостях.

Ціна такої схеми — не швидкість одного релізу, а втрата керованості: ні відкотити, ні відтворити на чистому стенді.

Розбираємо, як це закривається під час налаштування Flyway: версіоновані файли з репозиторію, контрольні суми застосованих змін, окремий обліковий запис з обмеженими правами й прогін міграцій у конвеєрі до старту нової версії застосунку.

Що дає керований порядок міграцій схеми

Керований порядок міграцій потрібен не задля акуратності в репозиторії, а щоб стан схеми не залежав від ручних правок на стендах. Коли зміни живуть окремими пронумерованими файлами, база збирається відтворювано, а викат перестає бути подією з невідомою тривалістю. Ефекти видно у вимірюваних величинах.

  • Єдиний контур. Тестова, передпродуктивна й продуктивна бази проходять одну послідовність міграцій — розходження спливає на збірці, а не в момент релізу.
  • Версіонування схеми. У міграції є номер і контрольна сума, у базі — журнал застосованого. Інструмент на кшталт Flyway не накотить файл, змінений після застосування: правка заднім числом не проходить непоміченою.
  • Передбачуваний викат. Інкрементальна зміна накочується за секунди й не залежить від обсягу накопичених даних — вікно робіт планується заздалегідь.
  • Відкат без відновлення з копії. Парні міграції та схема розширення-стиснення залишають попередній реліз застосунку робочим: повернення — це операція, а не аварійне відновлення.
  • Простій через міграції зникає. Блокуючі перебудування виносяться в окремий крок і йдуть без зупинки запису — незапланованих пауз не залишається.

Підсумок: однаковий набір об'єктів на всіх контурах, час викату в відомому інтервалі й знятий клас відмов, який раніше давали ручні правки схеми.

Варіанти налаштування Flyway: порівняння режимів роботи

Один і той самий опис міграцій Flyway застосовується по-різному: схему можна змінювати автоматично під час старту застосунку, окремим кроком конвеєра перед викатом або вручну за командою інженера.

Режим задає не синтаксис міграцій, а момент застосування, права в базі й те, наскільки швидко команда помічає розсинхрон схеми та коду.

Режим Коли доречний Обмеження
Автоматичні міграції під час старту Локальні та тестові стенди, одиничний інстанс, часті ітерації За кількох реплік міграція стартує паралельно — потрібне блокування, інакше гонка; момент застосування не контролюється
Окремий крок конвеєра до викату Продуктивні середовища, кілька реплік, потрібен передбачуваний порядок Потрібен окремий доступ до бази й запас часу під довгі зміни схеми
Міграції на вимогу Регульовані контури, аудит змін, критичні таблиці Людський фактор: схема відстає від викату, помилка призводить до простою

Як вибирати режим під оточення

Опис міграцій залишається єдиним для всіх контурів, різниться лише конфігурація оточень: на стендах — автоматичне накочування, у продукти ві — окремий крок під обліковим записом із правами лише на зміну схеми.

Перевірка відповідності версії схеми виноситься на старт застосунку: якщо міграції не застосовані, сервіс не піднімається.

Це прибирає клас інцидентів, коли новий код працює зі старою схемою, а руйнівні операції на кшталт очищення схеми в продукти ві вимикаються на рівні налаштувань.

Етапи впровадження: від аудиту схеми до передачі регламентів

Порядок робіт будуємо так, щоб кожен наступний крок спирався на перевірений попередній. Помилка у версіонуванні має спливти на копії, а не на робочому контурі, — тоді це година відкату замість нічного відновлення з резервної копії.

  1. Аудит схеми. Збираємо структуру всіх контурів, порівнюємо між собою та з історією змін у системі контролю версій. Знаходимо розходження, правки, накочені вручну, та об'єкти, яких немає в жодному скрипті.
  2. Схема версіонування. Домовляємося про нумерацію міграцій, правила найменування та розділення одноразових і повторюваних змін. Фіксуємо, хто і як додає наступну міграцію.
  3. Перенесення історії. Приводимо чинну базу до опорного стану: позначаємо поточну структуру вихідною точкою, щоб минулі зміни не накочувалися заново.
  4. Перевірка на копії. Проганяємо весь набір на повній копії робочого контуру — спочатку з нуля, потім поверх поточного стану. Рахуємо час і ловимо конфлікти.
  5. Точки контролю. Міграції йдуть окремим кроком до старту застосунку, з блокуванням викату в разі помилки. Збіг структури з очікуваною — умова проходження далі.
  6. Регламент викату. Окремо описуємо зміни, що потребують зупинки сервісу: підготовка, вікно, порядок відкату, відповідальні.
  7. Передача. Віддаємо конфігурації, схеми, інструкції та розбір типових збоїв — команда веде міграції далі сама.

Що залишається в репозиторії та в команди після впровадження

Впровадження вважається завершеним не тоді, коли міграція пройшла на тестовому контурі, а коли в команди залишився комплект артефактів, за яким наступний реліз випускає будь-який інженер, а не автор змін.

Нижче — мінімальний набір, який ми передаємо разом із робочим конвеєром; кожен пункт перевіряємо на прийманні.

  • Репозиторій міграцій — плоскі версіоновані файли з прямим і зворотним сценарієм, одна логічна правка на файл. Уже застосовані файли не редагуються: будь-яка зміна схеми — новий файл, інакше контрольні суми розійдуться між контурами.
  • Політика рев'ю — обов'язковий перегляд скрипта другим інженером, правила найменування та порядок викладки. Окремо фіксуємо заборону на ручні правки схеми: будь-які зміни проходять лише через репозиторій.
  • Налаштування оточень — профілі підключення для розробки, тесту й промислового контуру, окремі облікові записи з мінімально потрібними правами. Блокування й таймаути задані явно, щоб довга міграція не валила сервіс.
  • Регламент відкату — що робимо при невдалій міграції: точка відновлення, порядок компенсувальних скриптів, хто ухвалює рішення про зупинку. Цільовий час повернення до робочої версії фіксуємо й перевіряємо на навчаннях.
  • Документація схеми — актуальна модель даних, яка збирається з самого сховища після кожної викладки, з описом ключових сутностей і зв'язків. Жива схема замість застарілої презентації піврічної давності.
  • Інструкції для чергової зміни — де дивитися журнал міграцій, які помилки означають зупинку конвеєра, як перевести викладку в ручний режим. Плюс чек-лист приймання релізу на 5–7 пунктів.

Комплект залишається у вашому репозиторії та вашій системі керування задачами — ним можна користуватися без нас.

Кейс: як схема на кількох контурах перестала розходитися

Проєкт — сервіс із трьома контурами: розробка, приймання й продуктив. Міграції там накочували руками: скрипти лежали в репозиторії, інженер запускав їх по черзі й стежив за виводом.

На момент розбору схеми розійшлися більш ніж на 40 об'єктів — індекси, обмеження, значення за замовчуванням і типи окремих полів.

Ціна розходження проявилася на прийманні: перевірки йшли за структурою, якої в продукти ві не було, і частина дефектів доїжджала до користувачів. Сам викат займав 40–60 хвилин ручної роботи й потребував вікна, а відкат перетворювався на розбір журналів і правки на місці.

Схему перевели на Flyway: кожен скрипт отримав номер версії та контрольну суму, стан фіксується в службовій таблиці.

Міграції вбудували в конвеєр збірки — вони застосовуються на кожному контурі автоматично, а спроба застосувати вже накочений або змінений скрипт зупиняє збірку до розбору.

Що стало після впровадження

Викат схеми скоротився до 4–6 хвилин і перестав потребувати окремого вікна. Розходжень між контурами — нуль: структура на прийманні та в продукти ві збирається з одного ланцюжка версій.

Час відновлення при невдалій міграції — близько 10 хвилин: зворотний сценарій плюс повернення попереднього артефакту. Зник цілий клас відмов, коли на контур потрапляв не той скрипт або один і той самий застосовувався двічі.

Що робити, якщо частину міграцій уже застосовано вручну

Схема розвивалася прямими правками: колонку додали через консоль, індекс побудували вручну, частина об'єктів уже давно в продакшені.

Таблиці історії застосованих міграцій при цьому немає, і перший запуск Flyway бачить порожній журнал — він намагається накотити все з початку й падає на вже наявних таблицях. Порядок відновлюють через базову лінію, а не через ручне перезбирання журналу.

Базова лінія — це зафіксований поточний стан схеми, від якого починається керована історія.

Виставляють baselineVersion на версію, з якої далі йдуть міграції, і вмикають baselineOnMigrate: під час першого запуску створюється один запис про базову лінію, а наявні об'єкти залишаються недоторканими. Усе, що робилося руками до неї, вважається частиною стартової точки.

Однієї базової лінії мало. Ручні правки накочувалися без контролю, тому об'єкти можуть розходитися з тим, що описано в міграціях — аж до типів колонок і обмежень.

Проганяють validate і дивляться розходження, потім repair перезбирає контрольні суми й прибирає записи про невдалі спроби.

Далі відновлюють порядок: зміни йдуть лише файлами міграцій, а пряма правка продакшену заборонена або відкочується окремою міграцією. Корисно звірити схему тестового й робочого контурів — так базова лінія не закріпить непомічене розходження, яке спливе через кілька релізів.

Якщо схема розійшлася надто сильно, чесніше поставити базову лінію на версію нижче поточної й описати залишок окремим скриптом приведення.

Рішення ухвалюють за обсягом розходжень, а не за звичкою: іноді дешевше один раз вирівняти схему, ніж тягнути журнал, який ніколи не сходився.

Часті технічні сумніви щодо міграцій баз даних

Сумніви інженерів навколо міграцій зводяться до чотирьох сценаріїв: одночасний старт кількох екземплярів сервісу, падіння зміни на середині, видалення стовпця, що став непотрібним, і порядок погодження правок схеми. Нижче — як кожен із них закривається в налаштуванні Flyway.

Сервіс стартує в кількох екземплярах — міграція застосується двічі?

Ні: інструмент бере блокування на службовій таблиці історії версій, тому зміну застосовує лише перший вузол, решта чекають звільнення й бачать, що версію вже зафіксовано.

Складність в іншому — під час поетапного оновлення екземплярів старий код якийсь час працює з новою схемою, тому зміни робимо зворотно сумісними: спочатку додали, перемкнули читання й запис, і лише потім прибрали зайве.

Що залишиться в базі, якщо міграція впаде на середині?

Залежить від того, чи підтримує СУБД транзакційні зміни структури. Де підтримує — міграція відкочується повністю, і повторний запуск іде з чистого стану.

Де ні — частина об'єктів уже створена, і налаштування включає розбір такого стану: звіряємо фактичну схему, позначаємо невдалу версію й повторюємо з коректної точки. Великі перетворення тому дробимо на дрібні кроки.

Як видаляють стовпці та погоджують небезпечні зміни?

Видалення стовпця або таблиці — двофазна операція: спочатку прибираємо звернення в коді й викочуємо реліз, наступною зміною видаляємо об'єкт. Так зникає ризик, що працюючий екземпляр звернеться до відсутнього поля.

Довгі операції, які утримують блокування таблиці, виносимо в окреме вікно й обмежуємо час очікування блокування, щоб не зібрати чергу запитів. Самі правки схеми проходять загальне погодження в тому самому порядку, що й код.

Обговоримо задачу й повернемося з оцінкою та планом

Щоб повернутися з оцінкою та планом робіт, а не із загальними формулюваннями, достатньо короткого зрізу вашого контуру міграцій. Нижче — вхідні дані, за якими ми побачимо обсяг і ризики, не заходячи на ваші стенди.

  • СУБД та її версія на проді й на тестових стендах, плюс дамп структури схеми без самих даних.
  • Поточні скрипти змін: як називаються, де лежать, чи є вже застосовані вручну й не позначені в службовій таблиці Flyway.
  • Як зміни потрапляють у прод зараз: хто і якою командою накочує, у яке вікно, що роблять при помилці на середині.
  • Репозиторій і збірка: де зберігаються міграції, чим збирається застосунок, чи є окремий конвеєр викату.
  • Оточення й доступи: скільки стендів, чим різняться набори даних, які облікові записи можна видати автоматиці.
  • Вимоги до відкату й простою: допустимий час недоступності та що вважається коректним відкатом — зворотний скрипт або відновлення з копії.

Далі ми розбираємо передане, перевіряємо порядок застосування й повторюваність скриптів, відзначаємо кроки, які доведеться залишити ручними, і звіряємо опис схеми з тим, що вже розгорнуто.

На виході ви отримуєте план етапів, склад автоматичних перевірок перед викатом і порядок відкату — з оцінкою за строками та складом робіт.

Наступний крок — коротка розмова по суті. Опишіть задачу: достатньо пари абзаців про поточний стан і про те, що заважає, — повернемося з оцінкою та планом.

Наші компетенції:

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1393
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1368
  • Розробка логотипу компанії B2B Advance
    Розробка логотипу компанії B2B Advance
    815
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1139