Кратко

  • RFC 2372 советовал создать prepared-recovery record до PREPARED и commit-recovery record до COMMIT в состоянии Prepared, сохраняя каждую запись до точно названного свидетельства разрешения.
  • Этот порядок задавал местное хранение обязательства, но не доказывал запись на устойчивый носитель, переживание сбоя, восстановление правильной идентичности или знание результата приложением.

PREPARED звучит как промежуточное состояние. На деле именно после этого слова участник теряет право самостоятельно отступить при сбое. Координатор мог уже собрать голоса и принять решение о фиксации. Отправляя PREPARED, подчинённая сторона обещала помнить транзакцию даже тогда, когда сокет, процесс или машина перестанут существовать в прежнем виде.

RFC 2372 вышел в июле 1998 года как Informational RFC, а не интернет-стандарт. Он описывал сценарии и требования TIP и прямо называл связь протокольных действий с журналом рекомендательной. Документ не сообщал о продукте, внедрении, движке хранения или испытании аварией. Он формулировал обязанность, которую реальной системе ещё предстояло доказать.

Подчинённая сторона должна была создать prepared-запись до отправки PREPARED и хранить её до ABORT, COMMIT либо QUERIEDNOTFOUND. Пока запись существовала, нельзя было посылать COMMITTED или NOTRECONNECTED. Вышестоящая сторона после получения PREPARED, но до COMMIT в состоянии Prepared, создавала commit-запись и оставляла её до COMMITTED или NOTRECONNECTED.

Это не просто совет журналировать важные события. PREPARED превращал местную свободу в обязанность перед координатором. COMMIT превращал решение в то, что, возможно, придётся повторить после аварии. Удаление записи означало утверждение: предусмотренное свидетельство закрыло долг.

Отрицательный ответ мог подтверждать завершение

После разрыва вышестоящая сторона отправляла RECONNECT с идентификатором подчинённой транзакции, при необходимости извлечённым из журнала. Если подчинённая сторона всё ещё была Prepared, она отвечала RECONNECTED. Если она уже приняла COMMIT, ответила COMMITTED и забыла завершённое состояние, приходил NOTRECONNECTED. В правильной последовательности это «нет» могло быть положительным доказательством завершения.

Подчинённая сторона могла отправить QUERY. QUERIEDEXISTS означал, что координатор всё ещё знает транзакцию и позже переподключится. QUERIEDNOTFOUND разрешал abort: координатор мог отправить ABORT, не получить ABORTED и забыть presumed-abort транзакцию. Отсутствие обретало смысл только вместе с ролью, состоянием, идентификатором и историей сообщений.

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

Разрешения на удаление были асимметричны. Подчинённая сторона ждала решения либо результата запроса, освобождавшего Prepared; вышестоящая — подтверждения участника либо особого случая уже завершившего и забывшего состояние участника. Таймер, перезапуск, нехватка диска или уверенность оператора не заменяли эти сигналы.

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

Между «создать» и «сохранить» находился весь путь записи

Что считалось созданием: буфер процесса, кэш ядра, журнал, физический носитель или копия в другой зоне отказа? Какую долговечность обещало подтверждение хранилища? Могла ли запись разорваться? Находилась ли транзакция без утраченного оперативного индекса? Не опережал ли асинхронный отправитель устойчивую запись?

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

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

Делегирование меняло хранителя, а не отменяло долг

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

Клиент всё равно мог потерять финальный ответ commit и не узнать, что транзакция завершилась. RFC возлагал выяснение исхода на приложение и упоминал реализационно-зависимый пользовательский журнал. Менеджер транзакций мог успешно восстановиться, а инициатор работы — остаться без бизнес-ответа.

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

Два канала требовали дисциплины приложения. TIP мог не видеть запросы приложения в полёте. Нельзя было вызывать commit до их окончания или положительно отвечать партнёру до регистрации транзакции локальным менеджером. Идеальный журнал не исправлял решение над неполным набором деловых операций.

Безопасность защищала край цепочки

Аутентификация и авторизация приложения оставались вне TIP. TLS мог аутентифицировать стороны и шифровать команды, если его согласовали. Это защищало от самозваного менеджера, но не доказывало устойчивость записи, деловое полномочие, изменение ресурса или признание результата.

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

Линза слоёв реальности Heng Lu не позволяет слить запрос, локальное действие, состояние TIP, запись, подтверждение хранилища, сообщение, восстановленную идентичность, ответ партнёра, результат ресурса и знание клиента в слово «зафиксировано». Один слой мог быть известен, а следующий — нет.

Минимальная спецификация оставляла местную проверку

RFC не задавал единый формат журнала, хранилище, API или консоль. Для совместимости были нужны общие команды, роли, идентификаторы и смысл восстановления, а не одна база данных. Через принцип минимальной начальной спецификации Heng Lu будущий выбор оставался у реализации.

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

Современные системы тоже говорят «принято», «реплицировано», «готово», «авторизовано» до сбоя. Каждое слово создаёт ожидание о том, что переживёт аварию. Урок RFC 2372 не в том, что журнал делает слово истинным, а в том, что слово с последствиями после сбоя требует предшествующего, устойчивого и проверяемого доказательства.

Источники