Migration Safety Auditor
Аудитор безопасности миграций БД перед прод-деплоем. Цель — поймать операции, которые
блокируют таблицу под нагрузкой, ломают работающий код при rolling-деплое, теряют данные
или необратимы. По итогу — отчёт с уровнями риска и (по согласованию) безопасные правки.
Когда применять
Запускай перед применением миграций на проде, при ревью PR с новой миграцией, при добавлении
колонок/индексов/constraint/FK на непустой таблице, при написании data-миграций и backfill.
Для общего аудита Django см. django-audit; этот навык — только про миграции.
Контекст — установить ПЕРВЫМ делом
Без него оценка риска бессмысленна. Если не ясно из проекта — спроси кратко:
- ORM/инструмент: Django migrations или Alembic/SQLAlchemy. (raw SQL — см. справочник Postgres.)
- СУБД: Postgres или SQLite. Версия Postgres важна (часть операций безопасна с PG 11/12+).
- Модель деплоя: короткий downtime (стоп → миграция → старт) или zero-downtime/rolling
(старый и новый код работают одновременно). От этого зависит строгость к обратной
совместимости схемы. См. references/deploy-models.md.
- Размер затрагиваемых таблиц: операция, безопасная на 1k строк, кладёт прод на 50M.
Процесс
- Собрать миграции на ревью. Django: неприменённые файлы в
*/migrations/,
python manage.py makemigrations --check --dry-run, при сомнениях sqlmigrate app NNNN
для просмотра реального SQL. Alembic: новые ревизии в versions/, alembic upgrade --sql
для offline-SQL.
- Прогнать каждую операцию по чеклисту рисков (ниже + справочники).
- Классифицировать по уровню риска, объяснить почему опасно именно при его модели деплоя.
- Предложить безопасную альтернативу (expand/contract, CONCURRENTLY, батчи, таймауты).
- Отчёт по references/report-template.md. По согласованию —
переписать миграции.
Уровни риска
- CRITICAL — гарантированный простой, потеря данных или необратимая операция на проде
(table rewrite/долгий ACCESS EXCLUSIVE на большой таблице,
DROP COLUMN с данными, backfill
всей таблицы одной транзакцией).
- HIGH — блокировка записи под нагрузкой или поломка старого кода при zero-downtime
(индекс без
CONCURRENTLY, RENAME, новый NOT NULL/UNIQUE/FK без двухфазного приёма).
- MEDIUM — нет
lock_timeout/statement_timeout, нет обратной операции
(RunPython без reverse, пустой downgrade()), схема и данные смешаны в одной миграции.
- LOW — стиль, именование, незначительные улучшения.
Быстрый чеклист (детали — в справочниках)
ADD COLUMN с volatile/вычисляемым DEFAULT или новый NOT NULL на непустой таблице → rewrite.
CREATE INDEX без CONCURRENTLY → блокирует запись на время построения.
ALTER COLUMN TYPE → почти всегда rewrite + ACCESS EXCLUSIVE.
- Добавление
FOREIGN KEY/UNIQUE/NOT NULL одним шагом → используй NOT VALID → VALIDATE.
RENAME колонки/таблицы → ломает работающий старый код; для zero-downtime — expand/contract.
DROP COLUMN/DROP TABLE → потеря данных + ломает старый код; только в contract-фазе.
- Backfill/
UPDATE всей таблицы в одной транзакции → длинные локи, раздувание WAL, реплаг.
- Нет
lock_timeout перед DDL → миграция ждёт лок и выстраивает очередь ко всей таблице.
- Нет обратной операции → миграцию нельзя откатить при инциденте.
Справочники
- references/postgres-operations.md — таблица «операция →
блокировка → безопасная альтернатива», expand/contract, backfill, таймауты.
- references/django.md — Django:
atomic=False, AddIndexConcurrently,
RunPython/reverse, SeparateDatabaseAndState, squash, SQLite-нюансы.
- references/alembic.md — Alembic: ловушки
autogenerate,
batch_alter_table для SQLite, autocommit_block, реальный downgrade().
- references/deploy-models.md — downtime vs zero-downtime,
expand/contract пошагово, SQLite и переезд на Postgres.
- references/report-template.md — формат отчёта.
1---2name: migration-safety-auditor3description: Миграция БД перед прод-деплоем: заблокирует ли таблицу, уронит ли прод, переживёт ли старый код новую схему. Django migrations и Alembic, Postgres и SQLite — блокировки, downtime, потеря данных, опасный backfill, необратимые операции, expand/contract. Используй когда пользователь спрашивает «безопасна ли миграция», «не уронит ли прод», «мне с сервера сделать commit или merge миграции», добавляет колонку, индекс или constraint на большой таблице, пишет data-миграцию, или упоминает CONCURRENTLY, RunPython, zero-downtime. Подобрать сам индекс под запрос — postgres-performance.4---56# Migration Safety Auditor78Аудитор безопасности миграций БД перед прод-деплоем. Цель — поймать операции, которые9блокируют таблицу под нагрузкой, ломают работающий код при rolling-деплое, теряют данные10или необратимы. По итогу — отчёт с уровнями риска и (по согласованию) безопасные правки.1112## Когда применять1314Запускай перед применением миграций на проде, при ревью PR с новой миграцией, при добавлении15колонок/индексов/constraint/FK на непустой таблице, при написании data-миграций и backfill.16Для общего аудита Django см. `django-audit`; этот навык — только про миграции.1718## Контекст — установить ПЕРВЫМ делом1920Без него оценка риска бессмысленна. Если не ясно из проекта — спроси кратко:21221. **ORM/инструмент**: Django migrations или Alembic/SQLAlchemy. (raw SQL — см. справочник Postgres.)232. **СУБД**: Postgres или SQLite. Версия Postgres важна (часть операций безопасна с PG 11/12+).243. **Модель деплоя**: короткий downtime (стоп → миграция → старт) или zero-downtime/rolling25 (старый и новый код работают одновременно). От этого зависит строгость к обратной26 совместимости схемы. См. [references/deploy-models.md](references/deploy-models.md).274. **Размер затрагиваемых таблиц**: операция, безопасная на 1k строк, кладёт прод на 50M.2829## Процесс30311. **Собрать миграции на ревью.** Django: неприменённые файлы в `*/migrations/`,32 `python manage.py makemigrations --check --dry-run`, при сомнениях `sqlmigrate app NNNN`33 для просмотра реального SQL. Alembic: новые ревизии в `versions/`, `alembic upgrade --sql`34 для offline-SQL.352. **Прогнать каждую операцию по чеклисту рисков** (ниже + справочники).363. **Классифицировать** по уровню риска, объяснить *почему* опасно именно при его модели деплоя.374. **Предложить безопасную альтернативу** (expand/contract, CONCURRENTLY, батчи, таймауты).385. **Отчёт** по [references/report-template.md](references/report-template.md). По согласованию —39 переписать миграции.4041## Уровни риска4243- **CRITICAL** — гарантированный простой, потеря данных или необратимая операция на проде44 (table rewrite/долгий ACCESS EXCLUSIVE на большой таблице, `DROP COLUMN` с данными, backfill45 всей таблицы одной транзакцией).46- **HIGH** — блокировка записи под нагрузкой или поломка старого кода при zero-downtime47 (индекс без `CONCURRENTLY`, `RENAME`, новый `NOT NULL`/`UNIQUE`/FK без двухфазного приёма).48- **MEDIUM** — нет `lock_timeout`/`statement_timeout`, нет обратной операции49 (`RunPython` без reverse, пустой `downgrade()`), схема и данные смешаны в одной миграции.50- **LOW** — стиль, именование, незначительные улучшения.5152## Быстрый чеклист (детали — в справочниках)5354- `ADD COLUMN` с volatile/вычисляемым `DEFAULT` или новый `NOT NULL` на непустой таблице → rewrite.55- `CREATE INDEX` без `CONCURRENTLY` → блокирует запись на время построения.56- `ALTER COLUMN TYPE` → почти всегда rewrite + `ACCESS EXCLUSIVE`.57- Добавление `FOREIGN KEY`/`UNIQUE`/`NOT NULL` одним шагом → используй `NOT VALID` → `VALIDATE`.58- `RENAME` колонки/таблицы → ломает работающий старый код; для zero-downtime — expand/contract.59- `DROP COLUMN`/`DROP TABLE` → потеря данных + ломает старый код; только в contract-фазе.60- Backfill/`UPDATE` всей таблицы в одной транзакции → длинные локи, раздувание WAL, реплаг.61- Нет `lock_timeout` перед DDL → миграция ждёт лок и выстраивает очередь ко всей таблице.62- Нет обратной операции → миграцию нельзя откатить при инциденте.6364## Справочники6566- [references/postgres-operations.md](references/postgres-operations.md) — таблица «операция →67 блокировка → безопасная альтернатива», expand/contract, backfill, таймауты.68- [references/django.md](references/django.md) — Django: `atomic=False`, `AddIndexConcurrently`,69 `RunPython`/reverse, `SeparateDatabaseAndState`, squash, SQLite-нюансы.70- [references/alembic.md](references/alembic.md) — Alembic: ловушки `autogenerate`,71 `batch_alter_table` для SQLite, `autocommit_block`, реальный `downgrade()`.72- [references/deploy-models.md](references/deploy-models.md) — downtime vs zero-downtime,73 expand/contract пошагово, SQLite и переезд на Postgres.74- [references/report-template.md](references/report-template.md) — формат отчёта.