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

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

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

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

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

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

proto_version

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

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

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

Версия 4, позволяющая параллельно передавать в потоке большие выполняющиеся транзакции, поддерживается только с серверами версии 16 и выше.

publication_names

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

binary

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

messages

Логический параметр, который включает отправку сообщений, написанных функцией pg_logical_emit_message.

streaming

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

two_phase

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

origin

Параметр для отправки изменений по их происхождению. Возможные значения: none, чтобы отправлять только те изменения, для которых не указан источник, или any, чтобы отправлять изменения независимо от их происхождения. Данный параметр можно использовать, чтобы избежать зацикливаний (бесконечной репликации одних и тех же данных) между узлами репликации.

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

Отдельные сообщения протокола рассматриваются в следующих подразделах. Собственно сообщения описаны в Раздел 53.9.

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

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

53.5.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 локально, поэтому никакие дополнительные данные не нужны. Однако для любых других типов перед сообщением Relation будет передаваться сообщение Type, связывающее имя типа с определённым OID. Таким образом, клиент, которому нужно однозначно определять типы столбцов в отношении, должен кешировать содержимое сообщений Type, и в случае обнаружения полученного OID в кеше использовать эту информацию, а в противном случае разрешать его локально.