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在关键故障场景下的高可用能力,为生产环境部署提供了实践依据。

相关推荐
小陈工2 小时前
Python Web开发入门(十七):Vue.js与Python后端集成——让前后端真正“握手言和“
开发语言·前端·javascript·数据库·vue.js·人工智能·python
0xDevNull7 小时前
MySQL数据冷热分离详解
后端·mysql
科技小花7 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸7 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
D4c-lovetrain7 小时前
linux个人心得22 (mysql)
数据库·mysql
阿里小阿希7 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神8 小时前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle
做个文艺程序员8 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全
不吃香菜学java8 小时前
Redis简单应用
数据库·spring boot·tomcat·maven
一个天蝎座 白勺 程序猿8 小时前
Apache IoTDB(15):IoTDB查询写回(INTO子句)深度解析——从语法到实战的ETL全链路指南
数据库·apache·etl·iotdb