PostgreSQL逻辑复制解密
字数 1621 2025-08-12 11:34:37
PostgreSQL逻辑复制详解
1. 逻辑复制概述
逻辑复制是基于复制标识复制数据及其变化的一种方法,区别于物理复制对页面操作的描述,逻辑复制是对事务及数据元组的一种描述。
1.1 逻辑复制与物理复制的区别
- 物理复制:操作tablespace/database/filenode文件的块
- 逻辑复制:操作和描述数据元组
2. 核心概念
2.1 复制槽(Replication Slot)
复制槽是记录复制状态的一组信息,主要功能:
- 防止过早清理逻辑复制解析所需的WAL日志
- 每个插槽从单个数据库流式传输一系列更改
- 创建时需要指定使用的输出插件
- 创建时会提供一个快照
2.2 输出插件(Output Plugin)
负责将WAL日志解码为可读格式,常用插件:
test_decoding:主要用于测试pgoutput:默认使用的插件wal2json:输出为JSON格式
PostgreSQL定义了一系列回调函数,允许用户编写自定义输出插件。
2.3 复制协议与消息
通过复制协议获取WAL数据流,例如使用PSQL工具建立复制连接:
psql "dbname=postgres replication=database"
关键命令:
START_REPLICATION [SLOT slot_name] [PHYSICAL] XXX/XXX [TIMELINE tli]
3. 工作流程
- WAL文件中的事务内容不一定是连续的
- 通过Reorder后放在buffer中
- 根据事务ID组织成一条消息
- COMMIT后发送给输出插件
- 输出插件解析后将消息流发送给目标端
4. 关键问题与解决方案
4.1 Failover Slot问题
问题:主备切换时备库缺少复制槽信息
解决方案:
- 主库创建复制槽,检查备库WAL文件连续性
- 复制包含slot信息的物理文件至备库(pg_repslot目录)
- 备库重启(StartupReplicationSlots只在postmaster启动时调用)
- 定期查询主库slot状态,使用
pg_replication_slot_advance推进备库复制槽
4.2 DDL同步问题
问题:原生逻辑复制不支持解析DDL语句
解决方案:
- 使用事件触发器感知表结构变更
- 记录到DDL_RECORD表中
- 将该表通过逻辑复制进行发布
- 接收端获取变更并执行相应DDL语句
4.3 双向同步问题
问题:双向同步会导致WAL循环
解决方案:
- 使用
pg_replication_origin_session_setup或replorigin_create指定Origin ID - 通过解析插件中的FilterByOriginCB回调函数在解析过程中过滤
- 比使用辅助表方案效率更高
4.4 其他问题
TOAST处理:
- 对于TOAST值,使用占位符处理
- 接收端接收到占位符则不处理该列
心跳表:
- 创建周期性更新的心跳表
- 防止发布的表长期不更新导致WAL积压
大事务延迟:
- PG14提供streaming模式
- 事务进行中即可解析并发送至接收端
5. 应用实践
5.1 全量与增量同步
流程:
- 创建复制槽并导出快照
- 根据快照进行全量数据迁移
- 根据复制槽进行增量数据迁移
架构:
- 使用PG数据库或消息队列(MQ)作为数据代理
- 全量与增量解析可同时进行
- 全量完成后通知增量处理程序
- 可在解析后进行数据预处理
5.2 自建实例迁移上云实践
迁移阶段:
-
数据检查阶段:
- 检查主键、权限、配置
-
数据迁移阶段:
- 结构迁移
- 存量数据迁移
- 增量数据迁移
- 监控迁移状态
-
应用迁移阶段:
- 切换域名
- 引入流量
-
回滚阶段:
- 增量数据回流
- 快速回滚机制
6. 总结
PostgreSQL逻辑复制提供了灵活的数据迁移方案,通过理解其核心概念、工作流程和常见问题解决方案,可以构建高效可靠的数据迁移管道。关键点包括:
- 正确配置和管理复制槽
- 选择合适的输出插件
- 处理DDL同步和双向复制等特殊场景
- 合理设计全量+增量的迁移方案
- 考虑高可用和容灾需求
通过本文介绍的技术和方法,可以应对大多数PostgreSQL数据迁移场景,实现数据的高效、安全流动。