PostgreSQL 15物理复制要求主库wal_level=replica、max_wal_senders≥16、listen_addresses='*',pg_hba.conf需单独配置host replication规则,从库必须用pg_basebackup初始化并验证pg_stat_replication和pg_is_in_recovery()状态。

主库必须开 wal_level=replica 且 max_wal_senders 要够用
PostgreSQL 15 的物理复制依赖 WAL 流式传输,wal_level 必须设为 replica(不能是 minimal 或旧版的 hot_standby),否则从库连不上,日志里会报 replication is not allowed because wal_level is set to minimal。
max_wal_senders 决定主库能同时服务几个流复制连接。如果只配一个从库,设成 10 没问题;但后续要加从库或做逻辑复制,建议直接设 16 或更高。这个值改完必须重启主库才生效。
- 修改
/var/lib/pgsql/15/data/postgresql.conf(路径依实际安装方式可能不同) - 确认以下三行已取消注释并正确设置:
wal_level = replicamax_wal_senders = 16listen_addresses = '*' -
wal_keep_size建议设为1GB或更大,避免网络抖动时 WAL 被自动清理导致从库断连重传
pg_hba.conf 里 replication 条目必须单独写,且 host 类型要对
很多部署失败是因为在 pg_hba.conf 里只写了普通连接规则,漏掉专用于复制的行。PostgreSQL 要求:复制连接必须匹配 host replication 开头的规则,不能复用 host all 规则。
典型错误是写成:host all replicator 192.168.1.101/32 md5 —— 这无效,因为第二字段不是 replication。
- 必须加这一行(IP 替换为从库真实地址):
host replication replicator 192.168.1.101/32 md5 - 如果主从在内网且信任环境,可用
trust,但生产环境强烈建议用md5 - 这条规则要放在所有
host all规则之前,否则会被更宽泛的规则拦截 - 改完后执行
pg_ctl reload或重启服务,SELECT * FROM pg_hba_file_rules();可验证是否加载成功
从库初始化必须用 pg_basebackup,不能 cp 或 rsync 数据目录
直接拷贝主库 data 目录到从库会导致系统表 OID 不一致、WAL 位点错乱,启动后报 could not access the primary WAL file 或卡在 recovery 状态。
pg_basebackup 是唯一安全的初始化方式,它会自动处理 checkpoint、同步 WAL、生成正确的 backup_label。
- 从库机器上执行(注意:命令在从库执行,连接主库):
pg_basebackup -h 192.168.1.100 -U replicator -D /var/lib/pgsql/15/data -P -X stream -R -
-R参数关键:它会自动生成standby.signal并写入primary_conninfo到postgresql.auto.conf - 若手动写
standby.signal,必须确保文件为空且权限为postgres:postgres,否则从库启动时忽略它 - 执行前确认从库 data 目录为空,且
postgres用户对其有完全读写权限
从库启动后查 pg_stat_replication 和 pg_is_in_recovery() 最快验活
别只看进程是否存在或日志有没有 “database system is ready”。真正有效的验证是查主从状态是否对齐。
主库上运行:SELECT client_addr, state, sent_lsn, write_lsn, flush_lsn, replay_lsn FROM pg_stat_replication;
看到 state = 'streaming' 且 replay_lsn 接近 sent_lsn 才算实时同步中。
- 从库上运行:
SELECT pg_is_in_recovery();—— 返回t表示正常 standby 状态;返回f说明已升主或配置失效 - 延迟单位是字节,不是秒。用
pg_wal_lsn_diff(flush_lsn, replay_lsn)查当前延迟量,超过 10MB 就该排查网络或磁盘 I/O - 常见假成功:从库日志显示 “database system is ready”,但
pg_is_in_recovery()返回f—— 很可能是standby.signal文件被删或权限不对
从库一旦启动,就不再接受写入;所有 DDL/DML 都必须在主库执行。误操作同步过去无法回滚,这是物理复制最常被忽视的约束。


















