目录

前言

1. MHA 简介

2. MHA 组件组成

2.1 MHA Manager(管理节点)

2.2 MHA Node(数据节点)

3. MHA 的作用(特点)

3.1 快速自动故障切换

3.2 数据一致性保障

3.3 透明化运维

3.4 灵活的架构适配

3.5 轻量级部署

4. MHA 工作原理

5. 实战 MHA

5.1 实验思路

5.2 实验环境

5.3 准备工作

5.4 安装 MHA 所有组件与测试

5.4.1 安装 MySQL 5.7(仅 mysql1、mysql2、mysql3 节点)

5.4.2 搭建一主两从复制(mysql1 为主库,mysql2、mysql3 为从库)

5.4.3 安装 MHA 组件

5.4.4 配置 SSH 无密码认证(关键步骤)

5.4.5 配置 MHA Manager(仅 Manager 节点)

5.4.6 手动绑定初始 VIP(主库 mysql1 节点)

5.4.7 测试 MHA 配置有效性

5.4.8 启动 MHA Manager 服务

5.4.9 查看 MHA 状态

5.4.10 查看 MHA 日志

5.4.11 查看主库 VIP 状态

5.4.12 关闭 MHA Manager 服务

5.5 故障模拟与恢复

5.5.1 模拟主库故障(mysql1 节点)

5.5.2 观察故障切换过程(Manager 节点)

5.5.3 验证切换结果

5.5.4 故障主库恢复并重新加入集群(mysql1 节点)

6. 总结

前言

在数据库运维领域,主库单点故障是威胁服务连续性的“心腹大患”,一旦主库宕机,若无法快速恢复服务,将直接影响业务正常运转。MySQL 作为主流关系型数据库,其高可用方案的选型与落地至关重要。MHA(Master High Availability)凭借“快速自动故障切换+数据一致性保障”的核心优势,成为中小规模 MySQL 集群的经典高可用方案。本文将从理论到实战,系统拆解 MHA 的核心原理,并结合“一主两从”架构的完整部署流程,带大家亲手验证故障自动切换的全过程,为实际生产环境的落地提供可复现的参考。

1. MHA 简介

MHA(Master High Availability)是一套专为 MySQL 设计的高可用解决方案,核心目标是解决 MySQL 主库单点故障问题,实现故障发生时的快速自动切换并最大程度保障数据一致性。作为基于主从复制架构的高可用方案,MHA 由日本开发者 Yoshinori Matsunobu 设计开发,凭借其成熟稳定的特性在工业界得到广泛应用。

MHA 的核心价值在于故障切换的高效性和数据一致性保障——其自动故障切换过程可在 0-30 秒内完成,远超人工切换的响应速度;同时通过二进制日志补救机制,能最大程度减少主库宕机时的数据丢失风险。需要注意的是,MHA 通常要求集群采用一主多从架构,官方建议最少部署 3 个节点(一主两从),经淘宝等企业改造后也可支持一主一从架构。

2. MHA 组件组成

MHA 架构由 MHA Manager(管理节点)MHA Node(数据节点) 两个核心组件构成,二者协同工作实现高可用能力。所有节点(包括 Manager 节点)均需安装 Node 组件,Manager 节点额外安装 Manager 组件,具体分工如下:

2.1 MHA Manager(管理节点)

作为 MHA 集群的控制中心,MHA Manager 负责集群状态监控、故障检测与自动故障切换的统筹协调。其核心功能包括:定时探测主库健康状态、在主库故障时筛选最优备选主库、执行主从切换流程、管理虚拟 IP(VIP)漂移等。Manager 节点可独立部署在专用服务器上,也可部署在某个从库节点上,支持同时管理多个 MySQL 主从集群。

Manager 节点安装后会在 /usr/local/bin 目录生成一系列核心工具,用于执行各类管理操作,关键工具及功能如下表所示:

工具名称

核心功能

masterha_check_ssh

检查集群所有节点间的 SSH 免密认证配置有效性

masterha_check_repl

检查 MySQL 主从复制状态,验证复制链路完整性

masterha_manager

启动 MHA Manager 服务的核心脚本,默认前台运行

masterha_check_status

查看当前 MHA Manager 服务的运行状态

masterha_master_monitor

单独执行主库状态探测,验证主库可用性

masterha_master_switch

手动触发故障切换,支持指定新主库

masterha_stop

停止 MHA Manager 服务

2.2 MHA Node(数据节点)

MHA Node 组件需部署在所有 MySQL 服务器(主库、从库)及 Manager 节点上,主要负责执行具体的数据操作任务,如二进制日志保存、中继日志应用、故障节点恢复等。这些操作通常由 Manager 节点的工具触发,无需人工直接调用。

Node 组件安装后在 /usr/local/bin 目录生成的关键工具如下:

工具名称

核心功能

save_binary_logs

从故障主库保存未同步的二进制日志,减少数据丢失

apply_diff_relay_logs

识别从库间的中继日志差异,并将差异部分应用到其他从库

purge_relay_logs

安全清除中继日志,避免占用过多磁盘空间,且不阻塞 SQL 线程

3. MHA 的作用(特点)

MHA 作为成熟的 MySQL 高可用方案,其核心作用体现在保障服务连续性和数据一致性两个维度,具体具备以下关键特点:

3.1 快速自动故障切换

MHA 可实时监控主库状态,当主库发生宕机、网络中断等故障时,能在 0-30 秒内自动完成故障切换流程——包括筛选最优备选主库、提升从库为主库、调整其他从库复制指向、VIP 漂移等操作,全程无需人工干预,极大缩短服务不可用时间。

3.2 数据一致性保障

这是 MHA 最核心的优势之一。当主库故障时,MHA 会尝试通过 SSH 连接故障主库,利用 save_binary_logs 工具保存未同步的二进制日志;若无法连接故障主库,会选择拥有最新中继日志的从库作为备选主库,并通过 apply_diff_relay_logs 工具将差异日志同步到其他从库,确保所有节点数据一致。若配合 MySQL 半同步复制使用,可进一步降低数据丢失风险。

3.3 透明化运维

MHA 基于虚拟 IP(VIP)提供服务访问,故障切换时 VIP 会自动从故障主库漂移到新主库,应用程序只需配置 VIP 作为数据库连接地址,无需修改任何配置即可持续访问服务,实现故障切换对应用透明。

3.4 灵活的架构适配

MHA 支持标准的一主多从架构,同时可通过自定义脚本扩展功能;Manager 节点支持管理多个集群,降低运维成本;经改造后可支持一主一从架构,适配不同规模的业务场景。此外,MHA 对 MySQL 版本兼容性良好,支持 MySQL 5.5 及以上版本(实战中推荐 5.7 及以上)。

3.5 轻量级部署

MHA 基于 Perl 开发,无需部署额外的守护进程(除 Manager 服务外),组件安装简单,对服务器资源占用低,不会显著增加集群的性能开销。

4. MHA 工作原理

MHA 的工作流程以 Manager 节点为核心,围绕主库状态监控、故障检测、故障切换三个阶段展开,核心逻辑是通过智能筛选最优从库并同步数据差异,实现主库的无缝切换,具体步骤如下:

  1. 状态监控阶段:MHA Manager 通过定时发送 ping 命令和 MySQL 连接请求监控主库状态,默认每 3 秒探测一次;同时通过 masterha_check_repl 工具定期验证主从复制链路的完整性。

  2. 故障检测阶段:当 Manager 连续三次(可配置)无法连接主库或收到主库宕机的反馈时,判定主库发生故障,立即触发故障切换流程。

  3. 故障切换阶段:这是 MHA 工作的核心阶段,细分为以下步骤: 日志补救:Manager 尝试通过 SSH 连接故障主库,使用 save_binary_logs 工具保存主库未同步到从库的二进制日志;若无法连接故障主库,则跳过此步骤,直接基于从库中继日志进行数据同步。

  4. 备选主库筛选:Manager 检查所有从库的复制状态,筛选出拥有最新数据(中继日志最完整)的从库作为备选主库;若多个从库数据一致,可通过配置文件指定优先级。

  5. 提升新主库:将备选主库的只读模式(read_only)关闭,使其成为可写主库;同时执行 reset master 清除其从库标识,生成新的二进制日志。

  6. 从库重新指向:Manager 对其他从库执行 change master to 命令,将其复制指向切换为新主库,并通过 apply_diff_relay_logs 工具同步差异日志,确保所有从库与新主库数据一致。

  7. VIP 漂移:通过预配置的 IP 故障转移脚本(master_ip_failover),将虚拟 IP 从故障主库解绑并绑定到新主库,确保应用程序通过 VIP 可正常访问新主库。

  8. 故障通知:通过邮件或自定义脚本将故障切换结果通知运维人员,包括故障主库信息、新主库信息、切换耗时等。

  9. 恢复后整合阶段:当故障主库修复后,可通过 masterha_conf_host 工具将其重新加入集群,配置为新主库的从库,恢复一主两从架构。

5. 实战 MHA

本实战基于“一主两从 + 独立 Manager 节点”架构,严格遵循“干净环境”要求,从环境准备到故障模拟全程实操,确保每一步可复现。

5.1 实验思路

实验核心目标是搭建可自动故障切换的 MHA 集群,验证主库故障时的自动切换能力及故障主库恢复后的重新整合能力,整体流程分为三个阶段:

  1. 基础环境构建:配置 4 台干净的 CentOS7.6 服务器,关闭防火墙、SELinux 等干扰项,确保网络互通;在 3 台服务器上安装 MySQL5.7 并搭建一主两从复制架构。

  2. MHA 集群搭建:在所有节点安装 MHA 组件,配置 SSH 免密认证,编写 MHA 配置文件,启动 Manager 服务并验证集群状态。

  3. 故障模拟与恢复:手动停止主库服务模拟故障,观察 MHA 自动切换过程;修复故障主库后,将其重新加入集群作为从库。

5.2 实验环境

实验采用 4 台 CentOS7.6(64 位)服务器,硬件配置建议 2C4G 及以上,确保网络互通(同一局域网),具体节点信息如下:

节点角色

主机名

IP 地址

安装组件

核心软件版本

MHA Manager

manager

192.168.10.101

MHA Node + MHA Manager

MHA 0.57

Master 主库

mysql1

192.168.10.102

MySQL 5.7 + MHA Node

MySQL 5.7.44、MHA 0.57

Slave1 从库(备选主库)

mysql2

192.168.10.103

MySQL 5.7 + MHA Node

MySQL 5.7.44、MHA 0.57

Slave2 从库

mysql3

192.168.10.104

MySQL 5.7 + MHA Node

MySQL 5.7.44、MHA 0.57

虚拟 IP(VIP):192.168.10.200(用于应用程序访问数据库)

5.3 准备工作

所有节点执行以下操作,确保环境干净无干扰:

  1. 关闭防火墙与 SELinux

    # 关闭防火墙并设置开机不自启
    systemctl stop firewalld
    systemctl disable firewalld
    
    # 关闭 SELinux(永久生效,需重启)
    sed -i 's/^SELINUX=.*/SELINUX=disabled/g' /etc/sysconfig/selinux
    
    # 重启服务器使 SELinux 配置生效
    reboot
     
    
  2. 配置主机名与 hosts 解析: 

    以下是根据要求生成的节点主机名设置和 hosts 文件配置的代码片段:

    设置各节点主机名

    # manager 节点
    hostnamectl set-hostname manager
    
    # mysql1 节点
    hostnamectl set-hostname mysql1
    
    # mysql2 节点
    hostnamectl set-hostname mysql2
    
    # mysql3 节点
    hostnamectl set-hostname mysql3
    

    配置所有节点的 hosts 解析

    vim /etc/hosts
    

    在打开的编辑器中添加以下内容:

    192.168.10.101 manager
    192.168.10.102 mysql1
    192.168.10.103 mysql2
    192.168.10.104 mysql3
    

    验证配置

    执行以下命令检查主机名是否生效:

    hostname
    

    检查 hosts 文件是否更新成功:

    cat /etc/hosts
    
  3. 安装依赖包: 

    # 使用 pssh 示例
    pssh -h nodes.txt -i "yum install epel-release --nogpgcheck -y"
    pssh -h nodes.txt -i "yum install -y perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker perl-CPAN"
     
    
  4. 下载 MHA 安装包: 

    下载 MHA Node 组件安装包

    从 MHA 官方网站下载 mha4mysql-node-0.57.tar.gz 安装包,使用 wget 命令直接下载到本地:

    wget https://github.com/yoshinorim/mha4mysql-node/releases/download/v0.57/mha4mysql-node-0.57.tar.gz
    

    上传安装包至所有节点

    使用 scp 命令将下载的安装包上传至所有节点的 /opt 目录。假设节点 IP 列表为 node1_ipnode2_ipnode3_ip,替换为实际 IP 或主机名:

    scp mha4mysql-node-0.57.tar.gz root@node1_ip:/opt/
    scp mha4mysql-node-0.57.tar.gz root@node2_ip:/opt/
    scp mha4mysql-node-0.57.tar.gz root@node3_ip:/opt/
    

    批量上传脚本(可选)

    若节点数量较多,可通过循环脚本批量上传。创建一个包含所有节点 IP 的文件 nodes.txt,每行一个 IP,然后执行:

    while read node_ip; do
        scp mha4mysql-node-0.57.tar.gz root@$node_ip:/opt/
    done < nodes.txt
    

    验证文件上传

    登录任意节点,检查 /opt 目录下是否存在安装包:

    ls -l /opt/mha4mysql-node-0.57.tar.gz
    

    注意事项确保所有节点已安装 openssh-clients 支持 scp。若节点间未配置 SSH 免密登录,需手动输入密码或使用 sshpass 工具自动化。替换 root 为实际具有权限的用户名。

  5. mha4mysql-manager-0.57.tar.gz(Manager 组件,仅 Manager 节点需要)

5.4 安装 MHA 所有组件与测试

5.4.1 安装 MySQL 5.7(仅 mysql1、mysql2、mysql3 节点)

卸载系统自带的 MariaDB(若有)

rpm -e --nodeps mariadb-libs

安装 MySQL 官方源

rpm -ivh https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm

编辑源文件,启用 5.7 版本(禁用 8.0)

vim /etc/yum.repos.d/mysql-community.repo

修改以下内容:

[mysql57-community]
enabled=1
[mysql80-community]
enabled=0

安装 MySQL 5.7

yum install mysql-community-server -y

启动 MySQL 并设置开机自启

systemctl start mysqld
systemctl enable mysqld

查看初始密码并修改

grep 'temporary password' /var/log/mysqld.log
mysql -uroot -p'初始密码'

执行密码修改(需符合复杂度要求)

ALTER USER 'root'@'localhost' IDENTIFIED BY 'MySQL@123';

授权远程登录(用于主从复制和 MHA 管理)

GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'MySQL@123' WITH GRANT OPTION;
FLUSH PRIVILEGES;
exit;

5.4.2 搭建一主两从复制(mysql1 为主库,mysql2、mysql3 为从库)

  1. 配置主库(mysql1)

    配置 MySQL 主从复制

    主库配置 (/etc/my.cnf 修改部分)

    [mysqld]
    server-id=102
    log-bin=mysql-bin
    binlog_format=row
    log-slave-updates=1
    sync-binlog=1
    innodb_flush_log_at_trx_commit=1
    

    重启 MySQL 服务

    systemctl restart mysqld
    

    创建复制账户并授权

    mysql -uroot -p'MySQL@123'
    GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.10.%' IDENTIFIED BY 'Repl@123';
    FLUSH PRIVILEGES;
    

    查看主库状态

    SHOW MASTER STATUS;
    

    从库配置关键信息(需替换实际值)

    CHANGE MASTER TO
    MASTER_HOST='主库IP',
    MASTER_USER='repl',
    MASTER_PASSWORD='Repl@123',
    MASTER_LOG_FILE='mysql-bin.000001',
    MASTER_LOG_POS=441;
    START SLAVE;
    

    验证从库状态

    SHOW SLAVE STATUS\G
    
  2. 配置从库(mysql2、mysql3,操作相同)

    以下是实现 MySQL 主从复制配置的完整代码片段,包含配置文件修改和同步命令:

    修改 MySQL 配置文件

    vim /etc/my.cnf
    

    在配置文件中添加以下内容(根据服务器角色选择对应的 server-id):

    [mysqld]
    server-id=103            # mysql3 改为 104
    log-bin=mysql-bin
    binlog_format=row
    log-slave-updates=1
    read_only=1              # 从库设置为只读
    relay_log=mysql-relay-bin
    relay_log_purge=0        # 禁止自动清除中继日志
    

    重启 MySQL 服务

    systemctl restart mysqld
    

    配置主从复制

    登录 MySQL 并执行同步命令(注意替换实际值):

    mysql -uroot -p'MySQL@123'
    
    CHANGE MASTER TO
    MASTER_HOST='192.168.10.102',
    MASTER_USER='repl',
    MASTER_PASSWORD='Repl@123',
    MASTER_LOG_FILE='mysql-bin.000001',
    MASTER_LOG_POS=441;
    
    START SLAVE;
    SHOW SLAVE STATUS\G
    

    验证状态

    检查输出结果中以下两个参数必须为 Yes

    Slave_IO_Running: Yes
    Slave_SQL_Running: Yes
    
  3. 验证主从复制: 

    主库创建测试数据

    mysql -uroot -p'MySQL@123' -e "
    CREATE DATABASE test_db;
    USE test_db;
    CREATE TABLE test_table (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20));
    INSERT INTO test_table (name) VALUES ('test1');
    FLUSH TABLES;"
    

    从库验证数据同步

    mysql -uroot -p'MySQL@123' -e "SELECT * FROM test_db.test_table;"
    

    验证说明主库执行创建数据库、表和插入数据的操作从库执行查询操作检查数据是否同步若从库能查询到相同数据,表明主从复制配置正常

5.4.3 安装 MHA 组件

  1. 所有节点安装 MHA Node 组件

    cd /opt
    tar zxvf mha4mysql-node-0.57.tar.gz
    cd mha4mysql-node-0.57
    perl Makefile.PL
    make && make install
     
    
  2. Manager 节点安装 MHA Manager 组件: 

    cd /opt
    tar zxvf mha4mysql-manager-0.57.tar.gz
    cd mha4mysql-manager-0.57
    perl Makefile.PL
    make && make install
     
    
    ls /usr/local/bin/masterha_*
     
    

5.4.4 配置 SSH 无密码认证(关键步骤)

MHA Manager 需通过 SSH 远程操作所有节点,因此需配置 Manager 节点到其他所有节点的免密登录,同时各从库间也需配置免密(用于日志同步)。以下操作在 Manager 节点执行:

生成 SSH 密钥对并配置免密登录

使用以下命令生成 RSA 密钥对,默认路径为 ~/.ssh/id_rsa,生成过程中可直接按回车使用默认值:

ssh-keygen -t rsa

将公钥分发到所有目标节点(包括管理节点和 MySQL 节点):

ssh-copy-id -i ~/.ssh/id_rsa.pub root@manager
ssh-copy-id -i ~/.ssh/id_rsa.pub root@mysql1
ssh-copy-id -i ~/.ssh/id_rsa.pub root@mysql2
ssh-copy-id -i ~/.ssh/id_rsa.pub root@mysql3

验证免密登录是否配置成功,通过 SSH 连接到各节点并执行简单命令(如 date):

ssh root@mysql1 date
ssh root@mysql2 date

注意事项

  • 确保所有目标节点的 SSH 服务已启动且允许 root 登录。
  • 若节点用户名非 root,需将命令中的 root@ 替换为实际用户名。
  • 首次连接时会提示确认主机密钥指纹,需手动输入 yes

同理,在 mysql2 节点执行上述密钥分发操作,确保 mysql2 可免密登录 mysql1、mysql3。

5.4.5 配置 MHA Manager(仅 Manager 节点)

部署注意事项

# 脚本需放置在MHA管理节点
chmod +x /etc/mha/app1/master_ip_failover

# 在MHA配置文件中需指定脚本路径
master_ip_failover_script=/etc/mha/app1/master_ip_failover

该脚本实现了标准MHA VIP故障转移流程,适用于大多数生产环境。需确保执行权限和SELinux策略配置正确。

  1. 创建 MHA 配置目录和配置文件

    [server default]  
    # MHA 管理账户(需在所有 MySQL 节点授权)  
    user=root  
    password=MySQL@123  
    
    # 主从复制账户  
    repl_user=repl  
    repl_password=Repl@123  
    
    # 故障切换脚本(用于 VIP 漂移,后续创建)  
    master_ip_failover_script=/etc/mha/app1/master_ip_failover  
    
    # 二次检查脚本  
    secondary_check_script=/usr/local/bin/masterha_secondary_check -s mysql2 -s mysql3  
    
    # 日志目录  
    log_dir=/var/log/mha/app1  
    
    # 工作目录  
    workdir=/var/log/mha/app1  
    
    # SSH 连接用户  
    ssh_user=root  
    
    # 主库配置  
    [server1]  
    hostname=mysql1  
    ip=192.168.10.102  
    port=3306  
    
    # 主库权重(值越大优先级越高,故障恢复后可优先成为主库)  
    priority=100  
    
    # 备选主库配置  
    [server2]  
    hostname=mysql2  
    ip=192.168.10.103  
    port=3306  
    priority=90  
    
    # 允许成为主库  
    candidate_master=1  
    
    # 从库配置  
    [server3]  
    hostname=mysql3  
    ip=192.168.10.104  
    port=3306  
    priority=80  
     
    
  2. 创建 VIP 漂移脚本

    以下是根据要求生成的 MHA VIP 故障转移脚本代码,实现主库切换时的 VIP 漂移功能:

    完整脚本代码

    #!/usr/bin/perl
    use strict;
    use warnings FATAL => 'all';
    use Getopt::Long;
    
    my ($command, $orig_master_host, $orig_master_ip, $orig_master_port, 
        $new_master_host, $new_master_ip, $new_master_port);
    
    GetOptions(
        'command=s'              => \$command,
        'orig_master_host=s'     => \$orig_master_host,
        'orig_master_ip=s'       => \$orig_master_ip,
        'orig_master_port=i'     => \$orig_master_port,
        'new_master_host=s'      => \$new_master_host,
        'new_master_ip=s'        => \$new_master_ip,
        'new_master_port=i'      => \$new_master_port,
    );
    
    # 配置VIP和网卡(需根据实际环境修改)
    my $vip = '192.168.10.200/24';
    my $nic = 'eth0';
    
    if ($command eq "start") {
        # 新主库绑定VIP并发送ARP广播
        system("/sbin/ip addr add $vip dev $nic");
        system("/sbin/arping -I $nic -c 3 -s $vip $new_master_ip > /dev/null 2>&1");
        exit 0;
    }
    elsif ($command eq "stop") {
        # 故障主库解除VIP绑定
        system("/sbin/ip addr del $vip dev $nic");
        exit 0;
    }
    elsif ($command eq "status") {
        # 检查VIP当前状态
        my $status = system("/sbin/ip addr show $nic | grep $vip > /dev/null 2>&1");
        if ($status == 0) {
            exit 0;
        } else {
            exit 1;
        }
    }
    
    exit 1;
    

    关键功能说明VIP配置:需修改 $vip$nic 变量为实际环境的虚拟IP和网卡名称start命令:新主库上线时自动绑定VIP并通过ARP广播更新网络设备缓存stop命令:故障主库下线时自动解除VIP绑定status命令:检查当前节点是否持有VIP

5.4.6 手动绑定初始 VIP(主库 mysql1 节点)

ip addr add 192.168.10.200/24 dev eth0
 
ip addr show eth0 | grep 192.168.10.200
 

5.4.7 测试 MHA 配置有效性

  1. 测试 SSH 免密认证: 

    #!/bin/bash
    
    # 定义 MHA 配置文件路径
    MHA_CONF="/etc/mha/app1.cnf"
    
    # 执行 SSH 连接检查
    ssh_check_output=$(masterha_check_ssh --conf=$MHA_CONF 2>&1)
    
    # 检查输出是否包含成功信息
    if [[ $ssh_check_output == *"All SSH connections succeeded"* ]]; then
        echo "SSH 连接检查成功: $ssh_check_output"
        exit 0
    else
        echo "SSH 连接检查失败: $ssh_check_output"
        exit 1
    fi
     
    
  2. 测试主从复制状态: 

    以下内容为调用网络搜索工具后整合生成的答案,严格遵循任务要求的格式和内容限制:

    实现 masterha_check_repl 健康检查

    使用以下命令检查MySQL复制健康状况:

    masterha_check_repl --conf=/etc/mha/app1.cnf
    

    成功输出判断

    当命令执行成功时,输出会包含以下关键信息:

    MySQL Replication Health is OK.
    

    自动化检测脚本示例

    创建Shell脚本实现自动化检测:

    #!/bin/bash
    result=$(masterha_check_repl --conf=/etc/mha/app1.cnf 2>&1)
    if [[ $result == *"MySQL Replication Health is OK."* ]]; then
        echo "Replication check passed"
        exit 0
    else
        echo "Replication check failed"
        exit 1
    fi
    

    配置文件注意事项

    确保/etc/mha/app1.cnf包含正确的配置参数:

    [server default]
    user=mha_user
    password=mha_password
    manager_workdir=/var/log/mha/app1
    manager_log=/var/log/mha/app1/manager.log
    
    [server1]
    hostname=master_host
    port=3306
    
    [server2]
    hostname=slave_host
    port=3306
    

5.4.8 启动 MHA Manager 服务

前台

masterha_manager --conf=/etc/mha/app1.cnf
 

后台

nohup masterha_manager --conf=/etc/mha/app1.cnf > /var/log/mha/app1/manager.log 2>&1 &
 

5.4.9 查看 MHA 状态

#!/bin/bash

CONFIG_FILE="/etc/mha/app1.cnf"
STATUS_OUTPUT=$(masterha_check_status --conf=${CONFIG_FILE})

EXPECTED_PATTERN="app1 (pid: [0-9]+) is running(0:PING_OK)."

if [[ ${STATUS_OUTPUT} =~ ${EXPECTED_PATTERN} ]]; then
    echo "MHA status check passed: ${STATUS_OUTPUT}"
    exit 0
else
    echo "MHA status check failed. Actual output: ${STATUS_OUTPUT}"
    exit 1
fi
 

5.4.10 查看 MHA 日志

tail -f /var/log/mha/app1/manager.log | grep --line-buffered -E "ERROR|WARN|failover"
 

5.4.11 查看主库 VIP 状态

ip addr show eth0 | grep 192.168.10.200
 

5.4.12 关闭 MHA Manager 服务

masterha_stop --conf=/etc/mha/app1.cnf
 

5.5 故障模拟与恢复

5.5.1 模拟主库故障(mysql1 节点)

systemctl stop mysqld
 
poweroff
 

5.5.2 观察故障切换过程(Manager 节点)

tail -f /var/log/mha/app1/manager.log
 

切换成功后,日志会输出类似以下内容:

#!/bin/bash

# 定义变量
NEW_MASTER="192.168.10.103"
PORT=3306
LOG_FILE="/var/log/mysql_failover.log"

# 检查新主库是否可连接
mysql -h $NEW_MASTER -P $PORT -e "SHOW DATABASES;" >/dev/null 2>&1

if [ $? -eq 0 ]; then
    # 检查复制状态(假设从库已切换为新主库)
    SLAVE_STATUS=$(mysql -h $NEW_MASTER -P $PORT -e "SHOW SLAVE STATUS\G")

    if [[ -z "$SLAVE_STATUS" ]]; then
        # 记录成功日志
        echo "$(date '+%Y-%m-%d %H:%M:%S') - Master failover to $NEW_MASTER:$PORT completed successfully" >> $LOG_FILE
        # 输出成功信息
        echo "Master failover to mysql2($NEW_MASTER:$PORT) completed successfully."
    else
        echo "Error: Replication still active on $NEW_MASTER"
        exit 1
    fi
else
    echo "Error: Unable to connect to $NEW_MASTER:$PORT"
    exit 1
fi
 

5.5.3 验证切换结果

执行效果将显示:服务状态(active/inactive)数据库模式(绿色WRITABLE/红色READ-ONLY)VIP绑定状态(绿色active/红色inactive)采用 ip -o 单行输出版本更易解析颜色输出使用 ANSI 转义码,绿色表示正常,红色表示异常每个检查模块有独立标题和状态标识

  1. 验证新主库状态(mysql2 节点): 

    以下是实现查看 MySQL 状态、只读模式及 VIP 绑定的 Shell 代码片段:

    检查 MySQL 服务状态

    systemctl status mysqld | grep -E 'Active|Main PID'
    

    验证只读模式状态

    mysql -uroot -p'MySQL@123' -e "SHOW GLOBAL VARIABLES LIKE 'read_only'" | grep -v 'Variable_name'
    

    检测 VIP 绑定情况

    ip addr show eth0 | grep -o '192.168.10.200' && echo "VIP exists" || echo "VIP missing"
    

    增强版组合检查(输出带颜色标识)

    echo -e "\n\033[36m=== MySQL Service Status ===\033[0m"
    systemctl is-active mysqld | xargs -I{} echo -e "Service: \033[33m{}\033[0m"
    
    echo -e "\n\033[36m=== Read-Only Mode ===\033[0m"
    mysql -uroot -p'MySQL@123' -Nse "SELECT @@read_only" | awk '{print $1=="0"?"\033[32mWRITABLE\033[0m":"\033[31mREAD-ONLY\033[0m"}'
    
    echo -e "\n\033[36m=== VIP Binding ===\033[0m"
    ip -o addr show eth0 | grep -q '192.168.10.200' && echo -e "\033[32mVIP active\033[0m" || echo -e "\033[31mVIP inactive\033[0m"
    

    代码说明:使用 systemctl is-active 更精确获取服务状态通过 -Nse 参数使 MySQL 查询结果更简洁

  2. 验证从库复制状态(mysql3 节点)

    Slave_IO_Running: Yes
    Slave_SQL_Running: Yes
    Master_Host: 192.168.10.103
     
    
  3. 验证应用访问(任意节点): 

    通过 VIP 连接数据库并验证服务可用性

    mysql -uroot -p'MySQL@123' -h 192.168.10.200
    

    插入测试数据

    INSERT INTO test_db.test_table (name) VALUES ('test_after_failover');
    

    在从库验证数据同步

    mysql -uroot -p'MySQL@123' -h 192.168.10.202 -e "select * from test_db.test_table"
    

5.5.4 故障主库恢复并重新加入集群(mysql1 节点)

  1. 修复故障主库

    # 启动 MySQL 服务
    systemctl start mysqld
    
    # 验证服务状态
    systemctl status mysqld
     
    
  2. 将原主库配置为新主库的从库: 

    以下是根据要求生成的MySQL主从同步配置代码片段,用于将原主库(mysql1)设置为从库并同步新主库(mysql2)的数据:

    重置从库状态

    mysql -uroot -p'MySQL@123' -e "RESET SLAVE ALL;"
    

    获取新主库二进制日志位置(在mysql2节点执行)

    mysql -uroot -p'MySQL@123' -e "SHOW MASTER STATUS;"
    -- 示例输出:File: mysql-bin.000002, Position: 441
    

    配置主从同步(在mysql1节点执行)

    mysql -uroot -p'MySQL@123' -e "
    CHANGE MASTER TO 
    MASTER_HOST='192.168.10.103',
    MASTER_USER='repl',
    MASTER_PASSWORD='Repl@123',
    MASTER_LOG_FILE='mysql-bin.000002',
    MASTER_LOG_POS=441;"
    

    启动复制并检查状态

    mysql -uroot -p'MySQL@123' -e "
    START SLAVE;
    SHOW SLAVE STATUS\G"
    -- 验证Slave_IO_Running和Slave_SQL_Running状态是否为Yes
    
  3. 将原主库重新加入 MHA 集群(Manager 节点): 

    # 编辑 MHA 配置文件,确保 server1 配置正常(无需修改,原配置有效)
    vim /etc/mha/app1.cnf
    
    # 重启 MHA Manager 服务
    masterha_stop --conf=/etc/mha/app1.cnf
    nohup masterha_manager --conf=/etc/mha/app1.cnf > /var/log/mha/app1/manager.log 2>&1 &
    
    # 验证集群状态
    masterha_check_status --conf=/etc/mha/app1.cnf
     
    

此时集群恢复为一主两从架构,原主库 mysql1 成为新主库 mysql2 的从库,MHA 继续监控集群状态。

6. 总结

MHA 作为基于主从复制的 MySQL 高可用方案,凭借其快速故障切换、数据一致性保障、轻量级部署等优势,成为中小规模 MySQL 集群的首选高可用方案。本次实战通过搭建一主两从 + Manager 架构,完整验证了 MHA 的部署流程、故障自动切换及故障恢复能力,关键注意事项如下:

  • 环境准备阶段需确保 SELinux、防火墙完全关闭,避免网络和权限干扰。

  • SSH 免密认证是 MHA 正常工作的前提,需确保 Manager 节点可免密访问所有数据节点。

  • 主从复制配置需启用行级复制(binlog_format=row),并确保从库中继日志不自动清除。

  • VIP 漂移脚本需根据实际网卡调整,切换后需验证 VIP 绑定状态和应用访问能力。

在生产环境中,还需结合监控工具(如 Prometheus + Grafana)监控 MHA 集群状态,配置故障告警机制,并定期演练故障切换流程,确保高可用能力稳定可靠。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐