53.9. Форматы сообщений логической репликации #

В этом разделе подробно описывается формат каждого сообщения логической репликации. Эти сообщения или выдаются через SQL-интерфейс слота репликации или передаются процессом walsender. Когда их передаёт walsender, они помещаются внутрь WAL-сообщений протокола репликации, описанных в Разделе 53.4, и в общем следуют тому же потоку сообщений, что и сообщения физической репликации.

Begin #
Byte1('B')

Указывает, что это начальное сообщение.

Int64 (XLogRecPtr)

Окончательный LSN транзакции.

Int64 (TimestampTz)

Время фиксации транзакции. Значение задаётся в микросекундах, прошедших с начала эпохи PostgreSQL (2000-01-01).

Int32 (TransactionId)

Идентификатор транзакции.

Сообщение #
Byte1('M')

Указывает, что это сообщение логического декодирования.

Int32 (TransactionId)

Идентификатор транзакции (только для транзакций, передаваемых потоками). Это поле присутствует со 2-й версии протокола.

Int8

Флаги; либо 0, если флагов нет, либо 1, если сообщение логического декодирования передано как транзакционное.

Int64 (XLogRecPtr)

LSN сообщения логического декодирования.

String

Префикс сообщения логического декодирования.

Int32

Длина содержимого сообщения.

Byten

Содержание сообщения логического декодирования.

Commit #
Byte1('C')

Указывает, что это сообщение о фиксации.

Int8(0)

Флаги; в настоящее время не используются.

Int64 (XLogRecPtr)

LSN записи фиксации.

Int64 (XLogRecPtr)

Конечный LSN транзакции.

Int64 (TimestampTz)

Время фиксации транзакции. Значение задаётся в микросекундах, прошедших с начала эпохи PostgreSQL (2000-01-01).

Origin #
Byte1('O')

Указывает, что это сообщение об источнике.

Int64 (XLogRecPtr)

LSN записи фиксации на сервере-источнике.

String

Имя источника.

Заметьте, что внутри одной транзакции может быть несколько сообщений Origin.

Relation #
Byte1('R')

Указывает, что это сообщение об отношении.

Int32 (TransactionId)

Идентификатор транзакции (только для транзакций, передаваемых потоками). Это поле присутствует со 2-й версии протокола.

Int32 (Oid)

OID отношения.

String

Пространство имён (пустая строка для pg_catalog).

String

Имя отношения.

Int8

Свойство идентификации реплики для отношения (то же, что и relreplident в pg_class).

Int16

Число столбцов.

Затем для каждого столбца в публикации (за исключением генерируемых) идёт следующий блок сообщения:

Int8

Флаги столбца. В настоящее время это может быть 0 (флагов нет) или 1 (столбец помечается как часть ключа).

String

Имя столбца.

Int32 (Oid)

OID типа данных столбца.

Int32

Модификатор типа столбца (atttypmod).

Тип #
Byte1('Y')

Указывает, что это сообщение о типе.

Int32 (TransactionId)

Идентификатор транзакции (только для транзакций, передаваемых потоками). Это поле присутствует со 2-й версии протокола.

Int32 (Oid)

OID типа данных.

String

Пространство имён (пустая строка для pg_catalog).

String

Имя типа данных.

Insert #
Byte1('I')

Указывает, что это сообщение о добавлении данных.

Int32 (TransactionId)

Идентификатор транзакции (только для транзакций, передаваемых потоками). Это поле присутствует со 2-й версии протокола.

Int32 (Oid)

OID отношения, соответствующий идентификатору в сообщении об отношении.

Byte1('N')

Обозначает следующее сообщение TupleData как содержащее новый кортеж.

TupleData

Блок сообщения TupleData, представляющий содержимое нового кортежа.

Update #
Byte1('U')

Указывает, что это сообщение об изменении данных.

Int32 (TransactionId)

Идентификатор транзакции (только для транзакций, передаваемых потоками). Это поле присутствует со 2-й версии протокола.

Int32 (Oid)

OID отношения, соответствующий идентификатору в сообщении об отношении.

Byte1('K')

Указывает, что следующий блок TupleData содержит ключ. Это поле является необязательным и присутствует, только если изменение затронуло столбцы, являющиеся частью индекса REPLICA IDENTITY.

Byte1('O')

Указывает, что следующий блок TupleData содержит старый кортеж. Это поле является необязательным и присутствует, только если у таблицы, в которой произошло изменение, свойство REPLICA IDENTITY равно FULL.

TupleData

Блок сообщения TupleData, представляющий содержимое старого кортежа или первичного ключа. Присутствует, только если перед ним идёт признак 'O' или 'K'.

Byte1('N')

Обозначает следующее сообщение TupleData как содержащее новый кортеж.

TupleData

Блок сообщения TupleData, представляющий содержимое нового кортежа.

Сообщение Update может содержать либо блок 'K', либо блок 'O', либо ни один из них, но не оба сразу.

Delete #
Byte1('D')

Указывает, что это сообщение об удалении данных.

Int32 (TransactionId)

Идентификатор транзакции (только для транзакций, передаваемых потоками). Это поле присутствует со 2-й версии протокола.

Int32 (Oid)

OID отношения, соответствующий идентификатору в сообщении об отношении.

Byte1('K')

Указывает, что следующий блок TupleData содержит ключ. Это поле присутствует, если таблица, в которой произошло удаление, использует индекс в качестве REPLICA IDENTITY.

Byte1('O')

Указывает, что следующий блок TupleData содержит старый кортеж. Это поле присутствует, если у таблицы, в которой произошло удаление, свойство REPLICA IDENTITY равно FULL.

TupleData

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

Сообщение Delete может содержать либо блок 'K', либо блок 'O', но не оба сразу.

Truncate #
Byte1('T')

Указывает, что это сообщение об усечении отношений.

Int32 (TransactionId)

Идентификатор транзакции (только для транзакций, передаваемых потоками). Это поле присутствует со 2-й версии протокола.

Int32

Число отношений.

Int8

Битовые флаги для TRUNCATE: 1 соответствует указанию CASCADE, 2 — RESTART IDENTITY.

Int32 (Oid)

OID отношения, соответствующий идентификатору в сообщении об отношении. Это поле повторятся для каждого отношения.

Описанные ниже сообщения Stream Start, Stream Stop, Stream Commit и Stream Abort доступны со 2-й версии протокола.

Stream Start #
Byte1('S')

Указывает, что это сообщение о начале потока.

Int32 (TransactionId)

Идентификатор транзакции.

Int8

1 означает, что это первый сегмент потока с этим идентификатором; 0, если это любой другой сегмент.

Stream Stop #
Byte1('E')

Указывает, что это сообщение об окончании потока.

Stream Commit #
Byte1('c')

Указывает, что это сообщение о фиксации транзакции в потоке.

Int32 (TransactionId)

Идентификатор транзакции.

Int8(0)

Флаги; в настоящее время не используются.

Int64 (XLogRecPtr)

LSN записи фиксации.

Int64 (XLogRecPtr)

Конечный LSN транзакции.

Int64 (TimestampTz)

Время фиксации транзакции. Значение задаётся в микросекундах, прошедших с начала эпохи PostgreSQL (2000-01-01).

Stream Abort #
Byte1('A')

Указывает, что это сообщение о прерывании транзакции в потоке.

Int32 (TransactionId)

Идентификатор транзакции.

Int32 (TransactionId)

Идентификатор подтранзакции (для транзакций верхнего уровня совпадает с идентификатором транзакции).

Int64 (XLogRecPtr)

LSN прерывания транзакции. Это поле присутствует с 4-й версии протокола.

Int64 (TimestampTz)

Время прерывания транзакции. Значение задаётся в микросекундах, прошедших с начала эпохи PostgreSQL (2000-01-01). Это поле присутствует с 4-й версии протокола.

Описанные ниже сообщения (Begin Prepare, Prepare, Commit Prepared, Rollback Prepared, Stream Prepare) доступны с 3-й версии протокола.

Begin Prepare #
Byte1('b')

Указывает, что это сообщение о начале подготовленной транзакции.

Int64 (XLogRecPtr)

LSN подготовки транзакции.

Int64 (XLogRecPtr)

Конечный LSN подготовленной транзакции.

Int64 (TimestampTz)

Время подготовки транзакции. Значение задаётся в микросекундах, прошедших с начала эпохи PostgreSQL (2000-01-01).

Int32 (TransactionId)

Идентификатор транзакции.

String

Пользовательский GID подготовленной транзакции.

Prepare #
Byte1('P')

Указывает, что это сообщение о подготовленной транзакции.

Int8(0)

Флаги; в настоящее время не используются.

Int64 (XLogRecPtr)

LSN подготовки транзакции.

Int64 (XLogRecPtr)

Конечный LSN подготовленной транзакции.

Int64 (TimestampTz)

Время подготовки транзакции. Значение задаётся в микросекундах, прошедших с начала эпохи PostgreSQL (2000-01-01).

Int32 (TransactionId)

Идентификатор транзакции.

String

Пользовательский GID подготовленной транзакции.

Commit Prepared #
Byte1('K')

Указывает, что это сообщение о фиксации подготовленной транзакции.

Int8(0)

Флаги; в настоящее время не используются.

Int64 (XLogRecPtr)

LSN фиксации подготовленной транзакции.

Int64 (XLogRecPtr)

Конечный LSN фиксации подготовленной транзакции.

Int64 (TimestampTz)

Время фиксации транзакции. Значение задаётся в микросекундах, прошедших с начала эпохи PostgreSQL (2000-01-01).

Int32 (TransactionId)

Идентификатор транзакции.

String

Пользовательский GID подготовленной транзакции.

Rollback Prepared #
Byte1('r')

Указывает, что это сообщение об откате подготовленной транзакции.

Int8(0)

Флаги; в настоящее время не используются.

Int64 (XLogRecPtr)

Конечный LSN подготовленной транзакции.

Int64 (XLogRecPtr)

Конечный LSN отката подготовленной транзакции.

Int64 (TimestampTz)

Время подготовки транзакции. Значение задаётся в микросекундах, прошедших с начала эпохи PostgreSQL (2000-01-01).

Int64 (TimestampTz)

Время отката транзакции. Значение задаётся в микросекундах, прошедших с начала эпохи PostgreSQL (2000-01-01).

Int32 (TransactionId)

Идентификатор транзакции.

String

Пользовательский GID подготовленной транзакции.

Stream Prepare #
Byte1('p')

Указывает, что это сообщение о подготовленной транзакции, передаваемой в потоке.

Int8(0)

Флаги; в настоящее время не используются.

Int64 (XLogRecPtr)

LSN подготовки транзакции.

Int64 (XLogRecPtr)

Конечный LSN подготовленной транзакции.

Int64 (TimestampTz)

Время подготовки транзакции. Значение задаётся в микросекундах, прошедших с начала эпохи PostgreSQL (2000-01-01).

Int32 (TransactionId)

Идентификатор транзакции.

String

Пользовательский GID подготовленной транзакции.

Описанные выше сообщения имеют следующие общие блоки.

TupleData #
Int16

Число столбцов.

Затем для каждого столбца (за исключением генерируемых) идёт одно из следующих вложенных сообщений:

Byte1('n')

Обозначает данные как значение NULL.

Или

Byte1('u')

Обозначает неизменённое значение TOAST (само значение не передаётся).

Или

Byte1('t')

Обозначает данные как значение в текстовом формате.

Или

Byte1('b')

Обозначает данные как значение в двоичном формате.

Int32

Длина значения столбца.

Byten

Значение столбца в двоичном или текстовом формате, определённом предшествующим байтом формата. Переменная n задаёт длину значения.

53.9. Logical Replication Message Formats #

This section describes the detailed format of each logical replication message. These messages are either returned by the replication slot SQL interface or are sent by a walsender. In the case of a walsender, they are encapsulated inside replication protocol WAL messages as described in Section 53.4, and generally obey the same message flow as physical replication.

Begin #
Byte1('B')

Identifies the message as a begin message.

Int64 (XLogRecPtr)

The final LSN of the transaction.

Int64 (TimestampTz)

Commit timestamp of the transaction. The value is in number of microseconds since PostgreSQL epoch (2000-01-01).

Int32 (TransactionId)

Xid of the transaction.

Message #
Byte1('M')

Identifies the message as a logical decoding message.

Int32 (TransactionId)

Xid of the transaction (only present for streamed transactions). This field is available since protocol version 2.

Int8

Flags; Either 0 for no flags or 1 if the logical decoding message is transactional.

Int64 (XLogRecPtr)

The LSN of the logical decoding message.

String

The prefix of the logical decoding message.

Int32

Length of the content.

Byten

The content of the logical decoding message.

Commit #
Byte1('C')

Identifies the message as a commit message.

Int8(0)

Flags; currently unused.

Int64 (XLogRecPtr)

The LSN of the commit.

Int64 (XLogRecPtr)

The end LSN of the transaction.

Int64 (TimestampTz)

Commit timestamp of the transaction. The value is in number of microseconds since PostgreSQL epoch (2000-01-01).

Origin #
Byte1('O')

Identifies the message as an origin message.

Int64 (XLogRecPtr)

The LSN of the commit on the origin server.

String

Name of the origin.

Note that there can be multiple Origin messages inside a single transaction.

Relation #
Byte1('R')

Identifies the message as a relation message.

Int32 (TransactionId)

Xid of the transaction (only present for streamed transactions). This field is available since protocol version 2.

Int32 (Oid)

OID of the relation.

String

Namespace (empty string for pg_catalog).

String

Relation name.

Int8

Replica identity setting for the relation (same as relreplident in pg_class).

Int16

Number of columns.

Next, the following message part appears for each column included in the publication (except generated columns):

Int8

Flags for the column. Currently can be either 0 for no flags or 1 which marks the column as part of the key.

String

Name of the column.

Int32 (Oid)

OID of the column's data type.

Int32

Type modifier of the column (atttypmod).

Type #
Byte1('Y')

Identifies the message as a type message.

Int32 (TransactionId)

Xid of the transaction (only present for streamed transactions). This field is available since protocol version 2.

Int32 (Oid)

OID of the data type.

String

Namespace (empty string for pg_catalog).

String

Name of the data type.

Insert #
Byte1('I')

Identifies the message as an insert message.

Int32 (TransactionId)

Xid of the transaction (only present for streamed transactions). This field is available since protocol version 2.

Int32 (Oid)

OID of the relation corresponding to the ID in the relation message.

Byte1('N')

Identifies the following TupleData message as a new tuple.

TupleData

TupleData message part representing the contents of new tuple.

Update #
Byte1('U')

Identifies the message as an update message.

Int32 (TransactionId)

Xid of the transaction (only present for streamed transactions). This field is available since protocol version 2.

Int32 (Oid)

OID of the relation corresponding to the ID in the relation message.

Byte1('K')

Identifies the following TupleData submessage as a key. This field is optional and is only present if the update changed data in any of the column(s) that are part of the REPLICA IDENTITY index.

Byte1('O')

Identifies the following TupleData submessage as an old tuple. This field is optional and is only present if table in which the update happened has REPLICA IDENTITY set to FULL.

TupleData

TupleData message part representing the contents of the old tuple or primary key. Only present if the previous 'O' or 'K' part is present.

Byte1('N')

Identifies the following TupleData message as a new tuple.

TupleData

TupleData message part representing the contents of a new tuple.

The Update message may contain either a 'K' message part or an 'O' message part or neither of them, but never both of them.

Delete #
Byte1('D')

Identifies the message as a delete message.

Int32 (TransactionId)

Xid of the transaction (only present for streamed transactions). This field is available since protocol version 2.

Int32 (Oid)

OID of the relation corresponding to the ID in the relation message.

Byte1('K')

Identifies the following TupleData submessage as a key. This field is present if the table in which the delete has happened uses an index as REPLICA IDENTITY.

Byte1('O')

Identifies the following TupleData message as an old tuple. This field is present if the table in which the delete happened has REPLICA IDENTITY set to FULL.

TupleData

TupleData message part representing the contents of the old tuple or primary key, depending on the previous field.

The Delete message may contain either a 'K' message part or an 'O' message part, but never both of them.

Truncate #
Byte1('T')

Identifies the message as a truncate message.

Int32 (TransactionId)

Xid of the transaction (only present for streamed transactions). This field is available since protocol version 2.

Int32

Number of relations

Int8

Option bits for TRUNCATE: 1 for CASCADE, 2 for RESTART IDENTITY

Int32 (Oid)

OID of the relation corresponding to the ID in the relation message. This field is repeated for each relation.

The following messages (Stream Start, Stream Stop, Stream Commit, and Stream Abort) are available since protocol version 2.

Stream Start #
Byte1('S')

Identifies the message as a stream start message.

Int32 (TransactionId)

Xid of the transaction.

Int8

A value of 1 indicates this is the first stream segment for this XID, 0 for any other stream segment.

Stream Stop #
Byte1('E')

Identifies the message as a stream stop message.

Stream Commit #
Byte1('c')

Identifies the message as a stream commit message.

Int32 (TransactionId)

Xid of the transaction.

Int8(0)

Flags; currently unused.

Int64 (XLogRecPtr)

The LSN of the commit.

Int64 (XLogRecPtr)

The end LSN of the transaction.

Int64 (TimestampTz)

Commit timestamp of the transaction. The value is in number of microseconds since PostgreSQL epoch (2000-01-01).

Stream Abort #
Byte1('A')

Identifies the message as a stream abort message.

Int32 (TransactionId)

Xid of the transaction.

Int32 (TransactionId)

Xid of the subtransaction (will be same as xid of the transaction for top-level transactions).

Int64 (XLogRecPtr)

The LSN of the abort. This field is available since protocol version 4.

Int64 (TimestampTz)

Abort timestamp of the transaction. The value is in number of microseconds since PostgreSQL epoch (2000-01-01). This field is available since protocol version 4.

The following messages (Begin Prepare, Prepare, Commit Prepared, Rollback Prepared, Stream Prepare) are available since protocol version 3.

Begin Prepare #
Byte1('b')

Identifies the message as the beginning of a prepared transaction message.

Int64 (XLogRecPtr)

The LSN of the prepare.

Int64 (XLogRecPtr)

The end LSN of the prepared transaction.

Int64 (TimestampTz)

Prepare timestamp of the transaction. The value is in number of microseconds since PostgreSQL epoch (2000-01-01).

Int32 (TransactionId)

Xid of the transaction.

String

The user defined GID of the prepared transaction.

Prepare #
Byte1('P')

Identifies the message as a prepared transaction message.

Int8(0)

Flags; currently unused.

Int64 (XLogRecPtr)

The LSN of the prepare.

Int64 (XLogRecPtr)

The end LSN of the prepared transaction.

Int64 (TimestampTz)

Prepare timestamp of the transaction. The value is in number of microseconds since PostgreSQL epoch (2000-01-01).

Int32 (TransactionId)

Xid of the transaction.

String

The user defined GID of the prepared transaction.

Commit Prepared #
Byte1('K')

Identifies the message as the commit of a prepared transaction message.

Int8(0)

Flags; currently unused.

Int64 (XLogRecPtr)

The LSN of the commit of the prepared transaction.

Int64 (XLogRecPtr)

The end LSN of the commit of the prepared transaction.

Int64 (TimestampTz)

Commit timestamp of the transaction. The value is in number of microseconds since PostgreSQL epoch (2000-01-01).

Int32 (TransactionId)

Xid of the transaction.

String

The user defined GID of the prepared transaction.

Rollback Prepared #
Byte1('r')

Identifies the message as the rollback of a prepared transaction message.

Int8(0)

Flags; currently unused.

Int64 (XLogRecPtr)

The end LSN of the prepared transaction.

Int64 (XLogRecPtr)

The end LSN of the rollback of the prepared transaction.

Int64 (TimestampTz)

Prepare timestamp of the transaction. The value is in number of microseconds since PostgreSQL epoch (2000-01-01).

Int64 (TimestampTz)

Rollback timestamp of the transaction. The value is in number of microseconds since PostgreSQL epoch (2000-01-01).

Int32 (TransactionId)

Xid of the transaction.

String

The user defined GID of the prepared transaction.

Stream Prepare #
Byte1('p')

Identifies the message as a stream prepared transaction message.

Int8(0)

Flags; currently unused.

Int64 (XLogRecPtr)

The LSN of the prepare.

Int64 (XLogRecPtr)

The end LSN of the prepared transaction.

Int64 (TimestampTz)

Prepare timestamp of the transaction. The value is in number of microseconds since PostgreSQL epoch (2000-01-01).

Int32 (TransactionId)

Xid of the transaction.

String

The user defined GID of the prepared transaction.

The following message parts are shared by the above messages.

TupleData #
Int16

Number of columns.

Next, one of the following submessages appears for each column (except generated columns):

Byte1('n')

Identifies the data as NULL value.

Or

Byte1('u')

Identifies unchanged TOASTed value (the actual value is not sent).

Or

Byte1('t')

Identifies the data as text formatted value.

Or

Byte1('b')

Identifies the data as binary formatted value.

Int32

Length of the column value.

Byten

The value of the column, either in binary or in text format. (As specified in the preceding format byte). n is the above length.