本文档整合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=ON、gtid_mode=ON; - 主库(mysql-m1):
read_only=OFF、super_read_only=OFF; - 两个从库(mysql-s1/mysql-s2):
read_only=ON、super_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: Yes、Slave_SQL_Running: Yes(核心,无任何例外);Retrieved_Gtid_Set、Executed_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 秒):
- MHA 检测到主库无响应,输出
Master is down!; - 选择第一候选主库 mysql-s1(管理节点),复制原主库未同步 binlog;
- 提升 mysql-s1 为新主库,关闭其只读模式;
- 让从库 2(mysql-s2)指向新主库 mysql-s1,重启复制;
- 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. 生产级监控与备份(核心・不可替代)
- 监控告警 :通过 Zabbix/Prometheus 监控 MHA 状态、MySQL 主从状态、VIP 状态、服务器资源,关键词
Failover/ERROR/Slave_IO_Running=No立即告警; - 定期备份 :MHA 不替代备份,配置 xtrabackup 实现每日全量备份 + 每小时 binlog 增量备份,备份文件异地存储;
- 定期演练:每月至少一次故障转移演练,模拟主库宕机、网络故障,验证 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-app1或masterha_stop停止; - 主库和从库使用相同的
server-id,会导致主从复制彻底失败; - 放松配置文件 / 脚本权限,MHA 配置文件和脚本必须为
700(仅 root 可访问),避免密码泄露。
3. 排障核心思路
- MHA 排障优先看日志 :
/var/log/mha/app1/mha_manager.log,所有故障细节均记录在此; - 主从复制故障:先看
Last_Error,再检查 server-id、GTID、复制账号、网络; - VIP 漂移失败:检查脚本中的 VIP / 网卡名,验证
ifconfig命令是否可用,防火墙是否拦截。