一、前言:MHA概述

二、MHA核心组件

1. MHA Node(数据节点)

2. MHA Manager(管理节点)

三、MHA核心特性

四、MHA工作原理

五、MHA环境搭建实战

环境规划

基础环境配置

MySQL配置

主从复制配置

MHA组件安装

SSH无密码认证配置

MHA配置文件

启动与测试MHA

六、故障模拟与恢复

故障模拟

故障修复步骤

七、总结

一、前言: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工作原理

  1. 从宕机的master保存二进制日志事件

  2. 识别含有最新更新的slave日志

  3. 应用差异的中继日志到其他slave

  4. 应用从master保存的二进制日志事件

  5. 提升一个slave为新的master

  6. 重新配置其他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数据库提供可靠的高可用性保障,确保业务连续性和数据安全性。

Logo

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

更多推荐