在PostgreSQL流复制架构中,级联复制是一种将备库进一步作为上游节点向其他备库分发WAL日志的方式。处于中间的节点同时承担两种角色:它从主库接收WAL流,并将其持久化到本地,同时允许下游备库通过复制协议连接并从它这里继续获取WAL。这种设计能显著降低主库上WAL发送进程的数量,减轻主库的CPU和网络压力,适合需要多只读备库或分层容灾的场景。

但中间节点并非简单地把主库参数复制一份。因为它在恢复模式下还要对外提供复制服务,所以会涉及恢复状态下的连接许可、WAL发送器预留、复制槽管理以及连接信息匹配等问题。本文从架构定位、参数配置和验证排查三个角度,详细梳理中间节点的配置要点。
一、级联复制中中间节点的双重角色
PostgreSQL的流复制基于WAL发送进程和WAL接收进程。主库上的wal sender进程负责把预写日志按顺序发送给每一个直接连接的备库。当备库数量增多时,每个备库都会在主库上占有一个wal sender,这对主库的资源消耗是线性增长的。级联复制通过把一些备库挂到某个备库下,让这个备库承担部分wal sender职责。
中间节点从主库接收WAL时,自己是备库身份,运行wal receiver进程;向下游发送WAL时,它又充当主库角色,运行wal sender进程。这两个角色并不冲突,但要注意中间节点只有在恢复模式下才能同时完成这两件事。恢复模式意味着数据库不会接受普通写事务,而是持续应用从上游收到的WAL。下游备库连接上来时,中间节点需要从本地已接收并写入的WAL文件中把日志流式传送出去,这就要求本地已经落盘的WAL不能过早被清理。
不同PostgreSQL版本在恢复模式的表达上有差异。较老版本使用recovery.conf文件,文件中的standby_mode=on表示进入备用恢复状态。较新版本则改用standby.signal空文件作为标记,连接信息统一放到postgresql.auto.conf中。理解这种差异对排查中间节点未进入恢复模式或未能正确连接上游的问题很有帮助。
二、中间节点关键参数配置
中间节点作为备库,首先需要设置wal_level。为了让下游能通过流复制连接,wal_level至少需要设置为replica。如果整个拓扑中有逻辑复制需求,可以设置为logical,但会产生更多WAL,需要根据实际场景权衡。max_wal_senders参数控制该节点最多能同时向多少个下游发送WAL,中间节点需要为每个下游预留一个发送器,同时还要考虑自身将来可能作为主库时的扩展。
下面是中间节点postgresql.conf中与级联复制相关的核心参数示例:
# postgresql.conf 中间节点核心参数 wal_level = replica max_wal_senders = 10 max_wal_replication_slots = 10 hot_standby = on listen_addresses = '*' port = 5432
其中hot_standby开启后,中间节点可以在恢复状态下接受只读查询,这对将中间节点同时用于读写分离的场景非常有用。如果仅作为纯复制中继,也可以关闭hot_standby以节省资源。listen_addresses需要确保下游节点能够通过网络访问到该节点。
中间节点还需要配置与上游主库的连接信息。以较新版本为例,需要在数据目录下创建standby.signal文件,并在postgresql.auto.conf中设置primary_conninfo。如果希望使用复制槽保证主库不会清理尚未发送给中间节点的WAL,可以在上游为中间节点创建一个复制槽,并在primary_slot_name中指定槽名。
# 在中间节点数据目录执行 touch standby.signal # 编辑 postgresql.auto.conf primary_conninfo = 'host=192.168.1.10 port=5432 user=replica_user password=secret application_name=mid_standby' primary_slot_name = 'mid_standby_slot'
pg_hba.conf的配置同样关键。中间节点必须允许下游节点以replication角色连接,否则下游在建立复制连接时会被拒绝。下面是一个允许同一网段下游节点复制的示例:
# pg_hba.conf 允许下游节点复制连接 host replication replica_user 192.168.2.0/24 scram-sha-256
这里replica_user是专用于复制的数据库角色,需要具备REPLICATION权限。IP网段需根据实际下游节点所在网络进行调整。如果下游节点通过主机名连接,也可以使用hostssl或合适的认证方式。配置完成后需要重载配置使pg_hba.conf生效。
还有一个容易遗漏的点:如果中间节点也使用复制槽为下游保留WAL,需要在中间节点上创建对应的复制槽,并在下游的primary_slot_name中指定。中间节点上的max_replication_slots参数要大于计划创建的槽数量。复制槽可以防止WAL被清理,但如果下游长时间离线,可能导致中间节点磁盘占用增大,因此需要结合max_slot_wal_keep_size或监控进行管理。
三、下游备库接入与验证
下游备库的初始化可以使用pg_basebackup从中间节点拉取基础备份,也可以先通过其他方式恢复一个基础备份,然后指向中间节点。以pg_basebackup为例,在目标机器上执行:
# 从中间节点初始化下游备库 pg_basebackup -h 192.168.2.10 -p 5432 -U replica_user -D /var/lib/postgresql/data -R -X stream -C -S downstream_slot
这里-h指定中间节点地址,-D指定目标数据目录,-R会自动生成standby.signal和postgresql.auto.conf中的连接信息,-X stream表示使用流式WAL传输,-C -S在中间节点上创建名为downstream_slot的复制槽并启用。初始化完成后,启动下游备库,它会通过primary_conninfo连接中间节点并开始接收WAL。
验证级联链路是否正常,可以在主库和中间节点上查询pg_stat_replication视图。例如在中间节点上执行:
SELECT application_name, state, sync_state, write_lag, flush_lag, replay_lag FROM pg_stat_replication;
如果下游备库已经连接,application_name会显示对应名称,state通常为streaming,表示WAL流正在正常发送。write_lag、flush_lag和replay_lag可以帮助判断下游的延迟情况。如果state长时间为startup或catchup,需要检查下游是否在追赶WAL,或者是否存在网络瓶颈。
在中间节点本机,可以通过函数查看自身作为备库的接收和应用状态:
SELECT pg_last_wal_receive_lsn() AS receive_lsn,
pg_last_wal_replay_lsn() AS replay_lsn,
pg_is_in_recovery();
pg_is_in_recovery()返回true说明中间节点仍处于恢复模式,这是级联复制中间节点正常工作的前提。如果返回false,说明该节点已被提升为主库或配置有误。
除了视图和函数,日志也是排查问题的重要来源。启动下游备库时,如果连接被拒绝,通常会在日志中看到类似FATAL: replication connection authorized或max_wal_senders相关的错误。根据错误信息检查pg_hba.conf、复制用户权限以及中间节点的最大发送数即可定位大部分问题。
四、维护与故障转移注意事项
级联复制中的中间节点一旦宕机,其下游所有备库都会失去WAL来源,因此中间节点的可用性比普通备库更关键。生产环境中建议对中间节点配置监控,关注其WAL接收延迟、磁盘空间和复制槽状态。如果中间节点被提升为新主库,下游备库的primary_conninfo不会自动切换,需要手动修改下游连接信息,或者借助Patroni、repmgr等工具实现自动故障转移和拓扑切换。
如果使用同步复制,需要明确synchronous_standby_names只作用于直接连接的备库。对于级联拓扑,主库只能将中间节点作为同步备库候选,下游备库的同步状态不能跨级传递。因此在需要强一致性的场景中,要么让关键备库直连主库,要么接受下游异步复制的可能数据丢失窗口。
复制槽虽然能防止WAL被提前清理,但也会带来磁盘膨胀风险。中间节点上为下游创建的复制槽如果长期没有活动消费者,WAL会不断累积,最终可能写满磁盘。建议定期检查pg_replication_slots视图中的active和restart_lsn,设置磁盘使用率告警,并在确认下游已永久离线后及时删除对应槽。
日常维护中还要注意级联链路上的时间线一致性。主库执行时间线切换后,中间节点和下游备库需要跟随新的时间线。如果手动操作不当,可能出现时间线分歧导致下游无法继续复制。使用pg_basebackup重新初始化乱掉的下游往往是最简单的恢复方式,但代价是传输整个数据目录,因此提前规划恢复策略很有必要。
PostgreSQL级联复制流复制中间节点配置修改时间:2026-08-19 18:44:10