InnoDB Cluster高可用测试实战:主从切换与故障恢复验证

在数据库运维场景中,高可用性是保障业务连续性的核心诉求。MySQL InnoDB Cluster作为官方推荐的高可用解决方案,通过集成MySQL Shell、MySQL Router和Group Replication,实现了集群的自动故障检测与主从切换能力。本文基于实际测试环境,详细记录InnoDB Cluster高可用测试的完整流程,验证集群在节点故障、机器宕机等场景下的自愈能力与数据一致性保障效果。

一、测试环境与前置准备

1. 集群拓扑

本次测试基于3节点InnoDB Cluster,节点信息如下,所有节点均部署MySQL 8.0版本,已通过Group Replication完成集群初始化:

节点名称 IP地址 端口 初始角色
maria-01 192.168.184.151 6446 Primary
maria-02 192.168.184.152 6446 Secondary
maria-03 192.168.184.153 6446 Secondary

2. 测试工具与账号

  • 管理工具:MySQL Shell(用于集群状态查询与管理)、Go语言(编写数据写入脚本)
  • 测试账号:mgr_user(具备集群管理与数据读写权限,密码:BgIka^123
  • 核心目标:验证集群在Primary节点故障Primary节点所在机器宕机场景下的自动切换能力,以及故障节点恢复后的集群重整合效果。

二、测试步骤1:搭建数据写入与监控环境

为模拟真实业务压力,需先构建持续数据写入场景,通过观察写入中断与恢复情况,直观判断集群高可用能力。

1. 登录Primary节点并创建测试数据

首先登录初始Primary节点(192.168.184.151),创建测试库、测试表,为后续数据写入做准备:

bash 复制代码
# 登录MySQL(通过Group Replication端口6446)
mysql -umgr_user -p'BgIka^123' -P6446 -h192.168.184.151

# 创建测试库maria
create database maria;
use maria;

# 创建测试表user_info(含自增ID、姓名、年龄、创建时间)
CREATE TABLE user_info (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255),
    age INT,
    created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
);

2. 编写Go语言数据写入脚本

通过Go语言编写定时写入脚本,实现每秒向user_info表插入1条数据,脚本会打印写入时间与错误信息,便于观察故障时的写入状态:

go 复制代码
package main

import (
    "database/sql"
    "fmt"
    "time"

    _ "github.com/go-sql-driver/mysql" // MySQL驱动
)

func main() {
    // 数据库连接配置(指向初始Primary节点)
    dbUser := "mgr_user"
    dbPass := "BgIka^123"
    dbIP := "192.168.184.151"
    dbPort := "6446"
    dbName := "maria"

    // 构建DSN(数据源名称)
    dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", dbUser, dbPass, dbIP, dbPort, dbName)
    fmt.Printf("连接信息:%s\n", dsn)

    // 建立数据库连接(defer确保程序退出时关闭连接)
    db, err := sql.Open("mysql", dsn)
    if err != nil {
        panic("数据库连接失败:" + err.Error())
    }
    defer db.Close()

    // 定时任务:每秒插入1条数据
    ticker := time.NewTicker(1 * time.Second)
    defer ticker.Stop()

    for range ticker.C {
        // 插入数据(姓名固定为John Doe,年龄固定为30)
        insertQuery := "INSERT INTO user_info (name, age) VALUES (?, ?)"
        _, err := db.Exec(insertQuery, "John Doe", 30)
        if err != nil {
            fmt.Printf("[%s] 写入失败:%s\n", time.Now().Format("2006-01-02 15:04:05"), err.Error())
            continue
        }
        fmt.Printf("[%s] 数据写入成功\n", time.Now().Format("2006-01-02 15:04:05"))
    }
}

3. 运行脚本并验证数据写入

将脚本在测试机上编译运行,同时在Primary节点查询数据,确认写入正常:

bash 复制代码
# 运行Go脚本(需提前安装Go环境与MySQL驱动)
go run insert_data.go

# 在Primary节点查询数据
mysql -umgr_user -p'BgIka^123' -P6446 -h192.168.184.151 -e "use maria; select count(*) from user_info;"

正常情况下,脚本会每秒打印"数据写入成功",查询结果显示user_info表数据量持续增长。

三、测试步骤2:Primary节点故障场景验证

1. 查看初始集群状态

通过MySQL Shell连接集群,确认初始Primary节点为maria-01(192.168.184.151):

bash 复制代码
# 登录MySQL Shell
mysqlsh -umgr_user -p'BgIka^123' -h192.168.184.151

# 获取集群对象并查询状态
var cluster = dba.getCluster('Cluster01')
cluster.status();

输出结果中,maria-01role字段为PRIMARYmaria-02maria-03SECONDARY,集群状态为OK

2. 停止Primary节点MySQL服务

在192.168.184.151节点上停止MySQL服务,模拟Primary节点故障:

bash 复制代码
# 停止MySQL服务(基于初始化脚本的启停命令)
/etc/init.d/mysql.server stop

3. 观察数据写入与集群切换

  • 数据写入状态 :观察Go脚本输出,会短暂打印"写入失败"(约1-2秒),随后自动恢复正常写入------这是因为InnoDB Cluster检测到Primary故障后,会自动从Secondary节点中选举新的Primary。

  • 验证新Primary节点:重新通过MySQL Shell连接集群(需连接其他正常节点,如192.168.184.152),查询集群状态:

    bash 复制代码
    # 连接到maria-02节点
    mysqlsh -umgr_user -p'BgIka^123' -h192.168.184.152
    
    # 查看集群状态
    var cluster = dba.getCluster('Cluster01')
    cluster.status();

    输出显示:maria-02已切换为新的Primary节点,maria-01状态变为MISSING

4. 恢复故障节点并验证重整合

在192.168.184.151节点上重启MySQL服务,观察集群是否自动将其重整合为Secondary节点:

bash 复制代码
# 重启MySQL服务
/etc/init.d/mysql.server start

# 再次查询集群状态
cluster.status();

结果显示:maria-01已恢复为Secondary节点,集群状态回到OK,数据写入持续正常(无丢失)。

四、测试步骤3:Primary节点所在机器宕机场景验证

1. 确认当前Primary节点

延续上一步测试结果,当前Primary节点为maria-02(192.168.184.152),先通过cluster.status()确认节点状态正常。

2. 关闭Primary节点所在机器

在192.168.184.152节点上执行关机命令,模拟更极端的"机器宕机"故障:

bash 复制代码
# 关闭机器(需谨慎操作,仅测试环境执行)
shutdown -h now

3. 观察故障切换与数据一致性

  • 数据写入状态 :Go脚本会短暂中断(约2-3秒),随后恢复正常写入------证明集群在"机器宕机"场景下仍能完成故障检测与切换。

  • 验证新Primary节点 :连接到maria-01(192.168.184.151),查询集群状态:

    bash 复制代码
    mysqlsh -umgr_user -p'BgIka^123' -h192.168.184.151
    var cluster = dba.getCluster('Cluster01')
    cluster.status();

    输出显示:maria-03已成为新的Primary节点,maria-02状态为MISSING

4. 恢复宕机机器并验证集群状态

启动192.168.184.152节点,待机器正常启动后,查看集群是否自动将其重整合:

bash 复制代码
# 机器启动后,查询集群状态
cluster.status();

结果显示:maria-02已恢复为Secondary节点,集群重新回到3节点正常状态,user_info表数据无丢失(通过select count(*)对比故障前后数据量可验证)。

注:若maria-02重启后,查看集群状态出现如下情况,可以登录maria-02的MySQL,然后执行start group_replication;命令开启组复制,从而使得maria-02在集群内正常运行。

五、测试结论与核心发现

  1. 高可用能力验证通过 :InnoDB Cluster在"Primary节点服务停止"和"Primary节点机器宕机"两种场景下,均能在3秒内完成故障检测与自动切换,数据写入仅短暂中断,无数据丢失,满足业务连续性要求。
  2. 故障节点自动重整合:故障节点(或机器)恢复后,集群会自动将其重整合为Secondary节点,无需人工干预,降低运维成本。
  3. 角色选举逻辑稳定:集群始终从健康的Secondary节点中选举新Primary,选举结果符合Group Replication的"多数派存活"原则(3节点集群需至少2个节点健康)。

六、注意事项与优化建议

  1. 生产环境需配置MySQL Router:本次测试直接连接节点IP,生产环境建议部署MySQL Router作为入口,实现"读写分离"与"自动路由到新Primary",避免客户端直接感知节点变化。
  2. 监控集群状态 :需通过Prometheus+Grafana等工具监控集群状态(如cluster.status()、节点存活状态、复制延迟),及时发现潜在故障。
  3. 测试频率:建议每季度执行一次高可用测试,验证集群配置未因版本更新、参数调整而失效。

通过本次测试,充分验证了InnoDB Cluster在关键故障场景下的高可用能力,为生产环境部署提供了实践依据。

相关推荐
茁壮成长的露露10 小时前
MongoDB分片案例
数据库·mongodb
小北方城市网10 小时前
Spring Boot 接口开发实战:RESTful 规范、参数校验与全局异常处理
java·jvm·数据库·spring boot·后端·python·mysql
AllData公司负责人10 小时前
【亲测好用】数据集成管理能力演示
java·大数据·数据库·开源
brevity_souls10 小时前
SQL Server 窗口函数简介
开发语言·javascript·数据库
倚-天-照-海10 小时前
Doris数据库基本概念
数据库
翼龙云_cloud10 小时前
阿里云渠道商:cpu 弹性扩容有哪些限制条件?
数据库·阿里云·云计算
陈聪.10 小时前
HRCE简单实验
linux·运维·数据库
APIshop10 小时前
实战代码解析:item_get——获取某鱼商品详情接口
java·linux·数据库
洛_尘10 小时前
MySQL 5:增删改查操作
数据库·mysql
老邓计算机毕设11 小时前
SSM养老院老人健康信息管理系统t4p4x(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·计算机毕业设计·ssm 框架·养老院老人健康管理系统