如何在主从数据库节点间可靠传输WAL日志文件?
兄弟,这种网络时不时抽风的情况在跨机Docker部署主从复制时真的很闹心,结合你描述的场景——流式复制+WAL归档挂载宿主机+每日数次1分钟左右的网络中断,还有你提到的无法挂载从节点相关目录的限制,我给你几个针对性的解决方案:
调优复制超时参数,适配网络中断时长
默认的wal_receiver_timeout和wal_sender_timeout都是60秒,刚好和你的网络中断时长吻合,这会直接导致复制连接被主动断开。你可以把这两个参数调大到120秒(2分钟),给网络恢复留足缓冲:- 主节点
postgresql.conf修改:wal_sender_timeout = 120000 # 单位:毫秒,即2分钟 - 从节点
postgresql.conf修改:wal_receiver_timeout = 120000
修改后重启Docker容器生效:
docker restart postgres-master和docker restart postgres-slave。- 主节点
用WAL归档作为流式复制的兜底方案
既然你已经把WAL归档目录挂载到了宿主机,刚好可以利用归档复制来应对网络中断。因为你无法挂载从节点的相关目录,那可以让主节点主动把归档的WAL日志推送到从节点的宿主机归档目录:- 主节点配置
archive_command,用scp把WAL文件推送到从节点:
archive_command = 'scp %p your-slave-user@slave-ip:/path/to/slave-host-archive/%f'(记得提前配置主从节点的SSH免密登录,避免每次推送输入密码)
2. 从节点配置restore_command,从本地归档目录读取缺失的WAL:# PostgreSQL 12及以上版本直接写在postgresql.conf里 restore_command = 'cp /path/to/slave-host-archive/%f %p' # 12以下版本写在recovery.conf里这样当流式复制断开时,从节点会自动切换到归档日志同步,等网络恢复后,流式复制会自动重新连接(前提是你配置了自动重连)。
- 主节点配置
开启自动重连,减少人工干预
确保从节点的primary_conninfo里加上reconnect=1参数,让从节点在连接断开后自动尝试重连:primary_conninfo = 'host=master-ip port=5432 user=repl_user password=your-repl-pass reconnect=1'这个参数默认是开启的,但手动加上更保险,避免因为配置遗漏导致无法自动恢复。
添加简单监控,及时掌握复制状态
可以写个小脚本定时检查复制状态,出问题时及时告警。比如在从节点的宿主机上创建脚本check_repl.sh:#!/bin/bash REPL_STATUS=$(psql -U postgres -t -c "SELECT status FROM pg_stat_wal_receiver;" 2>/dev/null) if [ -z "$REPL_STATUS" ] || [ "$REPL_STATUS" != "streaming" ]; then echo "PostgreSQL replication is disconnected at $(date)" | mail -s "Replication Alert" your-email@example.com fi然后加到crontab里每分钟执行一次:
* * * * * /path/to/check_repl.sh这样网络中断导致复制断开时,你能第一时间收到通知,避免问题扩大。
内容的提问来源于stack exchange,提问作者nagylzs

