Postgresql 中文操作指南

55.5. Logical Streaming Replication Protocol #

本节介绍逻辑复制协议,该协议是由 START_REPLICATION SLOT slot_name LOGICAL 复制命令启动的消息流。

This section describes the logical replication protocol, which is the message flow started by the START_REPLICATION SLOT slot_name LOGICAL replication command.

逻辑流式复制协议建立在物理流式复制协议的基本原理之上。

The logical streaming replication protocol builds on the primitives of the physical streaming replication protocol.

PostgreSQL 逻辑解码支持输出插件。pgoutput 是用于内置逻辑复制的标准插件。

PostgreSQL logical decoding supports output plugins. pgoutput is the standard one used for the built-in logical replication.

55.5.1. Logical Streaming Replication Parameters #

使用 START_REPLICATION 命令,pgoutput 接受以下选项:

Using the START_REPLICATION command, pgoutput accepts the following options:

  • proto_version

    • Protocol version. Currently versions 1, 2, 3, and 4 are supported. A valid version is required.

    • Version 2 is supported only for server version 14 and above, and it allows streaming of large in-progress transactions.

    • Version 3 is supported only for server version 15 and above, and it allows streaming of two-phase commits.

    • Version 4 is supported only for server version 16 and above, and it allows streams of large in-progress transactions to be applied in parallel.

  • publication_names

    • Comma separated list of publication names for which to subscribe (receive changes). The individual publication names are treated as standard objects names and can be quoted the same as needed. At least one publication name is required.

  • binary

    • Boolean option to use binary transfer mode. Binary mode is faster than the text mode but slightly less robust.

  • messages

    • Boolean option to enable sending the messages that are written by pg_logical_emit_message.

  • streaming

    • Boolean option to enable streaming of in-progress transactions. It accepts an additional value "parallel" to enable sending extra information with some messages to be used for parallelisation. Minimum protocol version 2 is required to turn it on. Minimum protocol version 4 is required for the "parallel" option.

  • two_phase

    • Boolean option to enable two-phase transactions. Minimum protocol version 3 is required to turn it on.

  • origin

    • Option to send changes by their origin. Possible values are "none" to only send the changes that have no origin associated, or "any" to send the changes regardless of their origin. This can be used to avoid loops (infinite replication of the same data) among replication nodes.

55.5.2. Logical Replication Protocol Messages #

下面的子部分将讨论单一协议消息。 Section 55.9中描述了单一消息。

The individual protocol messages are discussed in the following subsections. Individual messages are described in Section 55.9.

所有顶级协议消息均以消息类型字节开头。尽管在代码中表示为字符,但它是一个带符号字节,没有关联的编码。

All top-level protocol messages begin with a message type byte. While represented in code as a character, this is a signed byte with no associated encoding.

由于流复制协议提供了消息长度,因此无需顶级协议消息在它们的标头中嵌入长度。

Since the streaming replication protocol supplies a message length there is no need for top-level protocol messages to embed a length in their header.

55.5.3. Logical Replication Protocol Message Flow #

除了 START_REPLICATION 命令和重播进度消息之外,所有信息都只能从后端流向前端。

With the exception of the START_REPLICATION command and the replay progress messages, all information flows only from the backend to the frontend.

逻辑复制协议将单个事务逐个发送。这意味着在 Begin 和 Commit 消息对之间的所有消息都属于同一事务。类似地,在 Begin Prepare 和 Prepare 消息对之间的所有消息都属于同一事务。它还在 Stream Start 和 Stream Stop 消息对之间发送正在进行的大型事务的更改。此类事务的最后一个流包含 Stream Commit 或 Stream Abort 消息。

The logical replication protocol sends individual transactions one by one. This means that all messages between a pair of Begin and Commit messages belong to the same transaction. Similarly, all messages between a pair of Begin Prepare and Prepare messages belong to the same transaction. It also sends changes of large in-progress transactions between a pair of Stream Start and Stream Stop messages. The last stream of such a transaction contains a Stream Commit or Stream Abort message.

每个已发送的事务都包含零个或多个 DML 消息(插入、更新、删除)。如果是一个级联设置,它还可以包含 Origin 消息。origin 消息指示事务始于不同的复制节点。由于在逻辑复制协议的作用域中复制节点几乎可以是任何内容,因此唯一的标识符是 origin 名称。由下游根据需要(如果需要)处理此项内容。Origin 消息始终在事务中的任何 DML 消息之前发送。

Every sent transaction contains zero or more DML messages (Insert, Update, Delete). In case of a cascaded setup it can also contain Origin messages. The origin message indicates that the transaction originated on different replication node. Since a replication node in the scope of logical replication protocol can be pretty much anything, the only identifier is the origin name. It’s downstream’s responsibility to handle this as needed (if needed). The Origin message is always sent before any DML messages in the transaction.

每个 DML 消息都包含一个关系 OID,用于识别被操作的发布者的关系。对于给定关系 OID 的第一个 DML 消息之前,将发送一个 Relation 消息,描述该关系的架构。随后,如果关系的定义自上次发送给它的 Relation 消息后已更改,将发送一条新的 Relation 消息。(该协议假定客户端有能力记住尽可能多的关系的元数据。)

Every DML message contains a relation OID, identifying the publisher’s relation that was acted on. Before the first DML message for a given relation OID, a Relation message will be sent, describing the schema of that relation. Subsequently, a new Relation message will be sent if the relation’s definition has changed since the last Relation message was sent for it. (The protocol assumes that the client is capable of remembering this metadata for as many relations as needed.)

关系消息通过它们的 OID 标识列类型。在内置类型的情况下,假定客户端可以在本地查找该类型 OID,因此不需要其他数据。对于非内置类型 OID,将在 Relation 消息之前发送 Type 消息,以提供与此 OID 关联的类型名称。因此,需要特别识别关系列类型的客户端应缓存 Type 消息的内容,并首先查询该缓存以查看类型 OID 是否在那里定义。如果没有,则在本地查找类型 OID。

Relation messages identify column types by their OIDs. In the case of a built-in type, it is assumed that the client can look up that type OID locally, so no additional data is needed. For a non-built-in type OID, a Type message will be sent before the Relation message, to provide the type name associated with that OID. Thus, a client that needs to specifically identify the types of relation columns should cache the contents of Type messages, and first consult that cache to see if the type OID is defined there. If not, look up the type OID locally.