这是《PostgreSQL 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 逻辑复制发布逻辑变更,而不是物理页变化。它支持按库表选择、跨版本升级和异构消费,但语义限制更多。
22.1 架构
Publisher
logical decoding -> publication
|
Replication protocol
|
Subscriber
apply worker -> subscription
22.2 发布
发布端配置:
wal_level = logical
max_replication_slots = 10
max_wal_senders = 10
创建发布:
CREATE PUBLICATION sales_pub
FOR TABLE orders, order_items;
只发布部分操作:
ALTER PUBLICATION sales_pub SET (publish = 'insert, update');
22.3 订阅
CREATE SUBSCRIPTION sales_sub
CONNECTION 'host=publisher.internal port=5432 dbname=shop user=replicator password=strong-password sslmode=require'
PUBLICATION sales_pub;
初始数据会按发布表复制,之后应用增量逻辑变更。
22.4 冲突处理
订阅端遇到主键冲突或约束错误时,apply worker 会停止:
ERROR: duplicate key value violates unique constraint
处理方式:
- 查看订阅端错误;
- 删除或修正冲突行;
- 恢复 apply;
- 记录根因;
- 必要时重建订阅。
22.5 支持与限制
常见限制:
| 操作 | 逻辑复制行为 |
|---|---|
| INSERT | 支持 |
| UPDATE | 需要副本标识 |
| DELETE | 需要副本标识 |
| DDL | 不会自动发布 |
| 序列 | 不自动同步状态 |
| 大对象 | 版本和支持有限 |
| TRUNCATE | 取决于发布配置和版本 |
表必须有主键或唯一索引作为副本标识:
ALTER TABLE orders REPLICA IDENTITY USING INDEX uq_orders_order_no;
22.6 监控
发布端:
SELECT * FROM pg_stat_replication;
SELECT slot_name, plugin, database, active
FROM pg_replication_slots;
订阅端:
SELECT * FROM pg_stat_subscription;
关注:
- apply 延迟;
- 复制槽保留 WAL;
- 冲突错误;
- worker 状态;
- 表结构一致。
22.7 跨版本升级
旧版本 Publisher -> 新版本 Subscriber
流程:
- 新库建表和索引;
- 建发布和订阅;
- 等初始同步;
- 追平增量;
- 短停写;
- 校验数据;
- 切换应用;
- 同步序列;
- 删除订阅。
22.8 多写入与分区订阅
逻辑复制天然不防止多写入冲突。双向复制需要冲突解决策略和业务分区,不能只靠数据库默认行为。
本章小结
逻辑复制适合选择性表复制、跨版本升级和下游同步。它不复制 DDL 和序列状态,且依赖副本标识。生产必须监控复制槽、apply 延迟和冲突。
思考题
- 物理复制和逻辑复制有什么区别?
- REPLICA IDENTITY 有什么作用?
- 订阅端冲突如何处理?
- 为什么序列要单独处理?
- 逻辑复制升级的切换步骤是什么?