MySQL高可用方案:MHA架构详解与搭建指南
MHA(Master High Availability)是一套优秀的MySQL高可用环境下故障切换和主从复制解决方案,主要用于解决MySQL单点故障问题。该方案能够在30秒内自动完成数据库故障切换操作,并在最大程度上保证数据一致性,实现真正意义上的高可用性。MHA作为MySQL高可用解决方案,提供了自动故障转移和数据保护机制,能够有效降低数据库单点故障风险。通过本文的详细配置指南,您可以快速搭建
一、前言:MHA概述
MHA(Master High Availability)是一套优秀的MySQL高可用环境下故障切换和主从复制解决方案,主要用于解决MySQL单点故障问题。该方案能够在30秒内自动完成数据库故障切换操作,并在最大程度上保证数据一致性,实现真正意义上的高可用性。
二、MHA核心组件
1. MHA Node(数据节点)
-
运行在每台MySQL服务器上
-
负责监控MySQL实例状态和执行故障切换命令
2. MHA Manager(管理节点)
-
可单独部署或部署在slave节点上
-
管理多个master-slave集群
-
定时探测master节点状态
-
自动将最新数据的slave提升为新的master
-
故障转移过程对应用完全透明
三、MHA核心特性
-
数据保护:自动保存宕机主服务器的二进制日志,最大限度防止数据丢失
-
数据一致性:支持半同步复制,确保所有节点数据一致性
-
架构支持:支持一主多从架构,最少需要三台服务器(一主两从)
-
多集群管理:MHA Manager可管理多组主从复制
四、MHA工作原理
-
从宕机的master保存二进制日志事件
-
识别含有最新更新的slave日志
-
应用差异的中继日志到其他slave
-
应用从master保存的二进制日志事件
-
提升一个slave为新的master
-
重新配置其他slave指向新的master
五、MHA环境搭建实战
环境规划
-
MHA Manager节点:CentOS7.6,192.168.114.253
-
Master节点:CentOS7.6,192.168.114.50
-
Slave1节点:CentOS7.6,192.168.114.251
-
Slave2节点:CentOS7.6,192.168.114.252
基础环境配置
bash
# 所有节点执行 systemctl stop firewalld systemctl disable firewalld setenforce 0 # 设置主机名 hostnamectl set-hostname Master # Master节点 hostnamectl set-hostname Slave1 # Slave1节点 hostnamectl set-hostname Slave2 # Slave2节点 hostnamectl set-hostname manager # manager节点
MySQL配置
Master节点配置:
ini
[mysqld] server-id = 1 log_bin = master-bin log-slave-updates = true systemctl restart mysqld
Slave1节点配置:
ini
server-id = 2 log_bin = master-bin relay-log = relay-log-bin relay-log-index = slave-relay-bin.index systemctl restart mysqld
Slave2节点配置:
ini
server-id = 3 relay-log = relay-log-bin relay-log-index = slave-relay-bin.index systemctl restart mysqld
在 Master、Slave1、Slave2 节点上都创建两个软链接:
ini
ln -s /usr/local/mysql/bin/mysql /usr/sbin/ ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/
主从复制配置
sql
-- 所有节点创建授权用户 GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.114.%' IDENTIFIED BY '123456'; --从数据库同步使用 GRANT ALL PRIVILEGES ON *.* TO 'mha'@'192.168.114.%' IDENTIFIED BY 'manager'; -- 设置从库只读模式 SET GLOBAL read_only=1; --防止从库通过主机名连接不上主库 grant all privileges on *.* to 'mha'@'master' identified by 'manager'; grant all privileges on *.* to 'mha'@'slave1' identified by 'manager'; grant all privileges on *.* to 'mha'@'slave2' identified by 'manager'; flush privileges; (2)在 Master 节点查看二进制文件和同步点,根据具体情况自行调整 show master status; +-------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +-------------------+----------+--------------+------------------+-------------------+ | master-bin.000001 | 602 | | | | +-------------------+----------+--------------+------------------+-------------------+ (3)在 Slave1、Slave2 节点执行同步操作 change master to master_host='192.168.114.50',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=602; start slave; ##在 Master 主库插入条数据,测试是否同步## create database test_db; use test_db; create table test(id int); insert into test(id) values (1);
MHA组件安装
bash
# 所有节点安装依赖环境 yum install epel-release --nogpgcheck -y yum install -y perl-DBD-MySQL \ perl-Config-Tiny \ perl-Log-Dispatch \ perl-Parallel-ForkManager \ perl-ExtUtils-CBuilder \ perl-ExtUtils-MakeMaker \ perl-CPAN # 所有节点安装node组件 #注:安装 MHA 软件包,先在所有服务器上必须先安装 node 组件 对于每个操作系统版本不一样,这里 CentOS7.6选择 0.57 版本。 在所有服务器上必须先安装 node 组件,最后在 MHA-manager 节点上安装 manager 组件,因为 manager 依赖 node 组件。 cd /opt tar zxvf mha4mysql-node-0.57.tar.gz cd mha4mysql-node-0.57 perl Makefile.PL make && make install # Manager节点安装manager组件 tar zxvf mha4mysql-manager-0.57.tar.gz cd mha4mysql-manager-0.57 perl Makefile.PL make && make install
SSH无密码认证配置
bash
# Manager节点到所有数据库节点配置无密码访问 ssh-keygen -t rsa ssh-copy-id 192.168.114.50 ssh-copy-id 192.168.114.251 ssh-copy-id 192.168.114.252 #在 master 上配置到数据库节点 slave1 和 slave2 的无密码认证 ssh-keygen -t rsa ssh-copy-id 192.168.114.251 ssh-copy-id 192.168.114.252 #在 slave1 上配置到数据库节点 master 和 slave2 的无密码认证 ssh-keygen -t rsa ssh-copy-id 192.168.114.50 ssh-copy-id 192.168.114.252 #在 slave2 上配置到数据库节点 master 和 slave1 的无密码认证 ssh-keygen -t rsa ssh-copy-id 192.168.114.50 ssh-copy-id 192.168.114.251
MHA配置文件
复制脚本文件进行管理
#在 manager 节点上复制相关脚本到/usr/local/bin 目录 cp -rp /opt/mha4mysql-manager-0.57/samples/scripts /usr/local/bin #复制上述的自动切换时 VIP 管理的脚本到 /usr/local/bin 目录,这里使用master_ip_failover脚本来管理 VIP 和故障切换 cp /usr/local/bin/scripts/master_ip_failover /usr/local/bin
对脚本文件进行修改
vim /usr/local/bin/master_ip_failover
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;
my (
$command, $ssh_user, $orig_master_host, $orig_master_ip,
$orig_master_port, $new_master_host, $new_master_ip, $new_master_port
);
#添加内容部分
my $vip = '192.168.114.200'; #指定vip的地址
my $brdc = '192.168.114.255'; #指定vip的广播地址
my $ifdev = 'ens33'; #指定vip绑定的网卡
my $key = '1'; #指定vip绑定的虚拟网卡序列号
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip"; #代表此变量值为ifconfig ens33:1 192.168.114.200
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down"; #代表此变量值为ifconfig ens33:1 192.168.114.200 down
my $exit_code = 0; #指定退出状态码为0
#my $ssh_start_vip = "/usr/sbin/ip addr add $vip/24 brd $brdc dev $ifdev label $ifdev:$key;/usr/sbin/arping -q -A -c 1 -I $ifdev $vip;iptables -F;";
#my $ssh_stop_vip = "/usr/sbin/ip addr del $vip/24 dev $ifdev label $ifdev:$key";
#以下为原文件内容
GetOptions(
'command=s' => \$command,
'ssh_user=s' => \$ssh_user,
'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,
);
exit &main();
sub main {
print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";
if ( $command eq "stop" || $command eq "stopssh" ) {
my $exit_code = 1;
eval {
print "Disabling the VIP on old master: $orig_master_host \n";
&stop_vip();
$exit_code = 0;
};
if ($@) {
warn "Got Error: $@\n";
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "start" ) {
my $exit_code = 10;
eval {
print "Enabling the VIP - $vip on the new master - $new_master_host \n";
&start_vip();
$exit_code = 0;
};
if ($@) {
warn $@;
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "status" ) {
print "Checking the Status of the script.. OK \n";
exit 0;
}
else {
&usage();
exit 1;
}
}
sub start_vip() {
`ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
## A simple system call that disable the VIP on the old_master
sub stop_vip() {
`ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}
sub usage {
print
"Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
}
创建 MHA 软件目录并拷贝配置文件,这里使用app1.cnf配置文件来管理 mysql 节点服务器
创建 MHA 软件目录并拷贝配置文件,这里使用app1.cnf配置文件来管理 mysql 节点服务器 mkdir /etc/masterha cp /opt/mha4mysql-manager-0.57/samples/conf/app1.cnf /etc/masterha #删除原有内容,直接复制并修改节点服务器的IP地址 vim /etc/masterha/app1.cnf
修改/etc/masterha/app1.cnf配置文件:
ini
[server default] manager_log=/var/log/masterha/app1/manager.log manager_workdir=/var/log/masterha/app1 master_binlog_dir=/usr/local/mysql/data master_ip_failover_script=/usr/local/bin/master_ip_failover master_ip_online_change_script=/usr/local/bin/master_ip_online_change password=manager ping_interval=1 remote_workdir=/tmp repl_password=123456 repl_user=myslave #这里填写从库ip secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.114.251 -s 192.168.114.252 shutdown_script="" ssh_user=root user=mha [server1] hostname=192.168.114.50 port=3306 #设置候选master,主挂了自动切换到这 [server2] candidate_master=1 check_repl_delay=0 hostname=192.168.114.251 port=3306 [server3] hostname=192.168.114.252 port=3306
在master节点开启虚拟ip
/sbin/ifconfig ens33:1 192.168.114.200/24
启动与测试MHA
bash
# 测试SSH连接 masterha_check_ssh -conf=/etc/masterha/app1.cnf #最终看到这个表示ssh测试成功 Tue Nov 26 23:09:47 2020 - [info] All SSH connection tests passed successfully. # 测试主从复制 masterha_check_repl -conf=/etc/masterha/app1.cnf #能看到这个表示主从连接正常 MySQL Replication Health is OK. # 启动MHA服务 nohup masterha_manager --conf=/etc/masterha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1 & # 检查MHA状态 masterha_check_status --conf=/etc/masterha/app1.cnf #若要关闭 manager 服务,可以使用如下命令。 masterha_stop --conf=/etc/masterha/app1.cnf #或者可以直接采用 kill 进程 ID 的方式关闭。
测试主从复制可能遇到的报错

解决:注销或删除所有节点my.cnf的default-character-set=utf8
测试成功状态

六、故障模拟与恢复
故障模拟
bash
# 停止Master节点MySQL服务 systemctl stop mysqld # 查看Slave1是否接管VIP ifconfig
可以看到slave接管了vip

故障修复步骤
修复MySQL服务:
bash
systemctl restart mysqld
Master节点配置:
ini
#将原slave成为master的设备配置进行修改 [mysqld] log_bin = master-bin log-slave-updates = true systemctl restart mysqld
Slave节点配置:
ini
#将原master成为slave的设备配置进行修改 [mysqld] log_bin = master-bin relay-log = relay-log-bin relay-log-index = slave-relay-bin.index systemctl restart mysqld
修复主从复制:
sql
-- 在现主库查看二进制文件和同步点 SHOW MASTER STATUS; -- 在原主库执行同步操作 CHANGE MASTER TO MASTER_HOST='192.168.114.251', MASTER_USER='myslave', MASTER_PASSWORD='123456', MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=602; START SLAVE;


在manager重新进行配置
vi /etc/masterha/app1.cnf #重新指定主从 ...... secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.114.50 -s 192.168.114.252 ...... [server1] hostname=192.168.114.251 port=3306 [server2] candidate_master=1 check_repl_delay=0 hostname=192.168.114.50 port=3306 [server3] hostname=192.168.114.252 port=3306
重新启动MHA服务:
bash
nohup masterha_manager --conf=/etc/masterha/app1.cnf --remove_dead_master_conf \ --ignore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1 &
修复后结果,251成为新master,50成为slave,恢复正常运行

七、总结
MHA作为MySQL高可用解决方案,提供了自动故障转移和数据保护机制,能够有效降低数据库单点故障风险。通过本文的详细配置指南,您可以快速搭建一套稳定的MySQL高可用环境。在实际生产环境中,建议结合监控系统和报警机制,实现全方位的数据库高可用保障。
注意事项:
-
确保所有节点时间同步
-
定期检查MHA日志和状态
-
测试环境充分验证后再部署到生产环境
-
考虑网络延迟和带宽对复制性能的影响
通过合理配置和维护,MHA能够为MySQL数据库提供可靠的高可用性保障,确保业务连续性和数据安全性。
更多推荐


所有评论(0)