PostgreSQL: миграции без даунтайма

PostgreSQL: миграции без даунтайма

«ALTER TABLE» в пик трафика — классический способ положить iGaming или маркет в субботу. Миграции проектируют как релизы: expand → deploy → contract.

PostgreSQL: миграции без даунтайма
Иллюстрация к материалу

Expand / contract

Добавить nullable column → deploy код, пишущий в оба → backfill → NOT NULL → удалить старое.

Индексы

  • CREATE INDEX CONCURRENTLY — отдельная миграция
  • Не блокировать таблицы orders/wallet на минуты

Sequelize / raw SQL

  • up/down идемпотентны где возможно
  • Тяжёлые миграции — maintenance window или feature flag read path
PostgreSQL: миграции без даунтайма
Схема и рабочий процесс

Чеклист

  • Staging = copy prod schema
  • Rollback plan documented
  • Monitoring на lock wait

Пример expand/contract

Релиз 1: ADD COLUMN new_email nullable. Релиз 2: код пишет в email и new_email. Релиз 3: backfill job ночью. Релиз 4: NOT NULL + drop old column.

Так вы избегаете блокировки таблицы users на ALTER с NOT NULL в пик трафика.

Мониторинг миграций

  • Алерт на lock wait > 30s на prod
  • Лог длительности каждой migration up
  • Запрет destructive DDL без ticket и окна

Staging как копия prod

Перед релизом прогоняйте миграции на anonymized dump с объёмом хотя бы 10% prod. На пустой БД миграция «летит», на миллионах строк — внезапный ACCESS EXCLUSIVE lock.

Down-миграции и rollback

Down не всегда симметричен up: после backfill и NOT NULL откат может быть невозможен без потери данных. Документируйте «rollback = restore snapshot + redeploy previous tag» для тяжёлых миграций.

Sequelize migration в транзакции: DDL в PostgreSQL частично auto-commit — тяжёлые шаги выносите в отдельные файлы и мониторьте pg_stat_activity во время apply.

Если миграция уже тормозит prod

  • pg_stat_activity: какой lock и на какой таблице
  • Отмените необязательный DDL, перенесите в окно
  • CREATE INDEX CONCURRENTLY вместо обычного CREATE INDEX
  • Разбейте одну миграцию на expand (nullable) и contract (NOT NULL) в разных релизах