53.9. Logical Replication Message Formats
Prev | Up | Chapter 53. Frontend/Backend Protocol | Home | Next

## 53.9. Logical Replication Message Formats

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

Begin

  Byte1('B')

    Identifies the message as a begin message.

  Int64

    The final LSN of the transaction.

  Int64

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

  Int32

    Xid of the transaction.

Message

  Byte1('M')

    Identifies the message as a logical decoding message.

  Int32

    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

    The LSN of the logical decoding message.

  String

    The prefix of the logical decoding message.

  Int32

    Length of the content.

  Byte`n`

    The content of the logical decoding message.

Commit

  Byte1('C')

    Identifies the message as a commit message.

  Int8

    Flags; currently unused (must be 0).

  Int64

    The LSN of the commit.

  Int64

    The end LSN of the transaction.

  Int64

    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

    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

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

  Int32

    ID 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 (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

    ID of the column's data type.

  Int32

    Type modifier of the column (`atttypmod`).

Type

  Byte1('Y')

    Identifies the message as a type message.

  Int32

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

  Int32

    ID 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

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

  Int32

    ID 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

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

  Int32

    ID 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

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

  Int32

    ID 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

    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

    ID 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

    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

    Xid of the transaction.

  Int8

    Flags; currently unused (must be 0).

  Int64

    The LSN of the commit.

  Int64

    The end LSN of the transaction.

  Int64

    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

    Xid of the transaction.

  Int32

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

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.

  Byte`n`

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

Prev | Up | Next
53.8. Error and Notice Message Fields | Home | 53.10. Summary of Changes since Protocol 2.0