🛠️ Нужно добавить 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 помогает управлять риском, но не заменяет проверку версии, блокировок, данных и поведения приложения.
🔹🔹🔹🔹
Условная миграция:
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 помогает управлять риском, но не заменяет проверку версии, блокировок, данных и поведения приложения.
🔹🔹🔹🔹