PostgreSQL逻辑复制的未来演进

📅 2026/8/11 22:41:32
PostgreSQL逻辑复制的未来演进
本文整理于 HOW 2026 演讲内容演讲者侯志杰PostgreSQL Major Contributor。逻辑复制概述逻辑复制是PostgreSQL在PG 10版本正式引入的核心功能其基本原理是将发布端部分表的数据同步到订阅端。最简单的使用方式如下-- 发布端创建表并发布CREATETABLEusers(idint);CREATEPUBLICATION mypubFORTABLEusers;-- 订阅端创建相同表结构并订阅CREATETABLEusers(idint);CREATESUBSCRIPTION mysub CONNECTIONhost192.168.1.100 dbnamepostgres userrepuser passwordrep123PUBLICATION mypub;执行上述命令后两个PostgreSQL实例之间会自动建立连接持续将发布端的数据修改复制到订阅端。内部模块与数据流逻辑复制的内部流程涉及发布端与订阅端多个模块的协作用户在发布端写入数据产生WAL日志logical decoder读取WAL日志replication slot保护未被消费的日志不被清理逻辑解码将二进制日志转化为可操作的具体数据Output Plugin输出插件获取解码后的数据开发者可在此实现自定义逻辑数据发送至订阅端由apply worker接收并解析为SQL命令INSERT/UPDATE/DELETE应用到订阅端数据库application origin记录复制进度确保订阅端重启后能从正确位置继续避免重复或遗漏table sync worker负责全量初始数据的拷贝完成后由apply worker接管增量同步历史演进自PostgreSQL 10以来逻辑复制每年都有新功能加入DDL扩展发布端和订阅端的SQL命令持续增强易用性WAL预取提升日志读取性能Streaming模式支持大事务实时传输无需等待事务结束即可边读边传Row Filter支持按行过滤只复制满足条件的数据Sequence同步引入sequence sync worker复制序列数据冲突检测为双向复制场景提供基础尽管如此逻辑复制仍存在两个明显的潜力空间多主一致性和性能。目前逻辑复制虽支持多节点同时写入且无回环问题但双向写入时的数据冲突无法自动处理性能方面逻辑复制比物理复制慢一个数量级以上单进程Apply Worker在高并发写入下延迟持续增大。以下三个新功能正是针对这些痛点设计的。多主冲突检测与自动解决冲突的产生在多主写入场景下若两个节点同时修改同一行数据会产生冲突。以下图为例发布端插入(1, R)订阅端同时插入(1, B)主键均为1。当发布端的修改到达订阅端时发现主键已存在Apply Worker报错停止逻辑复制中断。可检测的冲突类型PostgreSQL目前已能在日志中识别以下冲突类型冲突类型说明insert_exists插入的行违反不可延迟的唯一约束主键冲突update_origin_differs待更新的行之前被其他来源修改过update_deleted待更新的元组已被其他来源并发删除日志会输出类似信息ERROR: conflict detected on relation public.test: conflictinsert_exists DETAIL: Could not apply remote change: remote row (1, remote). Key already exists in unique index test_pkey现有的手动解决方法当前PostgreSQL提供了几种手动处理冲突的方式方法一disable_on_error订阅端设置此选项后发生冲突时订阅端会停止而非持续报错给用户介入分析的机会。方法二SKIP LSNALTERSUBSCRIPTION mysub SKIP(lsn0/1566D10);跳过指定LSN对应的事务但会丢失该事务的数据需手动恢复。方法三自定义Trigger用户自行编写Trigger在Apply Worker写入前判断并处理冲突。CREATETRIGGERtrg_ignore_duplicate_insert BEFOREINSERTONmy_tableFOR EACH ROWEXECUTEFUNCTIONignore_duplicate_insert();ALTERTABLEmy_tableENABLEREPLICATRIGGERignore_duplicate_insert;方法四Advance Origin通过pg_replication_origin_advance向前推进复制进度跳过部分日志同样会丢失数据。未来的自动化方案冲突日志表新增系统表专门存储冲突历史数据用户可直接通过SQL查询获取冲突的元组、事务类型等信息无需自行解析日志。自动冲突解决策略在创建或修改订阅时指定冲突解决策略CREATESUBSCRIPTION mysub CONNECTION...PUBLICATION mypub CONFLICT RESOLVER(insert_existsapply_remote,...);ALTERSUBSCRIPTION mysub CONFLICT RESOLVER(insert_existsskip,...);内置的冲突解决方法包括解决策略行为apply_remote优先应用发布端修改如删除订阅端冲突行后插入新数据skip仅跳过冲突的行修改事务其他部分正常应用error遇到冲突直接报错last_update_win应用时间戳最新的修改保持最终一致性死元组保留为正确检测update_deleted等冲突需确保被删除的元组在冲突检测完成前不被Vacuum清理。新增订阅选项retain_dead_tuples可动态保留死元组在确认不再需要后允许回收。并行复制性能瓶颈逻辑复制在订阅端默认只有一个apply worker进程。在发布端有大量客户端并发写入时单进程无法及时处理所有变更复制延迟持续增大这是逻辑复制性能远低于物理复制的核心原因。现有方法的局限Streaming ParallelPG 16仅对未提交的大事务有效对小事务无优化不适用于普通场景。多订阅端划分按表划分时外键关联的两张表复制顺序无法保证可能导致数据不一致按行划分时提交顺序无法与发布端保持一致。新方案设计为每个事务独立开启进程进行并行应用核心机制如下依赖检测Leader Worker在分发变更时计算事务间的依赖关系。如果两个事务修改了同一行或可能破坏唯一约束则认为存在依赖后一个事务需等待前一个完成后再执行。提交顺序保证即使事务间无数据依赖提交阶段仍需严格遵循发布端的提交顺序确保数据一致性。性能数据基准测试显示增加Worker数量可提升约3倍的复制吞吐量。受限于提交顺序协调的开销性能提升有上限但已能显著改善高并发场景下的延迟问题。集中式逻辑解码问题重复解码在多订阅端场景下每个订阅端对应一个独立的WALSender进程每个进程都要对相同的WAL日志进行独立的逻辑解码。这种重复解码造成CPU开销随订阅数线性增长解码工作重复执行扩展性差延迟升高高写入负载下问题加剧解决方案引入专用进程统一解码WAL日志解码结果在所有WALSender之间共享复用。每个订阅端直接消费已解码的数据无需重复解析。这本质上是一种Pipeline化的处理机制将解码从N次降为1次。总结本文介绍了PostgreSQL逻辑复制未来演进中的三个核心方向多主冲突检测与自动解决通过冲突日志表和可配置的自动解决策略将当前需要手工介入的冲突处理流程化、自动化提升多主架构的可用性。并行复制通过依赖感知的事务分发和提交顺序保证突破单进程Apply Worker的性能天花板实测可提升约3倍吞吐量。集中式解码消除多订阅端场景下的重复解码开销将解码次数从O(n)降为O(1)。上述功能预计将在PostgreSQL 20、PostgreSQL 21或PostgreSQL 22版本中陆续实装。此外除了技术演进苹果公司近期也已决定组建团队并投入资源参与社区开发成为继微软、亚马逊、谷歌之后又一家反哺PostgreSQL社区的国际大厂这对整个生态的发展是积极的信号。