发现版本
3.0.5 / 6.0.0
问题概述
在有压测的情况下,备库执行switchover切换失败,主机降备卡了几个小时无法结束
初始状态:opgsha01 主 / opgsha02 备
切换后查询集群状态:


数据库日志:

堆栈信息:

复现步骤
铺底300G数据,并发200执行insert操作,执行脚本,主备不断切换(需判断主备状态正常才可切换)
问题原因
在swichover时,如果出现大量业务,且切换时间很快,可能会出现业务线程还没来得及接收SIGTERM的情况,导致正常做业务无法退出
修复方案
在状态机进行状态检测时,去进一步的杀后台线程
目前已在3.0.6修复
附:switchover复现脚本
#!/bin/bash
# 定义变量
PRIMARY_HOST="197.x.x.x" # 主节点IP地址或主机名
STANDBY_HOST="197.x.x.x" # 备节点IP地址或主机名
DATA_DIR="/gaussdata/xxx/xxx" # 数据目录
SSH_USER="omm" # 用于SSH登录的用户名
MAX_RETRIES=10000 # 最大重试次数
RETRY_DELAY=0 # 每次重试之间的延迟时间(秒)
# 查询OpenGauss角色的函数
check_role_remote() {
local CHECK_INTERVAL=3
local host=$1
local expected_role=$2
while true; do
role=$(ssh "$SSH_USER@$host" "gs_ctl query | grep 'local_role' | sed 's/.*: *//'|head -n 1")
state=$(ssh "$SSH_USER@$host" "gs_ctl query | grep 'db_state' | sed 's/.*: *//'")
# 检查role是否为expected_role
if [ "$role" == "$expected_role" ]; then
# 检查db_state是否为Normal
if [ "$state" == "Normal" ]; then
echo "$(date): $host DB State is $state and local is $role, initiating switchover..."
# 可执行switchover操作
return 0
# 如果db_state不是Normal,则继续循环检查
else
echo "$(date): $host DB State is $state , continuing to check..."
sleep 1s
fi
# 如果role不是expected_role,则可能是集群配置有误或主备关系未建立,需要人工干预
else
echo "$(date): Role is not expected_role ($role), manual intervention may be required."
break # 退出循环,因为这种情况下通常不会自动恢复
fi
# 等待指定的检查间隔后再继续检查
sleep $CHECK_INTERVAL
done
}
# 主循环
retry_count=0
while true; do
# 检查主备节点是否正常
if ! check_role_remote "$PRIMARY_HOST" "Primary"; then
echo "$PRIMARY_HOST is not primary."
exit 1
fi
if ! check_role_remote "$STANDBY_HOST" "Standby"; then
echo "$STANDBY_HOST is not standby."
exit 1
fi
if [[ $retry_count -ge $MAX_RETRIES ]]; then
echo "Reached maximum number of retries. Exiting."
exit 1
fi
echo "Starting switchover from primary to standby..."
# 备节点上执行切换
ssh "$SSH_USER@$STANDBY_HOST" gs_ctl switchover -D "$DATA_DIR"
# 等待一段时间以确保切换完成
sleep 5s
# 检查备节点是否已成为新的主节点
if ! check_role_remote "$STANDBY_HOST" "Primary"; then
echo "Failed to switch to new primary on standby node. Exiting."
exit 1
fi
# 检查主节点是否已成为备节点
if ! check_role_remote "$PRIMARY_HOST" "Standby"; then
echo "Failed to switch to standby on primary node. Exiting."
exit 1
fi
# 交换主备角色
PRIMARY_HOST_TEMP=$PRIMARY_HOST
PRIMARY_HOST=$STANDBY_HOST
STANDBY_HOST=$PRIMARY_HOST_TEMP
echo "PRIMARY_HOST=$PRIMARY_HOST"
echo "STANDBY_HOST=$STANDBY_HOST"
# 再次等待一段时间以确保切换完成
sleep 3s
# 增加重试计数器
retry_count=$((retry_count + 1))
# 等待一段时间再进行下一次切换
echo "Switchover completed successfully. Waiting for $RETRY_DELAY seconds before next iteration."
sleep "$RETRY_DELAY"
echo "The Switchover has been performed $retry_count times."
done
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




