CI/CD миграций схемы (Flyway/Liquibase)
Симптом
Цель: управлять изменениями схемы базы данных с помощью версионированных файлов миграций; применять их автоматически, но контролируемо в CI/CD с помощью Flyway или Liquibase.
1. Создайте версионированные файлы миграций (Vxxx__name.sql)
Записывайте каждое изменение схемы в именованный файл с возрастающим номером версии; соглашение Flyway — V<version>__<description>.sql (например, V1__initial_schemas.sql, V2__orders_table.sql). Эти файлы хранятся в Git и применяются в порядке версий. Применённые миграции фиксируются в служебной таблице (flyway_schema_history в Flyway), поэтому каждая миграция выполняется ровно один раз.
PostgreSQL
-- V2__orders_table.sql
CREATE TABLE orders (
id bigserial PRIMARY KEY,
amount numeric(12,2) NOT NULL,
created_at timestamptz DEFAULT now()
);2. Обеспечьте неизменность с помощью контрольных сумм
Flyway/Liquibase хранят контрольную сумму каждой применённой миграции. Если позже отредактировать уже применённый файл, контрольная сумма перестаёт совпадать, и инструмент завершается с ошибкой. Правило: НИКОГДА не редактируйте применённую миграцию; исправление вносите новым файлом версии. Это гарантирует, что у всех окружений (dev/staging/prod) одинаковая история.
PostgreSQL
# repair on checksum mismatch (use with care):
flyway repair
# the right way: add the change in a new Vx file3. Baseline для существующей базы данных
Используйте baseline при подключении инструмента миграций к уже заполненной базе данных без истории; он считает текущее состояние «начальной версией» и не пытается заново создавать существующие объекты. Применяются миграции после baselineVersion. В окружении, создаваемом с нуля, baseline не нужен; миграции выполняются начиная с V1.
PostgreSQL
flyway baseline -baselineVersion=1 -baselineDescription="existing schema"4. Автоматическая миграция в CI-конвейере
Запускайте инструмент миграций на шаге CI, чтобы автоматически применять изменения к тестовой и staging базам данных; команда migrate выполняет только новые (неприменённые) файлы и идемпотентна. Предварительное применение миграции к временной (эфемерной) базе данных с проверкой выявляет ошибочный SQL до попадания в prod. Схема должна мигрироваться ДО развёртывания кода приложения (с обратно совместимыми изменениями).
PostgreSQL
# CI step (Flyway)
flyway -url=jdbc:postgresql://staging/appdb \
-user=ci -password=$PW migrateMySQL
flyway -url=jdbc:mysql://staging/appdb \
-user=ci -password=$PW migrate5. Добавьте ручное утверждение для prod
Test/staging — автоматически, но migrate в prod должен требовать ручного утверждения; добавьте в CI/CD шаг 'approval gate' (ручное утверждение). Перед утверждением покажите, какие миграции будут выполнены, через 'flyway info' или 'liquibase status'. Перед применением в prod всегда делайте свежий бэкап, чтобы откатиться в случае проблем.
PostgreSQL
# what will run before approval?
flyway info
# liquibase equivalent:
liquibase status --verbose6. Определите обратимость и стратегию отката
Во Flyway Community нет автоматического undo; придерживайтесь принципа миграций только вперёд (forward-only): вместо отмены ошибки пишите новую миграцию, которая её исправляет. Changeset в Liquibase может содержать блок rollback и откатываться через 'liquibase rollback'. Самая надёжная стратегия: делайте изменения небольшими и обратно совместимыми, перед рискованными операциями (удаление столбцов) делайте бэкап и подготовьте письменный план отката.
PostgreSQL
-- Liquibase rollback example (inside a changeset)
--changeset dev:2
CREATE TABLE orders (...);
--rollback DROP TABLE orders;