NOT NULL на огромной таблице без простоя
Вопрос
Нужно сделать колонку orders.customer_id NOT NULL на таблице в 500 млн строк. ALTER COLUMN ... SET NOT NULL проверяет всю таблицу под ACCESS EXCLUSIVE. Как сделать без долгой блокировки в PostgreSQL 16?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Варианты ответа
- Выполнить
ALTER COLUMN ... SET NOT NULL CONCURRENTLYвне транзакции CHECK (... IS NOT NULL) NOT VALID,VALIDATE, затемSET NOT NULLправильный ответ- Создать уникальный индекс по
customer_id: он запрещает NULL - Обновить все NULL на 0 и сделать
SET NOT NULLв той же транзакции
Разбор
NOT VALID добавляет ограничение мгновенно и проверяет только новые строки. VALIDATE CONSTRAINT проверяет старые под блокировкой SHARE UPDATE EXCLUSIVE, которая не мешает чтению и записи. С PostgreSQL 12 SET NOT NULL не сканирует таблицу, если уже есть валидный CHECK, доказывающий отсутствие NULL, так что ACCESS EXCLUSIVE берётся на мгновение; после этого CHECK можно удалить. У SET NOT NULL нет опции CONCURRENTLY. Уникальный индекс NULL не запрещает (NULL не равны друг другу). Массовый UPDATE в одной транзакции с DDL держит блокировки долго и раздувает таблицу.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Предыдущий вопрос
ALTER TABLE повесил прод на пустом месте
Следующий вопрос
Удаление старых данных: DELETE или партиции
Термины по теме
Ещё по теме «Проектирование и нормализация»
- Нарушение второй нормальной формы
- Транзитивная зависимость
- Денормализация
- Нормализация
- Суррогатный ключ
- Связь многие ко многим
- Тип для денег
- ON DELETE CASCADE