Миграции БД при деплое: Flyway, goose, EF и обратная совместимость

↑ 7.6 DevOps для бэкенд-разработчика · ← Предыдущая · → Следующая

По желанию~3 мин чтенияУровень: senior

Зачем это на собесе

Как менять схему без простоя и без риска, что старая версия кода сломается.

Объяснение

ИнструментОсобенности
Flyway (Java, CLI, контейнер)SQL-файлы V1__init.sql, версионирование, чексуммы
goose (Go)SQL/Go-миграции, up/down
EF Core MigrationsC#-миграции, idempotent-скрипты, bundle (см. Миграции EF Core)
Liquibase, DbUp, Atlasальтернативы

Правила выкладки:

  • Миграции отдельным шагом до запуска новой версии (init-контейнер/job), а не из каждого экземпляра приложения.
  • Миграции идемпотентны и версионированы, применённые файлы не редактируются.
  • Хранятся в репозитории рядом с кодом.

Обратная совместимость (expand → migrate → contract)

  1. Expand: добавить новое (колонка nullable, новая таблица) — старый код работает.
  2. Выкатить код, пишущий в старое и новое (или читающий новое).
  3. Migrate: перенести данные пакетами.
  4. Contract: после полного перехода удалить старое отдельной миграцией.
ОперацияБезопасно?
ADD COLUMN NULLда
ADD COLUMN NOT NULL без defaultнет (блокирует, ломает старый код)
RENAME/DROP COLUMNнет: через expand/contract
CREATE INDEXв PostgreSQL — CONCURRENTLY
Изменение типапересоздание колонки поэтапно

Нюансы и подводные камни

  • Долгие блокировки (ALTER TABLE на больших таблицах) останавливают прод.
  • Откат «вниз» миграции данных часто невозможен: планируйте прямые исправления.
  • Одновременная работа двух версий приложения при rolling-обновлении требует совместимости.
  • Тестируйте миграции на копии реальных объёмов данных.
  • Блокировка на уровне миграций (advisory lock) предотвращает параллельный запуск.

Практика

  1. Переименуйте колонку через expand/contract на тестовой БД.
  2. Настройте job миграций в CI/CD перед деплоем.
  3. Создайте индекс на большой таблице без блокировки.

Вопросы с ответами

Связанные темы