🛠️ Нужно добавить FOREIGN KEY на большую таблицу. Что проверить до запуска?
Условная миграция: ALTER TABLE orders ADD CONSTRAINT orders_customer_fk FOREIGN KEY (customer_id) REFERENCES customers (id);
На большой таблице риск не только во времени проверки. В PostgreSQL 18 обычный ADD FOREIGN KEY берёт SHARE ROW EXCLUSIVE на обе таблицы. Этот режим конфликтует с обычными операциями записи, поэтому миграция может ждать сама и задерживать INSERT, UPDATE и DELETE.
Для внешнего ключа проверку старых данных можно вынести в отдельный этап: ALTER TABLE orders ADD CONSTRAINT orders_customer_fk FOREIGN KEY (customer_id) REFERENCES customers (id) NOT VALID; Затем: ALTER TABLE orders VALIDATE CONSTRAINT orders_customer_fk;
После первого шага: — новые INSERT и UPDATE уже проверяются; — старые строки ещё не подтверждены полностью; — ограничение остаётся невалидированным.
NOT VALID не означает «без блокировок». Первый этап всё равно меняет схему. В PostgreSQL 18 валидация берёт SHARE UPDATE EXCLUSIVE на orders и ROW SHARE на referenced table. Обычный DML может продолжаться, но проверка читает данные, создаёт нагрузку и может конфликтовать с DDL и maintenance-операциями.
До запуска проверьте: — версию PostgreSQL и особенности partitioned tables; — наличие нарушений; — lock mode каждой фазы; — длинные транзакции; — длительность и нагрузку проверки; — порядок выката приложения; — обработку lock_timeout, отмены и повторного запуска; — способ убедиться, что constraint действительно валидирован.
Важно: lock_timeout только ограничивает ожидание блокировки. Он не гарантирует безопасное завершение миграции.
Вывод: разделение на NOT VALID и VALIDATE CONSTRAINT помогает управлять риском, но не заменяет проверку версии, блокировок, данных и поведения приложения.
🔹🔹🔹🔹