К содержимому
14 авг. 2026 г.·8 мин чтения

План отката должен пережить первую запись

План отката работает, когда права на запись, возврат данных, совместимость, срок работы старой системы и репетиция определены до переключения.

План отката должен пережить первую запись

Плану отката можно доверять, только если старая система принимает записи новой без потерь, дублей и нарушения порядка. Вернуть балансировщик нагрузки легко. Сложности начинаются с первого заказа, платежа, дела, проводки или изменения статуса, записанного после переключения.

Поэтому откат связан с данными и полномочиями, а не с функцией развертывания. До переключения команда должна знать, какая система владеет записью в каждый момент, как поздние изменения вернутся в старую модель, какие внешние последствия нельзя отменить и кто вправе отдать команду на возврат. Если ответы хранятся у кого-то в голове или зависят от кода, который ни разу не запускали, плана отката нет. Остается лишь надежда, что новая система сломается раньше, чем произойдет что-то существенное.

Переключение передает право на запись

При безопасном переключении право на запись в каждый момент принадлежит ровно одной системе. Обе системы могут обслуживать чтение, сравнивать результаты, принимать копии событий или считать в теневом режиме. Они не должны независимо принимать обязательные изменения одной и той же бизнес-записи. Два источника записи создают конфликты, которые нельзя исправить сменой маршрута трафика.

Право на запись не ограничивается главным подключением к базе данных. Старая среда часто принимает изменения через пакетные файлы, очереди сообщений, операторские экраны, задания по расписанию, передачи от партнеров, хранимые процедуры и прямые исправления службы поддержки. Я видел, как команда заморозила веб-приложение, а ночное задание незаметно провело корректировки под другой учетной записью. Миграция выглядела стабильной, пока на следующее утро не разошлись две бухгалтерские книги.

Составляйте реестр записи по бизнес-операциям, а не по таблицам. Для каждой операции укажите точку входа, учетную запись, границу транзакции, созданный идентификатор, источник времени, последующие эффекты и систему, которая владеет операцией до и после переключения. «Обновить клиента» слишком расплывчато. «Изменить почтовый адрес, выпустить уведомление для регулятора и поставить задание на печать в очередь» уже показывает, что должен сохранить откат.

Управлению маршрутом тоже нужен один владелец. DNS плохо подходит для аварийного переключения: резолверы и клиенты хранят запись в кеше дольше, чем предполагают операторы. Лучше управлять маршрутом на шлюзе, прокси, потребителе очереди, брокере подключений или в другой точке, где команда видит активное направление. Запишите текущее значение управляющего параметра и команду для его изменения. Снимок консоли не дает руководителю инцидента воспроизводимого действия.

Опишите состояния полномочий простыми словами: OLD_WRITES, DRAINING, NEW_WRITES и ROLLING_BACK хватит многим системам. В каждом состоянии запись должна быть разрешена известному набору источников. При переходе система обязана отклонить неожиданный источник, а не просто внести его в журнал, потому что найденное после отката предупреждение не отменит транзакцию.

У каждого предварительного условия нужен четкий ответ

Переключение можно начинать, только когда у каждого условия отката есть именованный тест, свежий результат и владелец, способный остановить изменение. Фраза «репликация работает нормально» оставляет место для спора во время инцидента. Тест, который подтверждает, что позиция воспроизведения достигла зафиксированной позиции, вместе с точным запросом и выводом дает команде факт.

Составьте короткий договор о готовности. Это пропуск, а не пожелание:

  • Старая версия читает все изменения схемы, внесенные ради переключения.
  • Старая система развернута, доступна, обновлена и проходит аутентификацию во всех зависимостях.
  • Канал захвата или репликации обработал нагрузку, похожую на промышленную, и не превысил согласованный предел отставания.
  • Все источники записи из реестра подчиняются общему управлению, включая пакетные и операторские пути.
  • Команда восстановила свежую резервную копию в изолированной среде и проверила запуск.

Последний пункт выявляет частую подмену: успешная резервная копия не доказывает успешное восстановление. Зеленый статус задания подтверждает лишь то, что байты куда-то скопированы. Он не подтверждает доступность ключа шифрования, полноту архива, способность движка прочитать его и запуск приложения с этими данными. Приложите к протоколу переключения команду восстановления, длительность, контрольную сумму и результат проверки приложения.

Зафиксируйте контрольную точку данных непосредственно перед передачей права на запись. В PostgreSQL при физической потоковой репликации можно сравнить текущую позицию WAL на основном сервере с позицией воспроизведения на резервном. Руководство PostgreSQL определяет LSN как позицию в журнале предзаписи и указывает, что pg_last_wal_replay_lsn() возвращает последнюю позицию, воспроизведенную во время восстановления. Минимальный набор доказательств выглядит так:

/* On the primary */
SELECT pg_current_wal_lsn();
 pg_current_wal_lsn

 7A3/91F2C6D0
(1 row)

/* On the standby */
SELECT pg_last_wal_replay_lsn();
 pg_last_wal_replay_lsn

 7A3/91F2C6D0
(1 row)

Это пример формы вывода, а не универсальная граница. Равенство в один момент не доказывает обратимость каждой бизнес-записи, а разница в байтах не переводится напрямую во время. Проверка подтверждает один узкий факт: резервный сервер воспроизвел журнал до зафиксированной позиции. Нужны также прикладные счетчики, инварианты и выборочные записи, содержательные для конкретной предметной области.

Старая система остается готовой, пока данные могут вернуться

Старая система должна оставаться готовой к запуску, пока команда не докажет, что она примет все изменения после переключения, либо официально не откажется от отката в пользу исправления вперед. Фиксированное число дней звучит определенно, но не учитывает объем транзакций, отложенные задания, циклы расчетов и изменения схемы. Определите срок по наблюдаемым условиям выхода, а затем добавьте календарный предел для контроля расходов и дежурств.

«Готова» значит способна запуститься под давлением инцидента. У старого приложения есть вычислительные ресурсы, актуальная конфигурация, действующие секреты, доступ к сети, рабочие контракты с зависимостями, запас хранилища, мониторинг и операторы, которые еще умеют им пользоваться. Выключенная виртуальная машина с просроченным сертификатом хранит архив. Для отката она не годится.

Поддерживайте готовность хотя бы один полный бизнес-цикл, способный проявить отложенное поведение. В него могут входить ночное проведение операций, граница выставления счетов, файл от партнера, выходное расписание или закрытие периода. Не копируйте общую норму в семь или тридцать дней. Системе страховых дел с запоздалыми документами и кассовому сервису с ночными расчетами нужны разные окна наблюдения.

Условия выхода должны охватывать поведение и восстановимость. Требуйте, чтобы новая система завершила отложенные задания, сверила внешние подтверждения, соблюдала пределы ошибок и задержек на реальном трафике и создавала поток изменений, доступный старой системе. Также нужен успешный откат на данных, захваченных после имитации переключения. Если команда удаляет обратный путь, вносит разрушительное изменение схемы или допускает истечение контракта со старой зависимостью, запишите точный момент окончания возможности отката.

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

Записи после переключения определяют стратегию

Для каждой записи после переключения нужен один из четырех вариантов: воспроизвести ее в старой системе, сохранить для поздней обработки, компенсировать эффект или признать, что она исключает откат. Общее название «синхронизация данных» скрывает существенные решения. Выбор зависит от бизнес-смысла, особенно от порядка и внешних последствий.

Обратная репликация подходит, когда целевая модель выражает новое изменение, а инструмент сохраняет нужные границы транзакций. Она опасна, если современная система делит одну старую строку на несколько записей, заменяет изменяемый статус событиями, иначе создает идентификаторы или ужесточает проверку. Копирование строк может дать синтаксически верные данные, которые старое приложение поймет неправильно.

Журнал изменений только с добавлением часто проще для анализа. Назначьте каждой принятой команде неизменяемый ID операции, бизнес-ключ, исходную последовательность, версию схемы, автора, время приема, полезную нагрузку и результат. Импортер отката записывает примененный ID, поэтому повторная попытка не повторяет бизнес-действие. Идемпотентность нужна на бизнес-границе: команду «установить адрес X» можно повторить, а для команды «прибавить 10 к балансу» требуются уникальная операция и отклонение дубля.

Двойная запись из кода приложения популярна, потому что кажется мгновенной. Для большинства переключений я ее не советую. Запрос может зафиксироваться в новой базе и завершиться по тайм-ауту до фиксации в старой. Клиент не поймет, что произошло, а системы разойдутся. Обратный порядок меняет только сторону сбоя. Транзакционная исходящая очередь или поток изменений базы связывает захват с основной фиксацией и позволяет отдельному потребителю повторять доставку.

Некоторые записи нельзя автоматически отправлять назад. Если новая система допускает состояние, которое старая схема не выражает, поместите операцию в карантин и покажите счетчик до переключения. То же относится к разным правилам проверки. Не искажайте значение, не выбрасывайте поле и не прячьте новый смысл в старом поле свободного текста только ради нуля в отчете сверки.

Инструкция должна перемещать данные и трафик

Учтите все пути записи
CodeHero одновременно читает все языки в дереве, включая пакетный и прикладной код.

Исполнимая инструкция отката замораживает новые записи, устанавливает окончательную границу, переносит захваченные изменения в старую модель, проверяет бизнес-состояние и лишь потом возвращает трафик. Если вернуть трафик раньше, пользователи создадут новые изменения, пока импортер догоняет поток. Граница начнет двигаться во время инцидента.

Практическая последовательность содержит явные точки остановки и доказательства:

  1. Объявите ROLLING_BACK, отклоните новые изменяющие запросы, приостановите потребителей и запишите время с последним принятым ID операции. Чтение можно продолжить, только если оно не вызывает скрытую запись.
  2. Дождитесь окончания текущих транзакций или прервите их по документированному правилу. Зафиксируйте позицию исходного журнала, смещения очередей и число необработанных элементов журнала.
  3. Примените обратный поток до записанной границы. Остановитесь, если для операции нет преобразования, она нарушает старый инвариант или создает другую внешнюю ссылку.
  4. Выполните сверочные запросы и выборочные бизнес-чтения в старой системе. Проведите синтетическую транзакцию через каждую важную точку входа, но направьте внешние уведомления в контролируемый приемник.
  5. Верните старой системе право на запись, постепенно откройте трафик, возобновите только старые задания и следите за счетчиками дублей, отказов и отставания.

Рядом с каждой командой напишите ожидаемый вывод. 0 rows может означать успех для поиска записей без владельца и катастрофу для подсчета заказов. Укажите нужный смысл. Держите порядок получения учетных данных и согласований рядом с командами, но не вставляйте секреты в инструкцию. Если исполнителю нужно искать путь в хранилище паролей, назовите запись и проверьте доступ на репетиции.

Измеряйте каждый этап отдельно. Общего времени восстановления мало. Команде нужно знать длительность заморозки записи, скорость обработки пикового объема обратным потребителем и проверку, которая занимает большую часть паузы. Если очередь из 500 000 операций воспроизводится дольше допустимого для бизнеса срока, план не работает, даже если малая репетиция прошла. Испытайте ожидаемый максимум с запасом.

Совместимость сохраняет обратный путь

Откат зависит от обратной совместимости баз данных, сообщений, API, файлов и аутентификации. Старый исполняемый файл должен работать с состоянием после переключения. Если миграция удаляет столбец, повторно использует значение перечисления, меняет смысл сообщения или обновляет учетные данные до неподдерживаемого старым клиентом формата, обратный путь может исчезнуть незаметно.

В описании Parallel Change Данило Сато делит несовместимое изменение на расширение, миграцию и сжатие. Эта модель полезна: откат доступен в расширенной фазе, пока работают старые и новые потребители. Проблемы начинаются, когда команда считает сжатие обычной уборкой и удаляет старое поле или точку доступа сразу после стабилизации нового трафика. Сжатие намеренно завершает возможность отката и требует отдельной записи об изменении.

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

Для сообщений тоже нужно правило совместимости. Потребители могут игнорировать незнакомые поля, но должны отклонять новый смысл под старым именем. Сохраняйте прежние типы событий до конца периода готовности или сделайте проверенный преобразователь вниз. Версионируйте его и храните исходную полезную нагрузку, чтобы оператор мог воспроизвести спорное преобразование.

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

Для внешних последствий нужна компенсация

Перенесите базу без копирования
CodeHero заменяет старые слои данных на Postgres без повторения прежней структуры.

Откат не вернет уже доставленное письмо, принятый банком файл, напечатанную этикетку или выполненное партнером распоряжение. Это внешние последствия, и до переключения для каждого нужна отдельная политика. Равенство баз данных их не устраняет.

Назначьте каждому исходящему действию ключ идемпотентности и сохраните подтверждение получателя. Во время отката старая система должна знать, какие действия уже выполнены, чтобы не отправить их повторно. Если получатель поддерживает идемпотентные запросы, используйте тот же ключ. Иначе поставьте перед действием внутренний реестр, который отклоняет вторую отправку.

Компенсация создает новое бизнес-действие, а не удаляет старое. Проведенный платеж может потребовать обратной проводки. Отправленное на склад распоряжение может потребовать отмены, которая тоже способна завершиться ошибкой. Для уведомления клиента может понадобиться исправление, написанное человеком. Запишите, кто разрешает каждую компенсацию, ее срок и действия на случай, если внешняя сторона не может обратить результат.

Задания по расписанию создают менее заметный риск дублей. Когда обе среды готовы к работе, два планировщика могут выбрать одни и те же строки и отправить одинаковое действие. Управление полномочиями должно охватывать задания так же строго, как HTTP-запросы. В обычном режиме неактивный планировщик не должен получать блокировку или промышленные учетные данные. При откате операторы передают блокировку только после остановки нового исполнителя и фиксации последнего завершенного элемента.

Сверяйте последствия по бизнес-идентификатору и подтверждению, а не по глубине локальной очереди. Пустая очередь может означать успешную обработку, сброс всех элементов в непросматриваемое хранилище ошибок или пустой результат фильтра. Полезный отчет объединяет ожидаемые действия, попытки, ответы получателя и компенсации в одной строке для каждого бизнес-события.

Репетиция должна вызвать неприятный сбой

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

Используйте похожую на промышленную копию или изолированную среду воспроизведения с очищенными записями и сохраненным трафиком. Запустите старую и новую версии, включите настоящее управление полномочиями и загрузите достаточно истории для правдоподобной работы миграций и индексов. При переписывании старых систем CodeHero проверяет равенство поведения на записанном промышленном трафике. Тот же набор трафика помогает выявить различия до репетиции отката.

Затем вызовите сбой после того, как новая система примет смешанный набор операций. Включите обновление, пришедшее дважды, две последовательные команды для одного счета, границу пакета, отклоненное значение, операцию с внешним эффектом в приемнике и задание, работавшее во время заморозки. Остановите обратного потребителя посередине и запустите снова. ID операций должны предотвратить дубли, а граница должна остаться неподвижной.

Один знакомый сбой заслуживает особого внимания. Обратный импортер сообщает об отсутствии очереди, трафик возвращается в старую систему, а простые счетчики совпадают. Через несколько часов партнер отклоняет дневной файл: современная система создала идентификаторы в формате, который старый экспорт обрезает. Откат правильно переместил строки, но потерял поведение на границе файла. Полная репетиция запускает экспорт, разбирает его по контракту получателя и сравнивает идентификаторы от начала до конца.

Соберите доказательства, которые оценит человек, не писавший миграцию: принятые ID операций, исходные и примененные позиции, результаты запросов инвариантов, число дублей, преобразования в карантине, записи реестра внешних эффектов, длительность этапов и итоговое состояние полномочий. Сохраните и неудачную репетицию. Если план проходит только после ручного исправления данных инженером, внесите исправление как управляемый шаг или устраните его изменением кода.

Наблюдение должно показывать бизнес-корректность

Используйте реальный трафик как доказательство
Записанные промышленные запросы дают стенду паритета конкретное поведение для сравнения.

Сигналы отката должны сообщать о бизнес-корректности, а не только о работающих процессах. Новый сервис может быстро отвечать, но создавать повторные номера счетов, пропускать правило проводки или навсегда оставлять экспорт в очереди. Инфраструктурные графики помогают найти неисправность, но редко говорят ответственному лицу, безопасно ли продолжать запись.

До переключения определите инварианты из поведения старой системы. Инвариант может требовать одну проводку для каждого принятого платежа, ссылку на принятый заказ для каждой отправки, причину закрытия для каждого закрытого дела или соответствующую контрольную сумму для каждого исходящего файла. Выразите каждый инвариант запросом или отчетом, который создают обе системы. При разных схемах сравнивайте каноническую бизнес-проекцию, а не добивайтесь буквального равенства таблиц.

Проекция должна нормализовать различия, которые не меняют поведение, и сохранять значимые. Перевести отметки времени в один часовой пояс перед сравнением разумно. Игнорировать копейки из-за того, что одна система хранит десятичные значения, а другая целые минимальные единицы, нельзя. Согласуйте правила с владельцами бизнес-записи и версионируйте вместе с кодом миграции. Иначе инженер сможет превратить красное сравнение в зеленое, расширив фильтр во время инцидента.

Счетчикам нужны знаменатели и границы. Фраза «двенадцать расхождений» мало говорит без числа проверенных записей, типов операций и интервала приема. Нулевой результат тоже обманывает, если задача сравнения остановилась на вчерашнем разделе. В каждом результате укажите исходную и целевую границы, число выбранных и сравненных записей, расхождения, самую старую операцию без пары и время завершения.

Используйте сигналы свежести, которые следуют настоящему пути воспроизведения. Общая глубина очереди скрывает застрявший раздел, если остальные продолжают опустошаться. Живой потребитель скрывает поврежденное сообщение, которое повторяется бесконечно. Показывайте самую старую непримененную операцию и ее возраст, последнюю замеченную исходную последовательность, последнюю зафиксированную целевую последовательность, число элементов в карантине, повторы по операциям и скорость опустошения. Стабильное отставание при постоянном трафике может быть нормальным в обычной работе, но губительным для отката, где во время заморозки нужен ноль.

Выборочная проверка по-прежнему нужна, потому что инварианты не охватят все странные старые правила. Отбирайте записи по детерминированным условиям, чтобы репетиция и промышленное переключение проверяли сравнимые случаи: самые крупные транзакции, записи с полями максимальной длины, повторно открытые дела, отмененные платежи, нестандартные валюты и операции на границе даты. Проверяйте бизнес-результат и выходной документ, а не только сохраненную строку. Счет может сходиться в базе, но печататься без налогового номера, и это различие в поведении.

Предупреждения должны прямо соответствовать заранее принятым решениям. Нарушение инварианта может немедленно остановить запись. Растущий возраст воспроизведения может запустить таймер. Краткий скачок задержки может потребовать наблюдения без отката. Запишите соответствие до переключения и приложите к предупреждению. Во время инцидента сигнал «миграция нездорова» лишь запускает спор о значении слова «нездорова».

Сохраните телеметрию после окончания периода готовности. Она объяснит, почему команда закрыла обратный путь, и даст исправлению вперед надежную базу. Итоговый протокол должен показать завершение отложенной работы, прохождение границ сравнения за согласованный бизнес-цикл, разрешение карантина и отсутствие необъясненных внешних последствий. Это убедительнее протокола встречи со словами «миграция выглядела нормально».

Сделайте задачу сравнения независимой от проверяемого маршрута. Если подключение к базе, кеш или код сериализации нового приложения обслуживает и проверяющий процесс, одна ошибка может испортить результат вместе с предполагаемой проверкой. Запускайте важные сверки через отдельно развернутый модуль чтения с ограниченными правами и сохраняйте текст запроса с контрольной суммой результата. Независимость не требует второй платформы, но требует пути отказа, который не может молча согласиться сам с собой.

Проверяйте отсутствие телеметрии как отдельный сбой. Остановите потребителя журнала, задержите один исходный раздел и заставьте приемник внешних эффектов отклонить подтверждение. Панель должна показать стареющую границу и незавершенное сравнение, а управление полномочиями не должно позволить объявить успех. Если пустая панель выглядит как ноль расхождений, исправьте ее до переключения.

Для решения об откате нужны часы

Решение об откате должно следовать заранее объявленным условиям, владельцу и временному бюджету. Без них инженеры тратят обратимое окно на диагностику, пока накапливаются новые записи и распространяются внешние последствия. Когда руководство просит вернуться, воспроизведение может занять больше времени, чем исправление вперед.

Выберите условия, описывающие вред пользователям или учету: отклонение критических операций, нарушение инвариантов, необъяснимое расхождение сверки, неограниченный рост очереди, отсутствие внешних подтверждений или невозможность закрыть обязательный пакет. Загрузка процессора и задержки дополняют решение, но одни инфраструктурные симптомы редко показывают сохранность данных. Укажите период наблюдения и источник каждого сигнала.

Дайте одному человеку право приказать откат и назначьте заместителя. Руководители базы данных, приложения, эксплуатации, бизнеса и инцидента могут советовать, но согласование идет слишком медленно при непрерывной записи. Также назначьте человека, который вправе объявить откат недоступным после разрушительной границы. Такое объявление должно переключить план на исправление вперед и компенсацию, а не оставлять команду обсуждать исчезнувший вариант.

У часов есть две границы. Срок решения определяет, сколько команда может исследовать сбой до заморозки записи или выбора исправления вперед. Бюджет исполнения определяет допустимую для бизнеса длительность паузы и воспроизведения. Рассчитайте оба значения по скорости поступления транзакций, скорости обработки очереди, внешним срокам и числу дежурных, затем проверьте предположения на репетиции.

Готовая к переключению команда может передать инструкцию оператору, который ее не писал, вызвать сбой после настоящих записей и восстановить старую систему в пределах бюджета. Если для упражнения нужен незаписанный запрос, конкретный инженер или ручное исправление данных, отложите переключение. В промышленной среде эти зависимости не станут удобнее.

Вопросы

Что должен включать план отката при переключении системы?

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

Как долго старая система должна быть доступна после миграции?

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

Можно ли откатиться, просто вернув трафик в старое приложение?

Только если новая система не приняла существенных записей. После первой записи нужно заморозить работу, воспроизвести или компенсировать поздние изменения, проверить старое состояние и лишь затем перенаправить трафик.

Безопасна ли двойная запись для отката базы данных?

Обычно нет, если прикладной код независимо пишет в две базы. Одна фиксация может пройти, пока другая завершится по тайм-ауту, поэтому связывайте захват с основной транзакцией и используйте идемпотентного потребителя доставки.

Что происходит с транзакциями, созданными после переключения?

Каждую транзакцию нужно воспроизвести в старой модели, сохранить до поздней обработки, компенсировать или признать несовместимой с откатом. Принимайте решение по бизнес-операции и сохраняйте порядок, идентификаторы и внешние подтверждения.

Как проверить, что откат действительно работает?

Дайте новой системе принять представительные записи, вызовите сбой, остановите и перезапустите канал воспроизведения, затем восстановитесь через промышленные средства управления. Сверяйте бизнес-инварианты и внешние эффекты, а не только число строк.

Когда изменение схемы делает откат невозможным?

Откат заканчивается, когда старая версия больше не может безопасно читать или обновлять активную схему либо у новых данных нет точного старого представления. Считайте удаление совместимости отдельной фазой с явным согласованием.

Должны ли старая и новая системы одновременно принимать запись?

Нет. Передайте право на запись одной системе, а остальные пути должны отклонять изменения или принимать их только как необязательную теневую работу. Независимые источники создают конфликты, которые маршрутизация не исправит.

Кто должен решать, когда запускать откат?

До переключения назначьте одного владельца решения и заместителя. Дайте им условия вреда пользователям, срок диагностики и бюджет исполнения, чтобы решение не зависело от аварийного согласования.

Что делать, если внешний эффект нельзя отменить при откате?

Запишите действие и подтверждение, не допускайте повторной отправки и определите компенсирующую бизнес-операцию, если она возможна. Если получатель не умеет отменять действие, в инструкции должны быть ответственный человек и ручной путь разрешения.