9.3 9.4 9.5 9.6 10 11 12 13 14 15 Current(16) 17
问题报告 纠错本页面

49.2. 逻辑解码概念 #

49.2.1. 逻辑解码
49.2.2. 复制槽
49.2.3. 输出插件
49.2.4. 导出快照

49.2.1. 逻辑解码 #

逻辑解码是一种将对数据库表的所有持久更改抽取到一种清晰、易于理解的格式 的处理,这种技术允许在不了解数据库内部状态的详细知识的前提下解释该格式。

PostgreSQL中,逻辑解码通过解码 预写式日志的内容来实现,预写式日志描述了存储 层面上的更改,而逻辑解码则会把更改解码成一种应用相关的形式,例如一个元组 流或者 SQL 语句流。

49.2.2. 复制槽 #

在逻辑复制的环境下,一个槽表示一个更改流,这些更改可以在客户机上以它们在原服务器上产生的顺序被重播。每一个流从一个单一数据库中流式传送更改序列。

注意

PostgreSQL也有流复制槽(见第 27.2.5 节),但是它们的使用有所不同。

一个复制槽在一个PostgreSQL集簇的所 有数据库之间具有一个唯一的标识符。槽在使用它们的连接之间保持独立并且 对于崩溃是安全的。

在常规操作中,一个逻辑槽只会把每次更改发出一次。 只有在检查点时才会持久化每一个槽的当前位置,因此如果发生崩溃,槽可能会回到一个较早的 LSN,这会导致服务器重启时再次发送最近的更改。 逻辑解码客户端负责避免多次处理同一消息导致的副作用。 客户端可能会希望在解码时记录它们看到的最新的 LSN,并且跳过任何从该 LSN 解码得到的重复数据或者(使用复制协议时的)请求,而不是让服务器来决定开始点。 复制进度跟踪特性就是为此服务的,请参考复制源头

对于同一个数据库可能会存在多个独立的槽。每一个槽有自己的状态,允许不 同的消费者从该数据库的更改流中的不同点开始接收更改。对于大多数应用, 每一个消费者都将要求一个单独的槽。

逻辑复制槽完全不知道接收者的状态。甚至可能会有多个不同的接收者在不同 时间使用同一个槽,它们将只是从上一个接收者停止消费更改的地方开始得到 更改。但在任一给定时刻,只有一个接收者可以从一个槽中消费更改。

逻辑复制槽也可以在热备库上创建。为了防止 VACUUM从系统目录中删除所需的行, 应在备库上设置hot_standby_feedback。 尽管如此,如果任何所需的行被删除,槽将会失效。 强烈建议在主库和备库之间使用物理槽。否则, hot_standby_feedback将起作用,但仅在连接 存活期间(例如节点重启会中断它)。然后,主库可能会删除 备库逻辑解码所需的系统目录行(因为它不知道备库上的 catalog_xmin)。如果主库上的wal_level 被降低到小于logical,备库上的现有逻辑槽 也会失效。这将在备库检测到WAL流中的此类更改时立即发生。 这意味着,对于滞后的walsenders(如果有),在主库上 wal_level参数更改之前的一些WAL记录将不会被解码。

创建逻辑槽需要有关所有当前运行事务的信息。在主服务器上,这些信息可以直接 获取,但在备用服务器上,这些信息必须从主服务器获取。因此,槽的创建可能需要 等待主服务器上发生一些活动。如果主服务器处于空闲状态,在备用服务器上创建逻 辑槽可能会花费显著的时间。可以通过在主服务器上调用pg_log_standby_snapshot 函数来加速这一过程。

小心

复制槽可以在崩溃时保持,并且不知道其消费者的状态。即便没有连接使用它们, 它们也将阻止移除所需的资源。这会消耗存储,因为只要还有一个复制槽需要, WAL 和来自于系统目录的行就不能被VACUUM移除。在极端情况下这会导致数据库关闭以防止事务ID回卷(见第 25.1.5 节)。因此如果不再需要一个槽,那就应该删除它。

49.2.3. 输出插件 #

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

49.2.4. 导出快照 #

当使用流复制接口创建一个新的复制槽时(参见CREATE_REPLICATION_SLOT), 会导出一个快照(参见第 9.27.5 节), 这将准确显示数据库在创建槽之后的状态,之后所有更改都将包含在更改流中。 这可以用来通过使用SET TRANSACTION SNAPSHOT 来读取创建槽时数据库的状态,从而创建一个新的副本。 然后可以使用该事务来转储数据库在那个时间点的状态,之后可以使用槽的内容更新而不会丢失任何更改。

并非总能够创建快照。特别是在连接到热备时,快照创建将会失败。不要求快照导出的应用可以用NOEXPORT_SNAPSHOT选项来抑制它。 option.