52.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 52.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.
- 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
-
ID of the relation.
- String
-
Namespace (empty string for
pg_catalog
). - String
-
Relation name.
- Int8
-
Replica identity setting for the relation (same as
relreplident
inpg_class
). - Int16
-
Number of columns.
Next, the following message part appears for each column:
- 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
-
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
-
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
-
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
-
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 a old tuple. This field is is present if the table in which the delete has 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.
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:
- 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.
- Int32
-
Length of the column value.
-
Byte
n
-
The value of the column, in text format. (A future release might support additional formats.)
n
is the above length.