MySQL 8.0+ MHA 高可用集群搭建(生产环境级・超详细)

本文档整合MySQL8.0 + 专属 MHA 搭建 +3 节点(1 主 2 从)架构 +my.cnf 超详细配置 +生产级全流程操作 ,所有步骤可直接落地生产,兼顾 MHA 高可用核心功能、MySQL8.0 兼容适配、3 节点资源最优配置,管理节点复用从库 1(节省服务器),包含VIP 无感知漂移、在线主从切换、故障自动转移、原主库恢复重入全能力,附所有核心配置文件、命令、排障要点。

一、核心前提与 3 节点环境规划

1. 强兼容前提

  • MySQL 版本:8.0.20+(生产稳定版),所有节点版本完全一致;
  • MHA 版本:0.58+(唯一兼容 MySQL8.0 的稳定版,Manager/Node 版本必须严格一致);
  • 系统版本:CentOS7.9/AlmaLinux8/9(生产主流,兼容性最优);
  • 核心兼容:MySQL8.0 账号需指定mysql_native_password插件(MHA 暂不支持默认的caching_sha2_password)。

2. 3 节点架构(1 主 2 从 + 复用管理节点)

核心规划 :管理节点部署在从库 1,实现资源复用;所有节点server-id绝对唯一,VIP 漂移至主库,应用统一连接 VIP 实现无感知切换。

节点角色 主机名 内网 IP 唯一 server-id 需安装包 核心职责
MySQL8.0 主库 mysql-m1 192.168.1.10 10 MHA Node 0.58 + MySQL8.0+ 主写节点,无其他角色
MySQL8.0 从库 + MHA 管理节点 mysql-s1 192.168.1.11 11 MHA Node 0.58 + MHA Manager 0.58 + MySQL8.0+ 从库 + MHA 全管理操作
MySQL8.0 从库 mysql-s2 192.168.1.12 12 MHA Node 0.58 + MySQL8.0+ 备用从库,故障转移候选主库
集群 VIP(虚拟 IP) - 192.168.1.100 - Keepalived(所有 MySQL 节点) 应用统一连接,故障自动漂移

3. 全局路径约定(所有节点统一)

  • MySQL 配置:/etc/my.cnf(yum/dnf 安装),数据 / 日志目录:/var/lib/mysql//var/log/mysqld.log
  • MHA 配置:/etc/mha,日志目录:/var/log/mha/app1,工作目录:/var/lib/mha/app1
  • 脚本路径:MHA 故障 / 切换脚本存放于/etc/mha/,所有脚本权限为700(仅 root 可执行)。

二、全节点通用基础配置(生产级・必做)

所有 3 个节点执行以下操作,解决网络、权限、依赖问题,为后续主从复制和 MHA 搭建铺路。

1. 网络与安全配置(生产不直接关闭防火墙 / SELinux)

复制代码
# 1. 开放必备端口(MySQL3306、SSH22),永久生效
firewall-cmd --add-port=22/tcp --add-port=3306/tcp --permanent
firewall-cmd --reload
# 2. SELinux设为宽容模式(避免拦截SSH/MHA/MySQL操作,临时+永久)
setenforce 0
sed -i 's/^SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config
# 3. 配置hosts解析(优先主机名通信,避免DNS延迟,所有节点一致)
cat >> /etc/hosts << EOF
192.168.1.10 mysql-m1
192.168.1.11 mysql-s1
192.168.1.12 mysql-s2
192.168.1.100 mysql-vip
EOF
# 4. 关闭DNS解析(系统层面,配合MySQL的skip_name_resolve)
echo "hosts: files dns" > /etc/nsswitch.conf

2. SSH 免密互通(MHA 核心前提・双向免密)

仅在 MHA 管理节点(mysql-s1)执行,实现管理节点免密登录所有 MySQL 节点,且 MySQL 节点间互免密(故障转移 binlog 复制更高效):

复制代码
# 1. 生成RSA密钥(一路回车,不设密码,生产禁止密钥密码)
ssh-keygen -t rsa -b 2048 -N '' -f ~/.ssh/id_rsa
# 2. 分发密钥至所有节点(包括自身)
ssh-copy-id -i ~/.ssh/id_rsa.pub root@mysql-m1
ssh-copy-id -i ~/.ssh/id_rsa.pub root@mysql-s1
ssh-copy-id -i ~/.ssh/id_rsa.pub root@mysql-s2
# 3. 修复.ssh目录权限(权限错误会导致免密失败,生产严格要求)
chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys
chown -R root:root ~/.ssh
# 4. 验证免密(无密码弹出即成功,示例验证主库)
ssh root@mysql-m1 "hostname && date"

3. 安装基础依赖(MHA/MySQL8.0 必备)

所有节点执行,安装 Perl 依赖(MHA 基于 Perl 开发)、生产工具,配置 epel 源:

复制代码
# 1. 安装epel源(CentOS7,AlmaLinux8/9可跳过)
yum install -y epel-release && yum clean all && yum makecache
# 2. 安装MHA核心Perl依赖(含MySQL8.0适配模块)
yum install -y perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-JSON
# 3. 安装生产常用工具(排障/操作)
yum install -y wget net-tools telnet vim tree lsof chrony
# 4. 配置NTP时间同步(所有节点时间一致,避免主从/MHA误判)
systemctl start chrony && systemctl enable chrony && chronyc sync

三、MySQL8.0+ 3 节点 my.cnf 超详细配置(MHA 必选 + 生产优化)

1. 配置说明

  • 路径:/etc/my.cnf,先备份原有配置cp /etc/my.cnf /etc/my.cnf.bak-$(date +%Y%m%d)
  • 结构:全局通用配置(所有节点一致)+ 节点专属配置(按角色添加,取消注释)
  • 标「MHA 必选」的参数禁止修改 / 删除,否则 MHA 故障转移会失败;
  • 性能参数适配 4G/8G 内存,大内存(16G/32G)按注释比例放大即可。

2. 完整 my.cnf 配置(直接复制落地,仅取消自身角色专属注释)

复制代码
[mysqld]
########################### 全局通用配置(所有3节点完全一致,MHA必选+生产优化) ###########################
# 基础标识(MHA/主从核心,禁止修改)
server_uuid = auto  # 自动生成唯一UUID,避免克隆节点重复
skip_name_resolve = 1  # MHA必选:关闭域名解析,避免连接超时
lower_case_table_names = 1  # 表名不区分大小写,避免主从不一致
explicit_defaults_for_timestamp = 1  # 时间戳规范,消除复制警告

# 字符集(生产统一,避免乱码)
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect = 'SET NAMES utf8mb4'
skip-character-set-client-handshake = 1

# 二进制日志(MHA/主从必选,核心配置)
log-bin = mysql-bin  # MHA必选:开启binlog,故障转移基础
binlog_format = row  # MHA必选:强制ROW格式,避免数据不一致
binlog_expire_logs_seconds = 604800  # binlog7天自动清理
max_binlog_size = 1G  # 单个binlog大小,便于MHA复制
sync_binlog = 1  # 每次提交刷盘,保证binlog不丢失(生产级数据安全)

# GTID复制(MHA必选,8.0+推荐,故障转移更精准)
gtid_mode = ON  # MHA必选:开启GTID
enforce_gtid_consistency = 1  # MHA必选:强制GTID一致性
log_slave_updates = 1  # MHA必选:从库记录复制binlog,便于原主库重入
gtid_next = AUTOMATIC  # 自动分配GTID,无需手动指定

# InnoDB核心优化(4G/8G内存基础值,大内存按比例放大)
innodb_buffer_pool_size = 1G  # 建议物理内存50%-70%(16G设8G,32G设20G)
innodb_buffer_pool_instances = 1  # 1G/个,与buffer_pool_size匹配
innodb_log_file_size = 512M  # 生产建议512M-2G,避免频繁刷盘
innodb_log_buffer_size = 64M
innodb_flush_log_at_trx_commit = 1  # 事务提交刷盘,保证数据安全
innodb_file_per_table = 1  # 单表独立ibd文件,便于维护
innodb_flush_method = O_DIRECT  # 绕过系统缓存,提升IO性能
innodb_read_io_threads = 8
innodb_write_io_threads = 8

# 连接与会话优化(生产级,避免连接数不足)
max_connections = 2048
max_connect_errors = 1000000  # 避免IP被误拉黑
wait_timeout = 86400
interactive_timeout = 86400
back_log = 1024

# 其他优化(MHA兼容,无冲突)
tmp_table_size = 64M
max_heap_table_size = 64M
sort_buffer_size = 2M
join_buffer_size = 2M
table_open_cache = 2048
table_definition_cache = 2048

# 日志与路径(所有节点一致,MHA必选路径统一)
log_error = /var/log/mysqld.log
pid-file = /var/run/mysqld/mysqld.pid
datadir = /var/lib/mysql  # MHA必选:所有节点数据目录一致

########################### 节点专属配置(按角色取消注释,仅保留自身角色) ###########################
# ************************** 仅主库(mysql-m1, 192.168.1.10)添加 **************************
# server-id = 10  # 唯一标识,禁止重复
# auto_increment_increment = 1  # 自增步长,可选:配合从库实现自增不冲突

# ************************** 仅从库1(mysql-s1, 192.168.1.11,MHA管理节点)添加 **************************
# server-id = 11  # 唯一标识,禁止重复
# read_only = 1  # MHA必选:从库只读
# super_read_only = 1  # MHA必选:禁止super权限写从库
# relay_log = mysql-relay-bin  # 中继日志,显式配置更规范
# relay_log_recovery = 1  # MHA必选:重启后自动恢复中继日志,避免复制中断

# ************************** 仅从库2(mysql-s2, 192.168.1.12)添加 **************************
# server-id = 12  # 唯一标识,禁止重复
# read_only = 1  # MHA必选:从库只读
# super_read_only = 1  # MHA必选:禁止super权限写从库
# relay_log = mysql-relay-bin  # 中继日志
# relay_log_recovery = 1  # MHA必选:重启后自动恢复中继日志

[mysqld_safe]
# 所有节点统一,无需修改
log-error = /var/log/mysqld.log
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/lib/mysql/mysql.sock
user = mysql

[mysql]
# 客户端通用配置
socket = /var/lib/mysql/mysql.sock
default-character-set = utf8mb4

[client]
# 客户端工具(mysqladmin/mysqldump)配置
socket = /var/lib/mysql/mysql.sock
default-character-set = utf8mb4

3. 配置生效与验证(所有节点)

复制代码
# 1. 重启MySQL服务,使配置生效,设置开机自启
systemctl restart mysqld && systemctl enable mysqld
# 2. 验证核心配置(MHA/主从关键,必看结果)
mysql -uroot -p -e "
show variables like 'server_id';
show variables like 'log_bin';
show variables like 'gtid_mode';
show variables like 'read_only';
show variables like 'super_read_only';
"

验证标准

  • 所有节点:log_bin=ONgtid_mode=ON
  • 主库(mysql-m1):read_only=OFFsuper_read_only=OFF
  • 两个从库(mysql-s1/mysql-s2):read_only=ONsuper_read_only=ON
  • 每个节点server_id与规划一致(10/11/12)。

4. 配置文件权限(生产级严格控制)

复制代码
# 仅root可读写,避免非授权修改
chmod 600 /etc/my.cnf
chown root:root /etc/my.cnf

四、MySQL8.0+ GTID 主从复制搭建(MHA 必选前提)

MHA 完全依赖主从复制,需搭建GTID 模式主从 ,重点解决 MySQL8.0 的密码插件兼容问题,所有从库需实现「双 Yes」(Slave_IO_Running/Slave_SQL_Running)。

1. 主库(mysql-m1)创建专属账号(MySQL8.0 专属语法)

核心 :为 MHA 管理账号和主从复制账号指定mysql_native_password插件,否则 MHA 无法认证。

复制代码
# 1. 登录主库MySQL
mysql -uroot -p
# 2. 创建MHA管理账号(所有节点通用,密码自定义,生产需复杂)
CREATE USER 'mha_admin'@'%' IDENTIFIED WITH mysql_native_password BY 'Mha@808080';
# 授予MHA最小必要权限(生产不授超级权限,刚好满足MHA运行)
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT, SUPER, PROCESS, LOCK TABLES, RELOAD ON *.* TO 'mha_admin'@'%';
# 3. 创建主从复制账号(repl为MHA默认识别名,**不可修改**)
CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'Repl@808080';
# 复制最小权限
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
# 4. 刷新权限
FLUSH PRIVILEGES;
# 5. 查看主库状态(无需记录binlog位置,GTID模式自动对齐)
SHOW MASTER STATUS\G;

2. 两个从库(mysql-s1/mysql-s2)配置 GTID 主从复制

两个从库执行完全相同的命令,指向主库 mysql-m1,实现 GTID 模式同步:

复制代码
# 1. 登录从库MySQL
mysql -uroot -p
# 2. 配置主从复制(GTID模式,无需指定binlog文件/位置)
CHANGE MASTER TO
MASTER_HOST='192.168.1.10',
MASTER_USER='repl',
MASTER_PASSWORD='Repl@808080',
MASTER_PORT=3306,
MASTER_AUTO_POSITION=1;
# 3. 启动从库复制
START SLAVE;
# 4. 验证主从复制状态(核心:双Yes,GTID一致)
SHOW SLAVE STATUS\G;

生产级验证标准

  • Slave_IO_Running: YesSlave_SQL_Running: Yes(核心,无任何例外);
  • Retrieved_Gtid_SetExecuted_Gtid_Set 与主库完全一致(数据无延迟);
  • 无任何复制错误(Last_Error为空)。

五、MHA 0.58 安装(分节点・版本严格一致)

MHA 无官方 yum 源,通过 rpm 包安装,仅管理节点(mysql-s1)装 Manager 包,所有节点均装 Node 包

1. 所有节点下载 MHA 0.58 安装包(/opt 目录)

复制代码
cd /opt
# 下载MHA Node 0.58(所有节点必备)
wget https://github.com/yoshinorim/mha4mysql-node/releases/download/v0.58/mha4mysql-node-0.58-1.el7.centos.noarch.rpm
# 下载MHA Manager 0.58(仅管理节点mysql-s1需要)
wget https://github.com/yoshinorim/mha4mysql-manager/releases/download/v0.58/mha4mysql-manager-0.58-1.el7.centos.noarch.rpm

若下载失败,可手动上传至/opt目录,不影响后续安装。

2. 分节点安装 MHA 包

(1)主库(mysql-m1)+ 从库 2(mysql-s2):仅装 Node 包
复制代码
cd /opt
rpm -ivh mha4mysql-node-0.58-1.el7.centos.noarch.rpm
(2)管理节点(mysql-s1):装 Node 包 + Manager 包(有依赖关系,先 Node 后 Manager)
复制代码
cd /opt
# 第一步:安装Node包(基础依赖)
rpm -ivh mha4mysql-node-0.58-1.el7.centos.noarch.rpm
# 第二步:安装Manager包(MHA核心管理工具)
rpm -ivh mha4mysql-manager-0.58-1.el7.centos.noarch.rpm

3. 验证安装成功(分节点)

复制代码
# 1. 所有节点验证Node包(有命令即成功)
which masterha_node_checker
# 2. 管理节点(mysql-s1)验证Manager包(所有命令均存在即成功)
which masterha_manager && which masterha_check_ssh && which masterha_check_repl && which masterha_check_status

成功标志 :输出所有命令的绝对路径(如/usr/bin/masterha_manager)。

六、MHA 3 节点核心配置(仅管理节点 mysql-s1 操作)

所有 MHA 配置均在管理节点完成,包括目录创建、3 节点 app1.cnf 配置、VIP 漂移脚本、在线切换脚本、VIP 初始化,适配 3 节点架构。

1. 创建 MHA 专属目录(权限严格为 700,避免密码泄露)

复制代码
# 配置目录(存放配置文件、脚本)
mkdir -p /etc/mha
# 日志目录(MHA运行/故障日志,持久化)
mkdir -p /var/log/mha/app1
# 工作目录(临时文件、binlog复制)
mkdir -p /var/lib/mha/app1
# 赋权(仅root可访问,生产级)
chmod -R 700 /etc/mha /var/log/mha /var/lib/mha
chown -R root:root /etc/mha /var/log/mha /var/lib/mha

2. 编写 3 节点 MHA 主配置文件(/etc/mha/app1.cnf・核心)

适配 3 节点架构,新增从库 2(mysql-s2)配置,指定候选主库优先级,所有参数与之前配置一致,直接复制落地:

复制代码
[server default]
# MHA基础路径
manager_workdir = /var/lib/mha/app1
manager_log = /var/log/mha/app1/mha_manager.log
master_binlog_dir = /var/lib/mysql
# MHA MySQL账号(与主库创建的一致)
user = mha_admin
password = Mha@808080
# 主从复制账号(MHA默认识别repl,不可改)
repl_user = repl
repl_password = Repl@808080
# MHA核心脚本(故障转移+在线切换)
master_ip_failover_script = /etc/mha/master_ip_failover.sh
master_ip_online_change_script = /etc/mha/master_ip_online_change.sh
# 二次检测脚本(防止网络抖动误切,生产必加)
secondary_check_script = /usr/bin/masterha_secondary_check -s mysql-m1 -s mysql-s1 -s mysql-s2
# 主库检测配置(生产级,平衡频率与资源)
ping_interval = 3
ping_retries = 3
# MHA故障转移核心配置
auto_increment_offset = 1
auto_master_position = 1
skip_binlog_check = 1  # MySQL8.0专属:关闭binlog校验
save_master_binlog_dir = /var/lib/mha/app1/binlog

# 3节点专属配置(按优先级排序)
[server1]  # 主库mysql-m1
hostname = mysql-m1
ip = 192.168.1.10
port = 3306
master_binlog_dir = /var/lib/mysql
candidate_master = 0  # 不设为候选主库,故障后不优先恢复
check_repl_delay = 0

[server2]  # 从库1mysql-s1(MHA管理节点,优先候选主库)
hostname = mysql-s1
ip = 192.168.1.11
port = 3306
master_binlog_dir = /var/lib/mysql
candidate_master = 1  # 第一候选主库
check_repl_delay = 0  # 忽略复制延迟,优先切换

[server3]  # 从库2mysql-s2(备用候选主库)
hostname = mysql-s2
ip = 192.168.1.12
port = 3306
master_binlog_dir = /var/lib/mysql
candidate_master = 1  # 第二候选主库
check_repl_delay = 0  # 忽略复制延迟

3. 编写 MHA 故障转移脚本(/etc/mha/master_ip_failover.sh・VIP 漂移)

实现主库宕机时 VIP 自动从原主库漂移至新主库,应用无感知,仅需修改 VIP 和网卡名,直接复制:

复制代码
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;

# 生产配置·需修改为自身环境
my $VIP = '192.168.1.100';        # 集群VIP
my $NETMASK = '255.255.255.0';    # 子网掩码
my $INTERFACE = 'eth0';           # 网卡名(用ip addr查看,如ens33/eth0)
my $ACTION = '';
my $HOSTNAME = '';
my $MYSQL_IP = '';

# 获取MHA传递的参数
GetOptions(
    'action=s' => \$ACTION,
    'hostname=s' => \$HOSTNAME,
    'ip=s' => \$MYSQL_IP,
);

# 日志函数(输出至MHA核心日志)
sub log_print {
    my $msg = shift;
    my $time = localtime();
    print "[$time] [INFO] $msg\n";
}

# 释放VIP(主库宕机时执行)
sub release_vip {
    log_print("Start releasing VIP $VIP on $MYSQL_IP ($INTERFACE)");
    `ifconfig $INTERFACE:$VIP down > /dev/null 2>&1`;
    if ($? == 0) {
        log_print("Success released VIP $VIP on $MYSQL_IP");
    } else {
        log_print("Failed to release VIP $VIP on $MYSQL_IP");
        exit 1;
    }
}

# 绑定VIP(新主库提升时执行)
sub bind_vip {
    log_print("Start binding VIP $VIP to new master $MYSQL_IP ($INTERFACE)");
    `ifconfig $INTERFACE:$VIP $VIP netmask $NETMASK up > /dev/null 2>&1`;
    if ($? == 0) {
        log_print("Success bound VIP $VIP to new master $MYSQL_IP");
    } else {
        log_print("Failed to bind VIP $VIP to new master $MYSQL_IP");
        exit 1;
    }
}

# 主逻辑
if ($ACTION eq 'stop' || $ACTION eq 'stopssh') {
    release_vip();
} elsif ($ACTION eq 'start') {
    bind_vip();
} elsif ($ACTION eq 'status') {
    my $vip_status = `ifconfig | grep $VIP`;
    $vip_status ? log_print("VIP $VIP is running on $HOSTNAME ($MYSQL_IP)") : log_print("VIP $VIP is NOT running on $HOSTNAME ($MYSQL_IP)");
} else {
    log_print("Invalid action: $ACTION");
    exit 1;
}

exit 0;

4. 编写 MHA 在线主从切换脚本(/etc/mha/master_ip_online_change.sh・生产维护必备)

实现生产维护时无感知切换主库(如主库升级 / 重启),VIP 自动漂移,原主库自动变为从库,与故障转移脚本参数一致,直接复制:

复制代码
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;

# 与故障转移脚本一致,无需重复修改
my $VIP = '192.168.1.100';
my $NETMASK = '255.255.255.0';
my $INTERFACE = 'eth0';
my $ACTION = '';
my $OLD_MASTER_IP = '';
my $NEW_MASTER_IP = '';

GetOptions(
    'action=s' => \$ACTION,
    'old_master_ip=s' => \$OLD_MASTER_IP,
    'new_master_ip=s' => \$NEW_MASTER_IP,
);

sub log_print {
    my $msg = shift;
    my $time = localtime();
    print "[$time] [INFO] $msg\n";
}

# 旧主库释放VIP
sub release_vip_old {
    log_print("Start releasing VIP $VIP from old master $OLD_MASTER_IP");
    `ssh root@$OLD_MASTER_IP "ifconfig $INTERFACE:$VIP down > /dev/null 2>&1"`;
    if ($? == 0) {
        log_print("Success released VIP $VIP from old master $OLD_MASTER_IP");
    } else {
        log_print("Failed to release VIP $VIP from old master $OLD_MASTER_IP");
        exit 1;
    }
}

# 新主库绑定VIP
sub bind_vip_new {
    log_print("Start binding VIP $VIP to new master $NEW_MASTER_IP");
    `ssh root@$NEW_MASTER_IP "ifconfig $INTERFACE:$VIP $VIP netmask $NETMASK up > /dev/null 2>&1"`;
    if ($? == 0) {
        log_print("Success bound VIP $VIP to new master $NEW_MASTER_IP");
    } else {
        log_print("Failed to bind VIP $VIP to new master $NEW_MASTER_IP");
        exit 1;
    }
}

# 主逻辑
if ($ACTION eq 'stop') {
    release_vip_old();
} elsif ($ACTION eq 'start') {
    bind_vip_new();
} elsif ($ACTION eq 'status') {
    log_print("Online change status check: VIP $VIP is on " . `ifconfig | grep $VIP | awk '{print \$NF}'`);
} else {
    log_print("Invalid action: $ACTION");
    exit 1;
}

exit 0;

5. 脚本赋权 + 初始化 VIP(必做)

复制代码
# 1. 为两个脚本添加可执行权限(仅root可执行,生产级)
chmod 700 /etc/mha/master_ip_failover.sh /etc/mha/master_ip_online_change.sh
# 2. 初始化VIP(手动绑定至当前主库mysql-m1,应用后续统一连接VIP)
ssh root@mysql-m1 "ifconfig $INTERFACE:192.168.1.100 192.168.1.100 netmask 255.255.255.0 up"
# 3. 验证VIP绑定成功(所有节点可执行)
ip addr | grep 192.168.1.100

成功标志:仅主库 mysql-m1 能查到 VIP 的网卡信息。

七、MHA 集群核心验证(仅管理节点 mysql-s1・无 ERROR 再启动)

配置完成后,必须执行两项验证,无任何 ERROR 才能启动 MHA,否则故障转移 / 在线切换会失败,这是生产级必做步骤。

1. 验证 SSH 免密互通(masterha_check_ssh)

复制代码
# 语法:masterha_check_ssh --conf=配置文件路径
masterha_check_ssh --conf=/etc/mha/app1.cnf

生产级成功标志 :全程无ERROR/Permission denied,最后一行输出SSH connection check passed常见错误排查

  • 提示Permission denied:重新配置 SSH 免密,检查~/.ssh目录权限;
  • 提示Host key verification failed:执行ssh-keyscan mysql-m1 mysql-s1 mysql-s2 >> ~/.ssh/known_hosts

2. 验证主从复制 + MHA 配置(masterha_check_repl)

核心验证,检查主从状态、MHA 配置、账号权限、脚本可用性:

复制代码
# 语法:masterha_check_repl --conf=配置文件路径
masterha_check_repl --conf=/etc/mha/app1.cnf

生产级成功标志

  • 全程无ERROR(部分 Warning 如无邮件配置可忽略);
  • 正确识别当前主库:Current master is mysql-m1(192.168.1.10:3306)
  • 最后一行输出MySQL replication check passed常见错误排查
  • 从库双 No:修复主从复制(检查 server-id、GTID、复制账号);
  • MHA 认证失败:检查账号是否指定mysql_native_password
  • 脚本无权限:重新执行chmod 700 /etc/mha/*.sh

八、MHA 集群启动与生产级管理(仅管理节点 mysql-s1)

验证通过后,启动 MHA 并配置systemd服务(替代手动启动,实现开机自启、一键启停、状态监控),符合生产运维规范。

1. 配置 MHA systemd 服务(生产必备)

复制代码
vim /usr/lib/systemd/system/mha-app1.service

写入以下内容(直接复制):

复制代码
[Unit]
Description=MHA for MySQL8.0 3Node Cluster app1
After=network.target mysqld.service
Requires=mysqld.service

[Service]
Type=simple
User=root
Group=root
# MHA后台启动(守护进程模式,日志写入配置路径)
ExecStart=/usr/bin/masterha_manager --conf=/etc/mha/app1.cnf --daemonize
# MHA正常停止命令(禁止直接kill进程)
ExecStop=/usr/bin/masterha_stop --conf=/etc/mha/app1.cnf
# 重启策略(失败后自动重启,生产级)
Restart=on-failure
RestartSec=5
# 日志重定向(与MHA自身日志一致)
StandardOutput=append:/var/log/mha/app1/mha_manager.log
StandardError=append:/var/log/mha/app1/mha_manager.log

[Install]
WantedBy=multi-user.target

2. 启动 MHA 并设置开机自启

复制代码
# 1. 重新加载systemd配置
systemctl daemon-reload
# 2. 启动MHA服务
systemctl start mha-app1
# 3. 设置开机自启(生产必做,服务器重启后自动启动MHA)
systemctl enable mha-app1
# 4. 验证MHA服务状态(核心,确保active(running))
systemctl status mha-app1

3. MHA 常用管理命令(生产运维必备)

复制代码
# 1. 查看MHA集群详细状态(核心,确认当前主库和运行状态)
masterha_check_status --conf=/etc/mha/app1.cnf
# 2. 停止MHA集群
systemctl stop mha-app1
# 3. 重启MHA集群
systemctl restart mha-app1
# 4. 实时查看MHA日志(排障/监控核心)
tail -f /var/log/mha/app1/mha_manager.log
# 5. 查看MHA进程
ps -ef | grep masterha | grep -v grep
# 6. 强制清除MHA状态文件(仅进程异常时使用)
rm -rf /var/lib/mha/app1/*

正常状态输出app1 (pid: 12345) is running(0:PING_OK), master: mysql-m1

九、MHA 核心功能测试(生产级・故障转移 + 在线切换)

1. 故障转移测试(模拟主库宕机・自动切换)

(1)模拟主库彻底宕机(mysql-m1 执行)
复制代码
# 停止MySQL并禁止开机自启,模拟硬件/软件故障
systemctl stop mysqld && systemctl disable mysqld
# 验证MySQL已停止
systemctl status mysqld
(2)观察故障转移过程(管理节点 mysql-s1)
复制代码
tail -f /var/log/mha/app1/mha_manager.log

核心步骤(日志中可见,全程 3-10 秒)

  1. MHA 检测到主库无响应,输出Master is down!
  2. 选择第一候选主库 mysql-s1(管理节点),复制原主库未同步 binlog;
  3. 提升 mysql-s1 为新主库,关闭其只读模式;
  4. 让从库 2(mysql-s2)指向新主库 mysql-s1,重启复制;
  5. VIP 从 mysql-m1 漂移至 mysql-s1,日志最后输出Failover completed successfully
(3)验证故障转移结果(全节点)
复制代码
# 1. 验证VIP漂移(所有节点)
ip addr | grep 192.168.1.100  # 仅mysql-s1有VIP
# 2. 验证新主库状态(mysql-s1执行)
mysql -uroot -p -e "SHOW MASTER STATUS\G; SHOW SLAVE STATUS\G;"  # 无从库信息,为独立主库
# 3. 验证从库2同步状态(mysql-s2执行)
mysql -uroot -p -e "SHOW SLAVE STATUS\G;"  # Master_Host为mysql-s1,双Yes
# 4. 验证应用连接(任意节点,模拟应用)
mysql -umha_admin -pMha@808080 -h192.168.1.100 -e "select @@hostname, @@server_id;"  # 输出mysql-s1

2. 在线主从切换(生产维护・无感知切换)

生产中主库维护(升级 / 重启)时,执行在线切换,无需停止业务,VIP 自动漂移,原主库自动变为从库。

(1)执行在线切换命令(管理节点 mysql-s1)
复制代码
# 核心命令:--orig_master_is_new_slave 自动将原主库配置为新主库的从库
masterha_switch --conf=/etc/mha/app1.cnf --master_state=alive --orig_master_is_new_slave

执行后输入y确认,全程 3-5 秒。

(2)验证切换结果(全节点)
  • VIP 漂移至新主库,应用连接 VIP 无感知;
  • 原主库自动变为新主库的从库,双 Yes;
  • MHA 状态显示新主库为目标节点,运行正常。

十、原主库恢复并重新加入 MHA 集群(生产级)

故障转移 / 在线切换后,原主库(mysql-m1)修复完成,需将其重新配置为从库,加入集群,恢复 3 节点 1 主 2 从的高可用架构。

1. 修复原主库并重启 MySQL(mysql-m1 执行)

复制代码
# 完成硬件/软件修复后,重启MySQL并设置开机自启
systemctl start mysqld && systemctl enable mysqld

2. 将原主库配置为新主库的从库(mysql-m1 执行)

复制代码
# 1. 登录MySQL
mysql -uroot -p
# 2. 重置复制(清除原有主从关系)
RESET SLAVE ALL;
# 3. 配置为新主库(如mysql-s1)的从库(GTID模式)
CHANGE MASTER TO
MASTER_HOST='192.168.1.11',
MASTER_USER='repl',
MASTER_PASSWORD='Repl@808080',
MASTER_PORT=3306,
MASTER_AUTO_POSITION=1;
# 4. 启动复制并验证(双Yes)
START SLAVE;
SHOW SLAVE STATUS\G;

3. 重启 MHA 并验证集群状态(管理节点 mysql-s1)

复制代码
# 1. 重启MHA服务(故障转移后MHA会自动停止,需重启)
systemctl restart mha-app1
# 2. 验证MHA状态
masterha_check_status --conf=/etc/mha/app1.cnf
# 3. 验证主从复制状态
masterha_check_repl --conf=/etc/mha/app1.cnf

成功标志:MHA 正常运行,集群恢复为 1 主 2 从,所有从库双 Yes,数据无延迟。

十一、生产环境强化配置(必做・提升稳定性与数据安全性)

以上步骤已实现 MHA 高可用,生产环境需补充以下配置,避免单点故障、减少数据丢失、提升可维护性

1. VIP 永久化 + Keepalived(双重保障 VIP 漂移)

ifconfig绑定的 VIP 重启后丢失,结合Keepalived 实现 VIP 的自动绑定、故障检测、漂移,即使 MHA 脚本失效,Keepalived 也能保证 VIP 可用性(核心:检测 MySQL 服务状态,服务挂掉则释放 VIP)。

2. 开启 MySQL8.0 半同步复制(彻底减少数据丢失)

MHA 结合半同步复制,确保主库 binlog 至少同步至一个从库后再返回客户端,避免主库宕机导致的数据丢失

复制代码
# 主库(mysql-m1)执行
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
SET GLOBAL rpl_semi_sync_master_enabled = 1;
SET GLOBAL rpl_semi_sync_master_timeout = 1000;
# 所有从库执行
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
SET GLOBAL rpl_semi_sync_slave_enabled = 1;
STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;
# 永久生效(所有节点写入my.cnf)
echo -e "rpl_semi_sync_master_enabled=1\nrpl_semi_sync_slave_enabled=1" >> /etc/my.cnf

3. 配置 MHA 日志轮转(防止日志文件过大)

创建 logrotate 配置文件,实现日志按日切割、自动清理:

复制代码
vim /etc/logrotate.d/mha-app1

写入内容:

复制代码
/var/log/mha/app1/mha_manager.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    create 700 root root
    sharedscripts
    postrotate
        if [ -f /var/run/mha-app1.pid ]; then
            kill -USR1 `cat /var/run/mha-app1.pid`
        fi
    endscript
}

4. 生产级监控与备份(核心・不可替代)

  1. 监控告警 :通过 Zabbix/Prometheus 监控 MHA 状态、MySQL 主从状态、VIP 状态、服务器资源,关键词Failover/ERROR/Slave_IO_Running=No立即告警;
  2. 定期备份 :MHA 不替代备份,配置 xtrabackup 实现每日全量备份 + 每小时 binlog 增量备份,备份文件异地存储;
  3. 定期演练:每月至少一次故障转移演练,模拟主库宕机、网络故障,验证 MHA 有效性和应用无感知性。

5. 其他强化项

  • 从库永久只读 :确保从库始终为read_only=1/super_read_only=1,避免手动写操作污染数据;
  • 关闭透明大页:echo never > /sys/kernel/mm/transparent_hugepage/enabled,写入/etc/rc.local永久生效;
  • 配置 swap 阈值:避免 MySQL 使用 swap,提升性能。

十二、核心总结与生产注意事项

1. 核心总结

  • 版本兼容 :MySQL8.0 + 必须搭配 MHA0.58+,账号需指定mysql_native_password插件,这是兼容核心;
  • 3 节点架构:管理节点复用从库 1,资源最优,从库 1 为第一候选主库,从库 2 为备用,故障转移秒级完成;
  • 核心前提:MySQL GTID 主从复制双 Yes+SSH 免密互通,缺一不可,验证无 ERROR 再启动 MHA;
  • 生产核心:VIP 无感知漂移 + 在线主从切换 + 故障自动转移,实现业务零中断,配合半同步复制 + 定期备份,保障数据安全。

2. 生产绝对禁止项

  • 修改 / 删除 MHA 必选参数(如binlog_format=row/gtid_mode=ON/ 从库read_only);
  • 直接 kill MHA 进程,必须使用systemctl stop mha-app1masterha_stop停止;
  • 主库和从库使用相同的server-id,会导致主从复制彻底失败;
  • 放松配置文件 / 脚本权限,MHA 配置文件和脚本必须为700(仅 root 可访问),避免密码泄露。

3. 排障核心思路

  • MHA 排障优先看日志/var/log/mha/app1/mha_manager.log,所有故障细节均记录在此;
  • 主从复制故障:先看Last_Error,再检查 server-id、GTID、复制账号、网络;
  • VIP 漂移失败:检查脚本中的 VIP / 网卡名,验证ifconfig命令是否可用,防火墙是否拦截。
相关推荐
2401_838472512 小时前
构建一个桌面版的天气预报应用
jvm·数据库·python
秦苒&2 小时前
【脉脉】AI 创作者 xAMA 知无不言:在浪潮里,做会发光的造浪者
大数据·c语言·数据库·c++·人工智能·ai·操作系统
码农水水2 小时前
美团Java面试被问:Netty的ByteBuf引用计数和内存释放
java·开发语言·数据库·mysql·算法·面试·职场和发展
码农水水2 小时前
浅谈 MySQL InnoDB 的内存组件
java·开发语言·数据库·后端·mysql·面试
shjita2 小时前
mapreduce输出乱码的处理
java·开发语言·数据库
qq_192779872 小时前
将Python Web应用部署到服务器(Docker + Nginx)
jvm·数据库·python
he___H2 小时前
MySQL调优-----MySQL执行原理
数据库·mysql
luoluoal2 小时前
基于自适应svm电影评价倾向性分析
python·mysql·毕业设计·源码
刃神太酷啦2 小时前
Linux 基础 IO 收官:库的构建与使用、进程地址空间及核心知识点全解----《Hello Linux!》(11)
java·linux·c语言·数据库·c++·算法·php