max_wal_senders是硬上限,超限即拒连;max_replication_slots控制逻辑复制slot数量,需≥实际slot数,二者配比不当会导致连接成功但复制卡住。

max_wal_senders 超了会直接拒绝新连接
postgresql 流复制里,max_wal_senders 是硬性上限:每个 wal sender 进程对应一个物理备库或逻辑订阅者。超过就报 FATAL: remaining connection slots are reserved for non-replication superuser connections —— 这不是警告,是立即断连。
- 默认值通常是
10,但主库有 5 个物理备库 + 3 个逻辑订阅 + 2 个 pg_basebackup 并发执行时,第 11 个就会失败 - 它不区分“活跃”还是“空闲”连接:只要 wal sender 进程在跑(哪怕备库网络断了还没超
tcp_keepalives_timeout),就算占一个槽位 - 修改后必须重启 PostgreSQL 才生效,热重载不支持
- 值设太高会增加内存开销(每个 sender 约 10MB 共享内存 + 后台进程开销),别盲目堆到 100+
max_replication_slots 必须 >= 实际启用的 slot 数量
max_replication_slots 控制的是逻辑复制 slot 的数量上限,和 max_wal_senders 是两套机制。slot 不等于连接——一个 slot 可以长期存在,而 wal sender 连接可能频繁断连重连。
- 如果创建第 6 个 replication slot 时
max_replication_slots = 5,会报错Error: all replication slots are in use - 物理复制不需要 slot,所以即使你只用 streaming replication,这个参数也完全无关;只有启用了
CREATE_REPLICATION_SLOT ... LOGICAL才需要调它 - slot 会阻止 WAL 清理,设太多又不消费,会导致
pg_wal/目录暴涨甚至磁盘打满 - 它支持 reload(
select pg_reload_conf()),不用重启,但改小值不会自动删已有 slot,得手动DROP_REPLICATION_SLOT
两个参数配比不当会导致“连接成功但复制卡住”
常见误配:把 max_wal_senders 设得够大,但漏调 max_replication_slots(或反过来)。结果是连接能建,但逻辑复制 consumer 拿不到 slot,或者物理备库连上了却因没足够 sender 槽位无法启动 replay。
- 逻辑复制场景下,每个 consumer 至少需要 1 个 slot + 1 个 wal sender 连接 → 总需槽数 ≥ consumer 数,总需 sender 数 ≥ consumer 数 + 物理备库数
- 用
pg_stat_replication查当前 sender 占用:SELECT count(*) FROM pg_stat_replication;用pg_replication_slots查 slot 使用:SELECT count(*) FROM pg_replication_slots - 不要靠“先凑合着用再调”——slot 一旦创建就持续占资源,sender 连接失败会触发 client 重试风暴,加重主库负载
检查和调整前务必确认 WAL 归档与清理是否正常
这两个参数本质是在延长 WAL 的生命周期。如果 archive_mode = off 或 archive_command 失败,又开了大量 slot 或高 max_wal_senders,WAL 文件堆积速度会远超预期。
- 运行
SELECT * FROM pg_stat_archiver看归档是否卡住;用pg_ls_waldir()观察pg_wal/下文件数量趋势 - 物理复制中,备库延迟过大也会让主库不敢回收 WAL —— 此时调高参数只是掩盖问题,得先查
pg_stat_replication的replay_lag和网络、IO 瓶颈 - 测试环境容易忽略 checkpoint 间隔影响:过长的
checkpoint_timeout配合高写入,会让单次 checkpoint 产生的 WAL 更多,进一步加剧空间压力
实际改配置时,最常被跳过的一步是验证 WAL 清理是否真跟上了——参数调完了,pg_wal/ 还在涨,说明根本问题不在连接数,而在下游消费能力或归档链路。