1. 逻辑复制基础:PostgreSQL 逻辑复制原理、发布与订阅模型、WAL 日志与解码插件
1.1 逻辑复制核心原理
PostgreSQL 逻辑复制是一种基于 发布-订阅 模型的数据同步机制,它允许将数据库中的增量变更(INSERT、UPDATE、DELETE)实时传输到其他数据库实例。与物理复制不同,逻辑复制传输的是 逻辑行级变更,而非磁盘块级别的物理 WAL 记录,因此支持跨版本、跨平台、选择性复制。
关键特性: 逻辑复制粒度可精确到表级,支持异构数据库同步,是构建缓存一致性、数据仓库、微服务 CQRS 的核心技术。
1.2 发布与订阅模型
逻辑复制由两个角色组成:发布者(Publisher) 和 订阅者(Subscriber)。发布者定义要复制的表集合(Publication),订阅者接收并应用这些变更(Subscription)。
| 角色 | 职责 | 关键参数 |
|---|---|---|
| 发布者 | 从 WAL 中提取逻辑变更,通过解码插件转换为逻辑协议 | publish = 'insert, update, delete, truncate' |
| 订阅者 | 连接到发布者,接收并应用变更到本地表 | slot_name、create_slot = true |
| 复制槽 | 在发布者端保留 WAL 日志,防止被清理 | pg_replication_slots 视图监控 |
1.3 WAL 日志与解码插件
逻辑复制的底层依赖 PostgreSQL 的 预写式日志(WAL)。WAL 记录了所有数据修改,逻辑解码插件将 WAL 中的物理变更解析为逻辑行级数据流。
- WAL 日志:事务提交前先写入 WAL,保证 ACID 持久性。逻辑复制读取 WAL 中的
XLOG记录。 - 解码插件:
pgoutput(内置,用于逻辑复制)、wal2json(输出 JSON 格式)、decoderbufs(Protocol Buffers 格式)。 - 工作流程:WAL 写入 → 解码插件解析 → 逻辑变更发送到订阅者 → 订阅者应用。
实践建议: 生产环境优先使用内置
pgoutput 插件,避免额外依赖。监控 pg_replication_slots 中 active 状态和 wal_status,防止 WAL 堆积导致磁盘满。
1.4 逻辑复制架构图
下图展示了逻辑复制的完整数据流,从发布者 WAL 写入到订阅者应用变更的全链路。
1.5 逻辑复制与物理复制对比
| 对比维度 | 逻辑复制 | 物理复制 |
|---|---|---|
| 复制粒度 | 表级、行级 | 整个实例 |
| 跨版本兼容 | 支持(如 PG14 → PG16) | 主从版本必须一致 |
| DDL 复制 | 需手动同步 | 自动同步 |
| WAL 格式 | 逻辑行级变更 | 物理块级变更 |
| 典型场景 | 缓存失效、数据仓库、微服务 | 高可用、读写分离 |
1.6 逻辑复制配置示例
以下是在发布者端创建发布、在订阅者端创建订阅的标准 SQL 流程。
-- 发布者:创建发布
CREATE PUBLICATION my_pub FOR TABLE users, orders;
-- 可选:发布所有表
-- CREATE PUBLICATION all_pub FOR ALL TABLES;
-- 订阅者:创建订阅
CREATE SUBSCRIPTION my_sub
CONNECTION 'host=192.168.1.100 port=5432 dbname=mydb user=repl password=secret'
PUBLICATION my_pub;
注意: 创建订阅前,目标表必须在订阅者端预先创建,且表结构一致。逻辑复制不会自动同步 DDL 变更。
1.7 逻辑复制故障排查要点
- 复制槽未激活:检查
pg_replication_slots中active是否为 true。 - WAL 堆积:订阅者消费过慢或断开,导致
pg_wal目录膨胀。 - 表结构不匹配:订阅者表缺少列、数据类型不一致导致应用失败。
- 网络延迟:逻辑复制流依赖 TCP 长连接,网络抖动可能导致重连。
监控命令:
SELECT slot_name, active, restart_lsn, wal_status FROM pg_replication_slots;SELECT * FROM pg_stat_subscription;