Выбор ответа Senior Проектирование и нормализация обновлено

ALTER TABLE повесил прод на пустом месте

Вопрос

Миграция ALTER TABLE orders ADD COLUMN note text обычно выполняется мгновенно, но на проде все запросы к orders встали на минуту. Что произошло и что делать?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Миграция ждала ACCESS EXCLUSIVE за долгим запросом, новые встали за ней. Добавление nullable-колонки без значения по умолчанию меняет только каталог и занимает миллисекунды, но требует ACCESS EXCLUSIVE.

Варианты ответа

  1. ADD COLUMN переписывает таблицу целиком, и запросы ждали её
  2. Миграция ждала ACCESS EXCLUSIVE за долгим запросом, новые встали за нейправильный ответ
  3. Автовакуум заблокировал таблицу, его надо отключать на время миграций
  4. PostgreSQL блокирует всю базу на время любого DDL до коммита

Разбор

Добавление nullable-колонки без значения по умолчанию меняет только каталог и занимает миллисекунды, но требует ACCESS EXCLUSIVE. Если в это время идёт долгий SELECT или висит открытая транзакция, миграция ждёт, а все новые запросы к таблице встают в очередь за ней, ведь их блокировки конфликтуют с запрошенной. Так короткий DDL кладёт прод. Защита: SET lock_timeout = '3s' перед DDL и повтор миграции с паузой, плюс statement_timeout для долгих запросов. Автовакуум в обычном режиме уступает DDL (сам прерывается), а блокировка берётся на таблицу, а не на всю базу.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.