受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

47.2. 逻辑解码概念 #

47.2.1. 逻辑解码 #

逻辑解码是将数据库表上的所有持久更改提取为一种连贯、易于理解的格式的过 程,这种格式无需详细了解数据库内部状态就能解释。

PostgreSQL 中,逻辑解码通过解码 预写式日志的内容来实现。预写式日志描述的是存 储层面的更改,而逻辑解码会将其转换成应用程序特定的形式,例如元组流或 SQL 语句流。

47.2.2. 复制槽 #

在逻辑复制的上下文中,一个槽表示一个更改流,客户端可以按照这些更改在源服 务器上发生的顺序来重放它们。每个槽都从单个数据库流式传送一系列更改。

Note

PostgreSQL 也有流复制槽(见 Section 26.2.5),但它们在那里的使用方式略有不 同。

复制槽在整个 PostgreSQL 集簇的所有数据库中都 有唯一标识符。槽独立于使用它们的连接而持久存在,并且具备崩溃安全性。

逻辑槽在正常运行时会让每个更改只发送一次。每个槽的当前位置只会在检查点 时持久化,因此在发生崩溃时,该槽可能会回退到较早的 LSN,这会导致服务器 重启后最近的更改再次被发送。逻辑解码客户端有责任避免多次处理同一消息带 来的不良影响。客户端可能希望记录解码时见到的最后一个 LSN,并跳过任何重 复数据;或者(在使用复制协议时)请求从该 LSN 开始解码,而不是让服务器自 行决定起始点。复制进度跟踪功能正是为此设计的,参见 复制源

对于同一个数据库,可以存在多个彼此独立的槽。每个槽都有自己的状态,允许不 同的消费者从数据库更改流中的不同位置接收更改。对于大多数应用,每个消费 者都需要一个单独的槽。

逻辑复制槽并不了解接收端的状态。甚至可以让多个不同的接收端在不同时间使用 同一个槽;它们只会从前一个接收端停止消费更改的位置之后继续获得更改。但 在任意给定时刻,只允许一个接收端从某个槽中消费更改。

Caution

复制槽可跨崩溃持久存在,而且不了解其消费者的状态。即使没有连接使用它们, 它们也会阻止所需资源被移除。这会消耗存储,因为只要复制槽仍然需要, VACUUM 就不能移除所需的 WAL 和系统目录中的相关行。在 极端情况下,这可能会导致数据库关闭,以防止事务 ID 回卷(见 Section 24.1.5)。因此,如果槽已经不再需要,就 应当将其删除。

47.2.3. 输出插件 #

输出插件把预写式日志内部表示的数据转换成复制槽消费者所需的格式。

47.2.4. 导出快照 #

当使用流复制接口创建新的复制槽时(见 CREATE_REPLICATION_SLOT),会导出 一个快照(见 Section 9.27.5), 它准确反映了数据库的这样一种状态:从该状态之后开始,所有更改都会被纳入 更改流。这可以通过使用 SET TRANSACTION SNAPSHOT 读取创建槽那一刻的数据库状态,据此创建一个新 副本。随后,该事务就可以用来转储该时刻的数据库状态,之后再利用该槽的内 容进行更新,而不会丢失任何更改。

不需要导出快照的应用程序可以使用 NOEXPORT_SNAPSHOT 选项来禁止导出。

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。