Получить доступ

Нужно переименовать колонку name в full_name без простоя при rolling-выкатке. Какая последовательность верна?

MiddleВыкатка и миграции
Ещё спрашивают так:
  • Как переименовать колонку без простоя?
  • Что такое parallel change?
Коротко

Expand–contract в пять шагов: добавить full_name → писать в обе колонки → перелить старые данные порциями → читать из новой → удалить name отдельным поздним релизом.

  • Прямой RENAME мгновенно ломает работающие экземпляры старой версии
  • Бэкфилл — пачками, а не одним UPDATE: длинная транзакция держит блокировки и раздувает таблицу
  • Индексы — CREATE INDEX CONCURRENTLY

А ещё На любом шаге можно остановиться и откатиться

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Почему не RENAME. В момент переименования старые экземпляры продолжают писать в name и падают. Даже если выкатка мгновенная, откат вернёт код, который не знает full_name.

Шаги:

  1. Expand — миграция ADD COLUMN full_name (nullable, без значения по умолчанию, чтобы не переписывать таблицу). Код не меняется.
  2. Двойная запись — релиз кода, который пишет в обе колонки, а читает ещё старую. После выкатки все новые и изменённые строки имеют обе.
  3. Бэкфилл — перенос старых строк порциями: UPDATE ... SET full_name = name WHERE id BETWEEN ... AND full_name IS NULL по несколько тысяч, с паузами. Один большой UPDATE держит блокировки, генерирует огромный WAL и отставание реплик.
  4. Переключение чтения — релиз, который читает full_name (и пишет ещё в обе — на случай отката).
  5. Contract — когда старых версий нигде нет и откат на них не нужен: код перестаёт писать в name, затем отдельной миграцией DROP COLUMN name.

Детали: ограничения (NOT NULL) добавлять после бэкфилла, в PostgreSQL — через CHECK ... NOT VALID и последующий VALIDATE, чтобы не блокировать таблицу; индексы — CONCURRENTLY; инструменты вроде gh-ost или pg-osc для тяжёлых изменений.

Что хотят услышать

  • Почему прямой RENAME ломает rolling-выкатку.
  • Пять шагов expand–contract по порядку.
  • Бэкфилл порциями и неблокирующие индексы.
  • Удаление старого — последним отдельным релизом.

Частые ошибки

  • Делать бэкфилл одним UPDATE на всю таблицу.
  • Удалять старую колонку в том же релизе, где переключили чтение.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓Добавить новую колонку → писать в обе → перелить данные порциями → переключить чтение → дождаться полного раската → удалить старую отдельным релизом
  • ✗Выполнить ALTER TABLE ... RENAME COLUMN и одновременно выкатить новый код
  • ✗Создать вторую таблицу, скопировать данные и переключить приложение на неё одним релизом
  • ✗Переименовать колонку ночью, когда нагрузка минимальна

Что спросят дальше

  • Почему фазу удаления откладывают?
  • Чем помогают Flyway и Liquibase и чего они не решают?

Разбор темы

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем