postgresql逻辑复制默认同步insert/update/delete,若只同步insert和update需显式指定publish='insert,update';update依赖主键或replica identity,无主键表须设full或添加唯一索引。

能捕获并同步 INSERT/UPDATE 增量,但默认也会同步 DELETE —— 除非你显式排除它。 PostgreSQL 逻辑复制不支持“只同步 INSERT 和 UPDATE 而自动忽略 DELETE”的开箱即用配置;必须在创建 PUBLICATION 时明确指定操作类型,否则默认包含全部(INSERT/UPDATE/DELETE)。
CREATE PUBLICATION 时必须指定 FOR TABLE ... WITH (publish = 'insert,update')
PostgreSQL 的 PUBLICATION 默认行为是 publish = 'insert,update,delete'。若只想同步 INSERT 和 UPDATE,需显式声明:
CREATE PUBLICATION my_pub FOR TABLE users WITH (publish = 'insert,update');- 不能写成
publish = 'insert update'(缺少逗号会报错syntax error at or near "update") - 大小写不敏感,但建议统一用小写;空格仅用于分隔,不可省略逗号
- 一旦发布创建完成,
ALTER PUBLICATION ... SET (publish = ...)不支持修改该参数(PG 16 及之前版本),只能DROP后重建
订阅端收到的变更严格受限于发布端的 publish 设置
发布端设为 insert,update 后,订阅端 pg_replication_origin_status 或日志中将完全看不到对应表的 DELETE 操作记录。这不是过滤或丢弃,而是发布端根本未生成这些变更事件。
- 验证方式:在发布端执行
DELETE FROM users WHERE id = 1;,再查订阅端该行是否残留 —— 它会保留,且不会报冲突(因为没收到 DELETE) - 注意:如果订阅端表有
ON DELETE CASCADE外键,该级联行为仍会发生,但这与逻辑复制无关,是本地约束触发的 - 若后续需要补发 DELETE,必须重建 publication 并重新初始化订阅(
WITH (copy_data = false, create_slot = true)可跳过全量,但需手动处理存量数据一致性)
UPDATE 捕获依赖主键或 REPLICA IDENTITY
逻辑复制对 UPDATE 的识别依赖行标识能力。若表无主键或唯一索引,PostgreSQL 默认无法精确定位被更新的行,会导致同步失败或数据错乱。
- 错误现象:
ERROR: logical replication cannot replicate tables without primary keys or replica identity - 解决路径二选一:
– 添加主键或非空唯一索引(推荐)
– 或执行ALTER TABLE users REPLICA IDENTITY FULL;(将整行作为标识,但显著增加 WAL 体积和网络带宽) -
REPLICA IDENTITY USING INDEX仅在 PG 14+ 支持,需确保索引列非空且唯一 - 执行
REPLICA IDENTITY修改后,已有 subscription 不会自动生效,需ALTER SUBSCRIPTION ... REFRESH PUBLICATION触发重同步元信息
增量同步延迟与监控关键点
逻辑复制的增量延迟不是靠“时间差”判断,而是比对 LSN 和 origin 进度。容易忽略的是:即使没有新变更,pg_replication_origin_advance() 也可能滞后。
- 检查延迟:在订阅端运行
SELECT * FROM pg_stat_subscription;,重点关注last_msg_send_time和last_msg_receipt_time差值,以及latest_end_lsn是否停滞 - 真正卡住的表现是
pg_replication_origin_status中replay_lsn长期不推进,而非单纯看时间戳 - 若发现 UPDATE 同步慢,先确认发布端是否有长事务阻塞 WAL 清理(
pg_stat_activity查backend_type = 'client backend'且state = 'idle in transaction') - 避免在高并发 UPDATE 场景下使用
REPLICA IDENTITY FULL,它会使单条 UPDATE 产生数倍 WAL 数据量
真正麻烦的不是配置本身,而是当业务要求“只同步新增和修改”时,DELETE 被静默忽略可能掩盖上游误删问题;上线前务必用真实 DELETE 场景做端到端验证,而不是只测 INSERT/UPDATE。











