wal_level必须设为logical才能启用逻辑复制,否则复制静默失败;还需配置max_wal_senders≥2、max_replication_slots≥1、pg_hba.conf添加replication权限行、用户授予REPLICATION属性及SELECT权限,并确保表结构完全一致。

wal_level 没设成 logical 就启动复制?直接静默失败
逻辑复制不是“开箱即用”的功能,wal_level 必须显式设为 logical,否则即使创建了 publication、subscription,复制也会卡在初始化阶段,不报错、不同步、不提示——只默默停在“waiting for initial copy”或根本收不到任何 INSERT/UPDATE 消息。
常见错误配置:wal_level = replica 或保留默认值 replica(PostgreSQL 12+ 默认),这仅支持物理复制,对逻辑复制无效。
-
wal_level = logical是硬性前提,改完必须重启 PostgreSQL(热重载不生效) -
max_wal_senders至少 ≥ 2:一个用于 base backup,一个用于逻辑复制流;建议设为5或更高 -
max_replication_slots必须 ≥ 1,且要 ≥ 实际创建的 slot 数量(publication 自动占用 slot)
pg_hba.conf 漏掉 replication 权限行,连接被拒却不报“replication”关键词
订阅端连接发布端时,用的是 replication 数据库类型,不是普通 dbname=xxx。如果 pg_hba.conf 只写了普通用户访问规则,连接会直接拒绝,但错误日志里往往只显示 connection rejected 或 FATAL: no pg_hba.conf entry,根本不会提“replication”三个字,极易误判为网络或密码问题。
- 必须加这一行(注意第 2 字段是
replication,不是数据库名):host replication repl_user 192.168.10.0/24 md5 - 用户
repl_user必须有REPLICATION属性:ALTER USER repl_user WITH REPLICATION; - 若用
pg_create_subscription()自动建 slot,该用户还需SUPERUSER或至少pg_read_all_data(PG 14+)
订阅端表结构不匹配,复制中途崩在 “duplicate key violates unique constraint”
逻辑复制不校验表结构一致性,它只按 relation ID 和列序号投递数据。如果从库表少了字段、主键类型不一致、或已有冲突主键值,INSERT/UPDATE 会直接报错并中断复制进程,错误如:ERROR: duplicate key value violates unique constraint "t1_pkey"。
- 发布端
CREATE PUBLICATION后新增的表,不会自动加入 publication —— 必须显式ALTER PUBLICATION ... ADD TABLE - 订阅端建表时,所有列名、类型、NOT NULL 约束、主键定义必须与发布端严格一致(顺序也要一致)
- 首次同步前,务必清空订阅端目标表,或确保无主键/唯一键冲突数据(
TRUNCATE比DELETE更安全) - 若需跳过初始全量同步,可用
create_subscription(..., copy_data := false),但之后必须手动保证数据一致
Go 里用 pglogrepl 连不上?大概率是环境变量或权限没对齐
pglogrepl 示例程序依赖 PGLOGREPL_TEST_CONN_STRING 环境变量传连接串,但它要求这个串**必须包含 replication 权限**,且不能带 dbname= —— 应该指向发布端数据库,但连接类型是 replication。很多开发者填了普通应用连接串,结果 ReplicationConnect() 返回 ERROR: must be superuser or replication role 却没意识到是权限问题。
- 正确连接串示例:
user=repl password=xxx host=localhost port=5432(不含dbname) - 用户
repl必须有REPLICATION属性,且对发布数据库有SELECT权限(否则 base backup 阶段报permission denied for table) - 若用 PG 15+,还需
GRANT ALL ON SCHEMA public TO repl;,否则解析Relation消息时可能 panic - 跳过 base backup 测试?设
PGLOGREPL_SKIP_BASE_BACKUP=true,但生产环境不建议跳
逻辑复制的坑不在语法多难,而在于它把“一致性责任”从数据库推给了人:wal_level、hba 规则、表结构、用户权限、连接串格式,任意一环断掉,它都不报明确错误,只沉默或报错在下游。最稳妥的做法是——每改一项配置,都用 pg_isready -U repl -d 'replication' -h host 验证连接能力,再查 pg_replication_slots 确认 slot 存在且 active。










