Перейти к основному содержимому

Протокол логической потоковой репликации

В этом разделе описывается логический протокол репликации, который представляет собой поток сообщений, запускаемый командой репликации START_REPLICATION SLOT имя_слота LOGICAL.

Протокол логической потоковой репликации основан на примитивах протокола физической потоковой репликации.

В логическом декодировании PostgreSQL поддерживаются модули вывода. Стандартный модуль pgoutput используется для встроенной логической репликации.

Параметры логической потоковой репликации

Используя команду START_REPLICATION, модуль pgoutput принимает следующие параметры:

proto_version

Версия протокола. В настоящее время поддерживаются версии 1, 2 и 3.

Версия 2 поддерживается только для сервера версии 14 и выше и позволяет передавать большие транзакции в потоковом режиме.

Версия 3 поддерживается только для сервера версии 15 и выше и позволяет передавать потоковые двухфазные коммиты.

publication_names

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

binary

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

messages

Булева опция, разрешающая отправку сообщений, которые пишет pg_logical_emit_message.

streaming

Булева опция для включения потоковой передачи выполняющихся транзакций. Для включения требуется минимальная версия протокола 2.

two_phase

Булева опция для включения двухфазных транзакций. Для включения требуется минимальная версия протокола 3.

Сообщения протокола логической репликации

Отдельные сообщения протокола рассматриваются в следующих подразделах. Описание отдельных сообщений приведено в разделе «Форматы сообщений логической репликации».

Все сообщения протокола верхнего уровня начинаются с байта типа сообщения. Хотя в коде он представлен в виде символа, это подписанный байт без соответствующей кодировки.

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

Поток сообщений протокола логической репликации

За исключением команды START_REPLICATION и сообщений о ходе воспроизведения, вся информация поступает только из бэкенда во фронтенд.

Протокол логической репликации отправляет отдельные транзакции по одной. Это означает, что все сообщения между парой сообщений Begin и Commit принадлежат одной транзакции. Аналогично, все сообщения между парой сообщений Begin Prepare и Prepare принадлежат одной транзакции. Кроме того, между парой сообщений Stream Start и Stream Stop отправляются изменения больших незавершенных транзакций. Последний поток такой транзакции содержит сообщение Stream Commit или Stream Abort.

Каждая отправленная транзакция содержит ноль или более сообщений DML (Insert, Update, Delete). В случае каскадной установки она также может содержать сообщения Origin. Сообщение происхождения указывает, что транзакция созданные на разных узлах репликации. Поскольку узел репликации в рамках логического протокола репликации может быть практически любым, единственным идентификатором является имя источника. Ответственность за обработку этого имени лежит на нисходящем потоке (если это необходимо). Сообщение Origin всегда отправляется перед любыми сообщениями DML в транзакции.

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

Сообщения Relation идентифицируют типы столбцов по их OID. В случае встроенного типа предполагается, что клиент может найти OID этого типа локально, поэтому дополнительные данные не требуются. Для OID не встроенного типа перед сообщением Relation будет отправлено сообщение Type, чтобы предоставить имя типа, связанное с этим OID. Таким образом, клиент, которому необходимо определить типы столбцов отношения, должен кэшировать содержимое сообщений Type и сначала обратиться к этому кэшу, чтобы посмотреть, определен ли там OID типа. Если нет, найдите OID типа локально.