数据面试题:PostgreSQL 18 如何让逻辑复制在主备切换后继续?
题干与适用场景
一个 PostgreSQL 18 主库通过逻辑复制把变更发送给分析集群和外部订阅者。主库可能故障切换到物理备库,请设计复制槽、参数、订阅者检查和切换顺序,确保切换后逻辑复制从正确位置继续,且不把“备库已同步”误当成“订阅者已追平”。
面试官考察点
- 是否区分逻辑复制槽、物理复制槽、WAL 保留和订阅者确认位置。
- 是否理解 failover 槽复制到备库是异步的,切换前必须验证就绪。
- 是否能使用
pgreplicationslots、LSN 和订阅状态证明安全切换。 - 是否能处理槽失效、订阅者落后、计划切换与意外故障。
回答前需要澄清的问题
- 订阅者是 PostgreSQL 还是外部系统,是否能在新主库重新连接?
- 允许的 RPO 是零、有限 LSN 差距,还是可接受重新快照?
- 主备之间是否启用物理复制槽与同步备用确认?
- 切换由编排器执行还是人工执行,谁负责冻结写入和更新连接?
30 秒回答框架
我会在主库为每个需要故障转移的逻辑复制槽启用 failover,让槽状态同步到热备;同时配置物理同步约束,避免订阅者先看到主库已确认但备库尚未持久化的变更。切换前检查备库上的槽已 synced、未失效,并确认订阅者所需槽全部就绪。提升备库后更新连接,验证订阅者从新主库继续消费,再解除写入冻结。若异步同步未追平,就按 RPO 选择延迟切换或接受重建订阅。
分步骤深入解答
1. 逻辑复制槽保存什么
逻辑复制槽保存解码进度和未被订阅者确认的 WAL 保留边界。槽不会自动等同于订阅者健康;订阅者停止消费时,主库可能持续保留 WAL 并增加磁盘压力。
2. 创建 failover 槽
PostgreSQL 18 支持在创建逻辑槽时设置 failover,也可在创建订阅时启用对应选项。示例使用 SQL 展示意图,实际参数名和权限应以目标版本文档与部署方式复核。
SELECT *
FROM pg_create_logical_replication_slot('analytics_slot', 'pgoutput', false, true);槽的 failover 标志允许其状态被同步到热备,但不代表同步已完成。
3. 备库侧同步开关
备库需要启用接收并应用逻辑槽同步的配置,例如 syncreplicationslots。主库还应通过 synchronizedstandbyslots 指定必须先追上的物理槽,避免逻辑订阅者进度超过可用于接管的备库。
4. 异步同步为何要单独确认
槽同步逻辑复制的是状态,过程本身是异步的。主库发生故障时,备库可能已经有数据页,却没有最新槽确认位置;直接提升会让订阅者找不到需要的起点,或产生重复与缺口。
5. 切换前检查槽状态
在候选备库查询 pgreplicationslots,确认目标槽已同步、不是临时槽、没有失效原因,并与订阅者清单逐项对应。
SELECT slot_name,
synced,
temporary,
invalidation_reason,
confirmed_flush_lsn
FROM pg_replication_slots
WHERE slot_type = 'logical';只有所有必需槽都满足条件,才把备库标记为可接管。
6. PostgreSQL 订阅者的额外确认
对 PostgreSQL 订阅者,还要确认订阅端已消费到与槽同步相容的位置。不能只看主备物理复制延迟;应结合订阅状态、最后接收 LSN 和业务延迟判断。
7. 外部订阅者的切换
外部系统通常不能自动理解 PostgreSQL 的槽状态。切换编排器应先冻结或暂停消费,提升备库后更新连接和槽名称,再用幂等事件与应用层偏移量验证没有跳过数据。
8. 故障与恢复路径
计划切换可以等待所有槽同步完成;意外故障则按 RPO 判断是否接受缺口、延迟切换或重建订阅。旧主库恢复后不能直接并入写路径,应先隔离、重新建立物理复制,再核对槽和订阅状态。
设计取舍与边界
- failover 槽提高逻辑复制可恢复性,却增加槽同步和 WAL 监控复杂度。
- 等待槽完全同步降低数据缺口,却可能延长故障切换时间。
synchronizedstandbyslots约束逻辑进度与物理备库追赶关系,不等于对所有外部订阅者提供端到端零丢失保证。- 槽失效、磁盘逼近上限和订阅者长期停摆必须有告警与清理策略,不能只依赖切换脚本。
落地计划与证据
- 在 PostgreSQL 18 测试集群创建 failover 逻辑槽,验证主备配置和权限。
- 注入订阅者停摆、WAL 堆积、槽未同步和主库突失,记录 LSN 与恢复结果。
- 自动化切换前查询
pgreplicationslots,将槽清单与订阅者清单逐项比对。 - 在计划切换与意外故障两条路径分别演练暂停、提升、改连、追平和回滚。
- 对照 PostgreSQL 18 Logical Replication Failover、Logical Decoding 和 Streaming Replication 文档复核参数与限制。
常见误区与追问
误区一:备库有数据就代表逻辑复制可接管
逻辑槽状态异步同步,数据页追平不代表槽位置已可用。必须检查槽的同步和失效字段。
误区二:只监控物理复制延迟
还要监控订阅者消费位置、槽确认 LSN、WAL 保留量和业务延迟,否则可能在物理层健康时发生逻辑积压。
误区三:把 failover 参数当成自动切换
它提供槽状态同步能力,不负责提升备库、更新连接或验证外部订阅者。切换仍需要编排和演练。
追问:槽没同步完能否立即提升?
只有在明确接受 RPO、缺口或重建成本时才可以;默认应等待同步完成并把结果写入切换门禁。
追问:如何避免重复消费?
保存事件唯一键或源 LSN,切换后让订阅者从可验证位置继续,并用幂等处理和对账任务处理重放。