Ответ вслух Senior Проектирование и нормализация обновлено

Миграции схемы без простоя

Вопрос

Нужно переименовать колонку orders.sum в amount в базе, с которой работают 10 подов, и без простоя. Как будете делать и какие правила миграций вы соблюдаете вообще?

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

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

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

Коротко

Прямой RENAME COLUMN выполняется мгновенно, но при выкатке поды обновляются по очереди, и старый код ещё обращается к sum, а её уже нет: ошибки до конца деплоя. Поэтому делаю expand и contract.

Что должно прозвучать в ответе

  • Схема меняется в несколько релизов: expand, перенос данных, contract

  • Новый код должен работать со старой и новой схемой одновременно, потому что поды обновляются по очереди

  • Для переименования: добавить колонку, писать в обе, перенести старые данные пачками, переключить чтение, удалить старую

  • Блокировки: `lock_timeout`, индексы `CONCURRENTLY`, ограничения через `NOT VALID` и `VALIDATE`

  • Переносы данных маленькими пачками, а не одним `UPDATE`

  • Каждый шаг обратим и проверен на копии прод-данных

Что могут спросить следом

  • Что сломается, если просто выполнить RENAME COLUMN?
  • Как безопасно добавить внешний ключ?
  • Как вы переносите 100 млн строк?

Разбор

Прямой RENAME COLUMN выполняется мгновенно, но при выкатке поды обновляются по очереди, и старый код ещё обращается к sum, а её уже нет: ошибки до конца деплоя. Поэтому делаю expand и contract. Релиз 1: добавляю amount (мгновенно, nullable), код пишет в обе колонки, читает старую. Затем фоновая задача переносит старые данные пачками по несколько тысяч строк, чтобы не держать долгие блокировки и не раздувать WAL. Релиз 2: код читает amount, всё ещё пишет в обе. Релиз 3: перестаём писать в sum, и только потом удаляю её отдельной миграцией. Общие правила: перед DDL SET lock_timeout, индексы CONCURRENTLY вне транзакции, внешние ключи и CHECK через NOT VALID и VALIDATE CONSTRAINT, никаких долгих транзакций в миграциях, а каждый шаг сначала прогоняется на копии с реальным объёмом.

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

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