Вопрос с собеседования · System design

Как вы спланируете выкатку изменения, затрагивающего и код, и схему базы, чтобы её можно было безопасно откатить?

MiddleВыкатка и миграции
Ещё спрашивают так:
  • Как безопасно выкатить изменение кода и схемы?
  • Как обеспечить возможность отката при миграции базы?
Коротко

Миграция и код — разными релизами; схема меняется через expand–contract; необратимые шаги (удаление колонок, данных) — в самом конце и с задержкой.

  • Пока необратимых шагов нет — быстрый откат; после — только исправление вперёд
  • Флаг на новое поведение — мгновенное выключение без отката
  • Постепенный раскат с метриками по версии и отрепетированный откат

А ещё Миграции — отдельный конвейер с проверкой на копии продовых данных

Подробно

Принцип. Во время выкатки и отката живут обе версии кода, поэтому каждый шаг должен быть совместим с текущей и предыдущей версией.

План:

  1. Расширение схемы — отдельным релизом: новые таблицы и nullable-колонки, индексы CONCURRENTLY. Старый код их не замечает.
  2. Код под флагом — пишет и в старое, и в новое; новое поведение выключено. Выкатка постепенная (canary), метрики по версии.
  3. Бэкфилл — порциями, с контролем нагрузки и отставания реплик.
  4. Включение флагом — постепенно, по процентам; быстрое выключение при проблемах.
  5. Переключение чтения на новое.
  6. Сужение — удаление старого кода, затем, через период наблюдения, удаление старых колонок. Это необратимо — поэтому последним.

Откат: на шагах 1–5 откат кода безопасен — старые данные на месте. После удаления данных остаётся только исправление вперёд (roll-forward). Поэтому необратимые шаги отделяют по времени и делают, когда уверены.

Проверка: прогон миграции на копии продовых данных (время, блокировки), таймауты на миграции (lock_timeout), отрепетированный откат, мониторинг ошибок и задержки в разрезе версии.

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

  • Разделение миграции и кода, совместимость с двумя версиями.
  • Фазы expand–contract с практическими деталями.
  • Обратимые и необратимые шаги, roll-forward.
  • Флаги, постепенный раскат, репетиция отката.

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

  • Удалять старые колонки в том же релизе, что и новый код.
  • Не иметь плана на случай, когда откат кода уже невозможен.

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

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

Показать варианты и ответ
  • ✗Миграцию и код выкатывать одним релизом, чтобы версии не расходились
  • ✓Разные релизы, expand–contract, необратимые шаги в конце
  • ✗Откатывать миграцию down-скриптом, если что-то пошло не так после удаления колонки
  • ✗Остановить сервис на время миграции и выкатить всё ночью, когда пользователей нет, затем включить обратно

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

  • Что делать, если бэкфилл занимает несколько суток?
  • Как понять, что старых версий в проде уже не осталось?

Разбор темы

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

Партнёр платформы

Разбор собеседования с sotto

После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.

Разбор собеседования