You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Patroni集群切换辅助:如何编写自动化shell脚本实现切主后重启副本

Patroni 集群Switchover自动重启副本Shell脚本实现方案

脚本核心执行流程

整个脚本按照「校验→切换→等待→识别→重启→二次校验」的逻辑设计,避免异常操作影响集群可用性:

  • 前置校验:检查集群健康状态,确认所有节点在线、无同步延迟,满足switchover条件
  • 执行主节点切换:调用你已掌握的curl命令完成主节点晋升
  • 等待集群状态收敛:等待新主状态变为running,所有副本同步追平新主的WAL日志
  • 识别副本节点:调用Patroni集群API拉取节点列表,过滤出所有非主的副本节点
  • 滚动重启副本:逐个重启副本节点,每重启一个节点等待它重新加入集群、同步完成后再操作下一个,避免集群失去多数派
  • 最终状态校验:重启完成后检查整个集群的角色、同步状态是否符合预期

核心功能代码说明

前置依赖

建议提前安装jq工具用于解析Patroni返回的JSON数据,Debian/Ubuntu可直接执行apt install jq安装,CentOS/RHEL可执行yum install jq安装。

关键命令片段

  1. 拉取集群节点列表,筛选所有副本节点
# 替换为你的Patroni任意节点的API地址,默认端口为8008
PATRONI_API="http://10.0.0.1:8008"
# 过滤出所有副本节点的主机名
REPLICA_NODES=$(curl -s ${PATRONI_API}/cluster | jq -r '.members[] | select(.role == "replica") | .name')
  1. 单个副本节点重启(两种方式二选一)
# 方式1:通过Patroni API重启指定节点,替换为对应节点的API地址
curl -s -X POST http://${replica_ip}:8008/restart
# 方式2:如果本地安装了patronictl,可直接调用命令重启
patronictl -c /etc/patroni/patroni.yml restart ${cluster_name} ${replica_node_name} --force
  1. 等待节点恢复逻辑
# 等待最多300秒,直到节点重新加入集群且同步状态正常
wait_second=0
while true; do
    role=$(curl -s ${PATRONI_API}/cluster | jq -r --arg node "${replica_node_name}" '.members[] | select(.name == $node) | .role')
    state=$(curl -s ${PATRONI_API}/cluster | jq -r --arg node "${replica_node_name}" '.members[] | select(.name == $node) | .state')
    if [ "${role}" == "replica" ] && [ "${state}" == "running" ]; then
        echo "节点${replica_node_name}重启完成,已正常同步"
        break
    fi
    if [ ${wait_second} -ge 300 ]; then
        echo "节点${replica_node_name}重启超时,请手动检查状态"
        exit 1
    fi
    sleep 5
    wait_second=$((wait_second+5))
done

完整脚本示例

#!/bin/bash
set -euo pipefail

# 配置项,根据你的集群实际情况修改
PATRONI_API="http://10.0.0.1:8008"
CLUSTER_NAME="patroni-cluster"
NEW_MASTER="$1"

# 前置参数校验
if [ $# -ne 1 ]; then
    echo "用法:$0 <目标新主节点名称>"
    exit 1
fi

# 步骤1:校验集群状态
echo "1/6 检查集群健康状态..."
cluster_health=$(curl -s ${PATRONI_API}/health | jq -r '.state')
if [ "${cluster_health}" != "running" ]; then
    echo "集群当前状态异常,无法执行switchover"
    exit 1
fi

# 步骤2:执行switchover
echo "2/6 执行主节点切换到${NEW_MASTER}..."
# 这里替换为你已经掌握的switchover curl命令
curl -s -X POST ${PATRONI_API}/switchover -d "{\"leader\": \"$(curl -s ${PATRONI_API}/leader | jq -r '.name')\", \"candidate\": \"${NEW_MASTER}\"}" -H "Content-Type: application/json"

# 步骤3:等待集群状态收敛
echo "3/6 等待集群状态稳定..."
sleep 10
wait_cluster=0
while true; do
    current_leader=$(curl -s ${PATRONI_API}/leader | jq -r '.name')
    if [ "${current_leader}" == "${NEW_MASTER}" ]; then
        echo "主节点切换完成,当前主节点为${NEW_MASTER}"
        break
    fi
    if [ ${wait_cluster} -ge 120 ]; then
        echo "主节点切换超时,请手动检查集群状态"
        exit 1
    fi
    sleep 5
    wait_cluster=$((wait_cluster+5))
done

# 步骤4:识别所有副本节点
echo "4/6 识别集群副本节点..."
REPLICA_NODES=$(curl -s ${PATRONI_API}/cluster | jq -r '.members[] | select(.role == "replica") | .name')
echo "当前待重启副本节点:${REPLICA_NODES}"

# 步骤5:滚动重启副本节点
echo "5/6 开始滚动重启副本节点..."
for replica in ${REPLICA_NODES}; do
    echo "正在重启副本节点${replica}..."
    # 替换为你实际使用的重启命令
    curl -s -X POST http://${replica}:8008/restart
    # 等待节点恢复
    wait_replica=0
    while true; do
        state=$(curl -s ${PATRONI_API}/cluster | jq -r --arg node "${replica}" '.members[] | select(.name == $node) | .state')
        if [ "${state}" == "running" ]; then
            echo "节点${replica}重启完成,已正常加入集群"
            break
        fi
        if [ ${wait_replica} -ge 300 ]; then
            echo "节点${replica}重启超时,请手动检查"
            exit 1
        fi
        sleep 5
        wait_replica=$((wait_replica+5))
    done
done

# 步骤6:最终校验
echo "6/6 校验集群最终状态..."
curl -s ${PATRONI_API}/cluster | jq '.members[] | {name: .name, role: .role, state: .state, lag: .lag}'
echo "Switchover及副本重启操作全部完成"

注意事项

  • 脚本所有配置项需要根据你的集群实际IP、端口、集群名称调整,本地需要能访问所有Patroni节点的8008端口
  • 首次执行前建议在测试集群逐行验证命令逻辑,确认符合预期再全量执行
  • 如果你的Patroni开启了API认证,需要在curl命令中增加-u 用户名:密码参数
  • 滚动重启逻辑避免了同时重启多个副本的问题,保证集群始终有至少1个副本在线,不会影响集群可用性

内容的提问来源于stack exchange,提问作者ljunplugged

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 10:36:05