逻辑解码是一种将对数据库表的所有持久更改抽取到一种清晰、易于理解的格式 的处理,这种技术允许在不了解数据库内部状态的详细知识的前提下解释该格式。
在PostgreSQL中,逻辑解码通过解码 预写式日志的内容来实现,预写式日志描述了存储 层面上的更改,而逻辑解码则会把更改解码成一种应用相关的形式,例如一个元组 流或者 SQL 语句流。
在逻辑复制的环境下,一个槽表示一个更改流,这些更改可以在客户机上以它们在原服务器上产生的顺序被重播。每一个流从一个单一数据库中流式传送更改序列。
PostgreSQL也有流复制槽(见Section 26.2.5),但是它们的使用有所不同。
一个复制槽在一个PostgreSQL集簇的所 有数据库之间具有一个唯一的标识符。槽在使用它们的连接之间保持独立并且 对于崩溃是安全的。
在常规操作中,一个逻辑槽只会把每次更改发出一次。 只有在检查点时才会持久化每一个槽的当前位置,因此如果发生崩溃,槽可能会回到一个较早的 LSN,这会导致服务器重启时再次发送最近的更改。 逻辑解码客户端负责避免多次处理同一消息导致的副作用。 客户端可能会希望在解码时记录它们看到的最新的 LSN,并且跳过任何从该 LSN 解码得到的重复数据或者(使用复制协议时的)请求,而不是让服务器来决定开始点。 复制进度跟踪特性就是为此服务的,请参考复制源头。
对于同一个数据库可能会存在多个独立的槽。每一个槽有自己的状态,允许不 同的消费者从该数据库的更改流中的不同点开始接收更改。对于大多数应用, 每一个消费者都将要求一个单独的槽。
逻辑复制槽完全不知道接收者的状态。甚至可能会有多个不同的接收者在不同 时间使用同一个槽,它们将只是从上一个接收者停止消费更改的地方开始得到 更改。但在任一给定时刻,只有一个接收者可以从一个槽中消费更改。
逻辑复制槽也可以在热备机上创建。为了防止VACUUM
从系统目录中删除所需的行,
应该在备机上设置hot_standby_feedback
。尽管如此,如果任何所需的行被删除,
该槽将失效。强烈建议在主机和备机之间使用物理槽。否则,hot_standby_feedback
只在连接存活期间有效(例如节点重启会导致其失效)。然后,主机可能会删除备机逻辑解码
可能需要的系统目录行(因为它不知道备机上的catalog_xmin
)。
如果主机上的wal_level
降低到低于logical
,备机上的现有逻辑槽
也会失效。备机在检测到WAL流中的此类变化后会立即执行此操作。这意味着,对于滞后的walsender(如果有),
主机上wal_level
参数变化之前的一些WAL记录将不会被解码。
创建逻辑槽需要有关所有当前运行事务的信息。在主服务器上,这些信息可以直接
获取,但在备用服务器上,这些信息必须从主服务器获取。因此,槽的创建可能需要
等待主服务器上发生一些活动。如果主服务器处于空闲状态,在备用服务器上创建逻
辑槽可能会花费显著的时间。可以通过在主服务器上调用pg_log_standby_snapshot
函数来加速这一过程。
复制槽可以在崩溃时保持,并且不知道其消费者的状态。即便没有连接使用它们,
它们也将阻止移除所需的资源。这会消耗存储,因为只要还有一个复制槽需要,
WAL 和来自于系统目录的行就不能被VACUUM
移除。在极端情况下这会导致数据库关闭以防止事务ID回卷(见Section 24.1.5)。因此如果不再需要一个槽,那就应该删除它。
主服务器上的逻辑复制槽可以通过使用
failover
参数来同步到热备服务器,
该参数属于
pg_create_logical_replication_slot
,
或者在创建槽时通过
failover
选项配合
CREATE SUBSCRIPTION
使用,然后在备机上调用
pg_sync_replication_slots
。
通过在备机上设置
sync_replication_slots
,
failover 槽可以在 slotsync 工作线程中定期同步。
要使同步生效,必须在主服务器和备机之间存在物理复制槽(即在备机上应配置
primary_slot_name
),
并且必须在备机上启用
hot_standby_feedback
。
还需要在
primary_conninfo
中指定有效的
dbname
。
强烈建议在主服务器的
synchronized_standby_slots
列表中包含该物理复制槽的名称,以防止订阅者消费变更的速度超过热备。
即使配置正确,发送变更到逻辑订阅者时仍会有一定的延迟,
这是由于等待
synchronized_standby_slots
中命名的槽所致。
当使用
synchronized_standby_slots
时,
主服务器不会完全关闭,直到与
synchronized_standby_slots
中指定的物理复制槽相关联的备机
确认已接收主服务器上最新刷新位置的 WAL。
故障切换后恢复逻辑复制的能力取决于备用节点故障切换时
pg_replication_slots.synced
值。只有在故障切换前已在备用节点上达到 synced 状态为 true 的持久槽
才能在故障切换后用于逻辑复制。临时 synced 槽不能用于逻辑解码,因此
这些槽的逻辑复制无法恢复。例如,如果由于订阅被禁用,
同步槽无法在备用节点上变为持久槽,则即使启用该订阅,
故障切换后也无法恢复该订阅。
要在从同步逻辑槽故障转移后恢复逻辑复制,必须修改订阅的'conninfo'以指向新的主服务器。
这是通过
ALTER SUBSCRIPTION ... CONNECTION
来完成的。建议在提升备用服务器之前先禁用订阅,并在修改连接字符串后重新启用订阅。
在提升期间,旧的主服务器可能会重新启动,如果未禁用订阅,逻辑订阅者可能 会继续从旧的主服务器接收数据,直到连接字符串被更改。这可能导致数据不 一致问题,阻止逻辑订阅者能够继续从新的主服务器进行复制。
输出插件将数据从预写式日志的内部表示转换成复制槽的消费者所需的格式。
当使用流复制接口创建一个新的复制槽时(参见CREATE_REPLICATION_SLOT),
会导出一个快照(参见Section 9.28.5),
这将准确显示数据库在创建槽之后的状态,之后所有更改都将包含在更改流中。
这可以用来通过使用SET TRANSACTION SNAPSHOT
来读取创建槽时数据库的状态,从而创建一个新的副本。
然后可以使用该事务来转储数据库在那个时间点的状态,之后可以使用槽的内容更新而不会丢失任何更改。
并非总能够创建快照。特别是在连接到热备时,快照创建将会失败。不要求快照导出的应用可以用NOEXPORT_SNAPSHOT
选项来抑制它。
option.