Код-ревью Senior Базы данных в эксплуатации обновлено

Код-ревью: миграция на горячей таблице

Вопрос

Миграция применяется на проде к таблице orders (80 млн строк, постоянная запись) во время rolling-деплоя новой версии кода. PostgreSQL 16. Найдите проблемы.

BEGIN;
ALTER TABLE orders ADD COLUMN status text NOT NULL DEFAULT 'new';
CREATE INDEX idx_orders_user ON orders (user_id);
ALTER TABLE orders ALTER COLUMN amount TYPE numeric(12,2);
ALTER TABLE orders RENAME COLUMN comment TO note;
ALTER TABLE orders ADD CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES users (id);
UPDATE orders SET status = 'done' WHERE paid_at IS NOT NULL;
COMMIT;

Коротко

Строка 2 здесь как раз безопасна: с PostgreSQL 11 добавление колонки с константным DEFAULT не переписывает таблицу. Остальное классика опасных миграций.

Что должен найти ревьюер

  1. Ошибкастрока 1
    Всё в одной транзакции: блокировка ACCESS EXCLUSIVE, взятая первым ALTER, держится до COMMIT, то есть на всё время индекса, перезаписи и UPDATE. Таблица недоступна минутами. Разбить на отдельные шаги и задать lock_timeout.
  2. Производительностьстрока 3
    Индекс без CONCURRENTLY блокирует запись на время построения.
  3. Производительностьстрока 4
    Смена типа на numeric(12,2) переписывает всю таблицу под эксклюзивной блокировкой. Через новую колонку и бэкфилл.
  4. Ошибкастрока 5
    Переименование колонки во время rolling: старые поды ещё обращаются к comment и падают. Только expand/contract.
  5. Производительностьстрока 6
    Внешний ключ проверяет все 80 млн строк под блокировкой. Сначала NOT VALID, потом VALIDATE CONSTRAINT.
  6. Производительностьстрока 7
    UPDATE миллионов строк одним запросом: долгие блокировки строк, раздувание таблицы, лаг репликации. Пачками по несколько тысяч.

Разбор

Строка 2 здесь как раз безопасна: с PostgreSQL 11 добавление колонки с константным DEFAULT не переписывает таблицу. Остальное классика опасных миграций. Правильный порядок: короткие отдельные шаги с lock_timeout, индексы конкурентно, ограничения через NOT VALID, переименования и смены типа через новую колонку, бэкфилл пачками отдельной задачей.

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

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

Термины по теме