暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

主备switchover切换超时,主机降备卡了几个小时无法结束

原创 qi_yu 2024-12-25
25

发现版本

3.0.5 / 6.0.0

问题概述

在有压测的情况下,备库执行switchover切换失败,主机降备卡了几个小时无法结束
初始状态:opgsha01 主 / opgsha02 备
切换后查询集群状态:
image.png
image.png
数据库日志:
image.png
堆栈信息:
image.png

复现步骤

铺底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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论