3. 主库配置实战
搭建 PostgreSQL 流复制,主库侧真正需要改动的配置并不多,但每一项都直接决定“备库能不能连上来、能不能拿到 WAL、拿到之后能不能持续跟上”。这一节我们把主库配置拆成两条线:一条是 postgresql.conf 里的复制行为参数,另一条是 pg_hba.conf 里的连接认证规则。前者决定“发不发、发多少、发给谁”,后者决定“谁可以连、以什么身份连、用什么方式认证”。
一、postgresql.conf:复制能力的四个开关
流复制的物理基础是 WAL。主库必须先把 WAL 写到磁盘,备库才能通过复制协议拉取。因此第一个参数是 wal_level。它有三个取值:minimal、replica、logical。流复制至少需要 replica;如果后续还要做逻辑复制或逻辑解码,则要设为 logical。在 PostgreSQL 10 之前这个参数叫 wal_level = hot_standby,现在已统一为 replica。修改后必须重启实例,因为它影响 WAL 记录的内容结构。
wal_level = replica
max_wal_senders = 10
max_replication_slots = 10
wal_keep_size = 512MB
listen_addresses = '*'
第二个参数是 max_wal_senders,它限制主库同时可以有多少个 WAL 发送进程(walsender)。每个备库、每个复制槽、每个 pg_basebackup 连接都会占用一个 walsender。如果设为 0,主库直接拒绝任何复制连接。生产上建议按“备库数量 + 级联备库 + 备份连接 + 余量”来估算,例如一主两备加一个备份任务,设 10 比较稳妥。这个参数可以动态修改,但已建立的连接不会自动断开。
第三个参数是 max_replication_slots,它决定主库最多能创建多少个复制槽。复制槽的核心价值是“防止主库过早删除备库还没收到的 WAL”。没有复制槽时,主库只靠 wal_keep_size 保留一段 WAL,一旦备库断线时间过长,主库把 WAL 删了,备库就只能重建。复制槽把“保留责任”绑定到具体备库上,主库会一直保留该槽确认收到之前的 WAL。代价是:如果备库长期不回来,主库的 pg_wal 会持续膨胀,甚至撑满磁盘。因此复制槽必须配合监控使用。
第四个参数是 wal_keep_size(旧版本为 wal_keep_segments)。它是在没有复制槽或复制槽之外额外保留的 WAL 量。可以把它理解为“安全垫”:即使没有槽,主库也至少保留这么多 WAL 供备库追赶。设置过小,备库短暂断线就可能追不上;设置过大,磁盘占用增加。常见做法是 512MB 到 2GB,具体取决于写入量和可接受的断线恢复窗口。
最后是 listen_addresses。它决定 PostgreSQL 在哪些网络接口上监听。默认 localhost 只允许本机连接,备库根本连不上。要允许备库从其他主机连接,需要设为 '*' 或指定具体 IP,例如 '10.0.0.10'。同时还要确认 port(默认 5432)没有被防火墙拦截。修改 listen_addresses 需要重启,或者至少 reload 后确认监听生效。
二、pg_hba.conf:让备库连得进来、认证得过
即使 postgresql.conf 全部正确,备库连接仍可能被 pg_hba.conf 拒绝。这个文件按“从上到下第一条匹配即生效”的规则工作,所以顺序非常重要。复制连接在 pg_hba 中使用的数据库字段是 replication,不是某个具体库名。一个典型的主库配置如下:
# TYPE DATABASE USER ADDRESS METHOD
local all all peer
host all all 127.0.0.1/32 scram-sha-256
host replication repl 10.0.0.0/24 scram-sha-256
host replication repl 10.0.1.21/32 scram-sha-256
这里有几个关键点。第一,复制专用账号 repl 必须具有 REPLICATION 权限,创建方式为:
CREATE ROLE repl WITH REPLICATION LOGIN PASSWORD 'StrongPass_2024';
第二,host replication repl 10.0.0.0/24 scram-sha-256 表示允许 10.0.0.0/24 网段内使用 repl 账号发起复制连接,认证方式为 scram-sha-256。如果备库在另一个网段,必须单独加一行,不能靠一条规则覆盖所有地址。第三,认证方式要与 password_encryption 匹配。PostgreSQL 14 之后默认是 scram-sha-256,如果写成 md5 而密码是按 scram 存储的,认证会失败。第四,修改 pg_hba.conf 后执行 SELECT pg_reload_conf(); 即可生效,不需要重启。
SELECT pg_create_physical_replication_slot('replica1_slot');。备库在 primary_conninfo 中通过 primary_slot_name = 'replica1_slot' 使用它。创建后可用 SELECT * FROM pg_replication_slots; 查看 active 和 restart_lsn 状态。三、配置生效顺序与验证
主库配置完成后,不要急着去备库执行 pg_basebackup。先在主库本地验证三件事:一是 SHOW wal_level; 返回 replica 或 logical;二是 SHOW max_wal_senders; 大于 0;三是用 psql "host=10.0.0.10 port=5432 user=repl dbname=replication" 测试复制账号能否通过认证。如果这一步报 no pg_hba.conf entry,说明地址或数据库字段写错;如果报 password authentication failed,说明密码或认证方式不匹配。
下面这张图把主库侧的关键配置对象、它们的作用位置以及相互依赖关系集中呈现出来,便于对照检查:
把这张图当作主库配置的检查清单:左侧五项决定复制能力是否具备,右侧规则决定备库能否通过认证。任何一项缺失,备库都会在连接或拉取 WAL 阶段失败。实际排障时,先看 pg_stat_replication 是否有记录,再看主库日志中的 pg_hba.conf 拒绝信息,最后核对 wal_level 和 max_wal_senders,基本可以快速定位问题所在。
pg_wal 目录可能迅速膨胀。建议对 pg_replication_slots 的 active 状态和 pg_wal_lsn_diff 做监控,必要时用 pg_drop_replication_slot() 清理废弃槽。