编写Postgres升级脚本:如何检测Postgres 10集群复制及主备节点?
嘿,这个场景我之前在Postgres集群升级时碰到过,给你几个实用的方法,能直接集成到你的bash脚本里,用来检测主节点上的活跃备节点及其主机名:
方法1:查询Postgres内置视图
pg_stat_replication 这是最直接可靠的方式,因为它会实时返回当前连接到主节点的备节点信息。你可以用psql直接查询:
# 以postgres用户身份执行,返回备节点的IP和应用名(备节点的标识) psql -U postgres -t -c "SELECT client_addr, application_name FROM pg_stat_replication;"
-t参数会去掉表头和多余的格式,只返回纯数据行,方便脚本解析client_addr是备节点的IP地址,application_name通常是备节点的自定义标识(比如你在备节点postgresql.conf里设置的application_name)
如果要把IP解析为主机名,可以用host命令反向解析,比如在脚本里这么处理:
#!/bin/bash # 查询主节点的备节点信息 REPLICATION_DATA=$(psql -U postgres -t -c "SELECT client_addr, application_name FROM pg_stat_replication;") if [[ -n "$REPLICATION_DATA" ]]; then echo "当前主节点存在以下活跃备节点:" # 逐行处理查询结果 echo "$REPLICATION_DATA" | while read -r line; do # 跳过空行 [[ -z "$line" ]] && continue # 提取IP和应用名 client_ip=$(echo "$line" | awk '{print $1}') app_name=$(echo "$line" | awk '{print $2}') # 反向解析IP到主机名 hostname=$(host "$client_ip" | awk '/domain name pointer/ {print $NF}' | sed 's/\.$//') # 输出结果,处理无法解析的情况 if [[ -n "$hostname" ]]; then echo "- 主机名: $hostname | IP: $client_ip | 标识: $app_name" else echo "- IP: $client_ip | 标识: $app_name (无法解析主机名)" fi done else echo "当前主节点没有活跃的备节点" fi
方法2:结合
pg_replication_slots补充信息(可选) 如果你的集群用了复制槽(replication slots),可以结合pg_replication_slots视图来获取更完整的备节点信息,比如:
psql -U postgres -t -c "SELECT slot_name, client_addr, active FROM pg_replication_slots;"
这个视图能显示所有配置的复制槽,以及是否有活跃的备节点在使用它,适合排查那些配置了但未连接的备节点。
方法3:检查主节点的
pg_hba.conf(辅助验证) 备节点要连接主节点做复制,必须在主节点的pg_hba.conf里有对应的授权规则。你可以用grep筛选复制相关的条目:
grep -E "^host.*replication" /etc/postgresql/9.6/main/pg_hba.conf
这个命令会返回所有允许复制连接的规则,比如host replication replicator 192.168.1.0/24 md5,你可以从这里提取允许的IP段,再结合pg_stat_replication的结果交叉验证,确保没有遗漏的备节点。
注意事项
- 确保执行脚本的用户有访问Postgres的权限,最好直接用
postgres用户运行脚本 - Postgres 9.6和10.4的
pg_stat_replication视图结构是兼容的,所以这个查询在升级前后都能正常工作 - 如果备节点是通过主机名连接主节点的,
client_addr依然会显示备节点的IP,所以反向解析是获取主机名的必要步骤
内容的提问来源于stack exchange,提问作者Juan Jimenez
相关产品推荐
相关产品推荐

