使用 MHA 实现 MySQL 主从复制高可用
一、MHA 概述
MHA(Master High Availability)是由日本一家公司开发的一套 MySQL 高可用性环境下故障切换和主从提升的高可用软件,目前在 MySQL 高可用方面是一个相对成熟的的解决方案。在 MySQL 故障切换过程中,MHA 能做到在 0~30 秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA 能在最大程度上保证数据的一致性,以达到真正意义上的高可用。
1.MHA 的主要功能
- 自动故障检测和自动故障转移;
- 交互式(手动)故障转移;
- 在线切换 Master 到不同的主机;
2.MHA 的优势
- 自动故障转移快;
- 主库崩溃不存在数据一致性问题;
- 配置不需要对当前 MySQL 环境做重大修改;
- 不需要添加额外的服务器(仅一台 manager 就可管理上百台 replication);
- 性能优秀,可工作在半同步复制和异步复制;
- 只要 replication 支持的存储引擎,MHA 都支持,不会局限于 innodb;
3.MHA 组成部分
MHA 由 Manager 节点和 Node 节点组成;MHA Manager 可以单独部署在一台独立的机器上管理多个 master-slave 集群,也可以部署在一台 slave 节点上。MHA Node 运行在每台 MySQL 服务器上。
4.MHA 工作原理
- MHA Manager 会定时探测集群中的 Master 节点;
- 当 Master 出现故障时,从宕机崩溃的 Master 保存二进制日志时间(binlog events);
- 识别含有最新更新的 Slave;
- 应用差异的中继日志(relay log)到其他的 Slave;
- 应用从 Master 保存的二进制日志事件(binlog events);
- 提升一个 Slave 为新的 Master,使其他 Slave 连接新的 Master 进行复制;
二、部署 MHA 实现 MySQL 主从复制高可用
准备工作:
主机名 | 操作系统 | IP地址 | 担任角色 |
master | CentOS7 | 192.168.1.1 | MySQL-主节点 |
slave1 | 192.168.1.2 | MySQL-从节点 | |
slave2 | 192.168.1.3 | MySQL-从节点 | |
manager | 192.168.1.4 | MHA manager 节点 |
- 如果未安装 MySQL 数据库 需看:Centos7安装Mysql数据库 来进行安装。(除了 Manager 不需要安装,其他机器都需要安装)
- 实验所需软件包从这个连接下载:https://pan.baidu.com/s/1c39hxF-beUxu9Cl_OaZSuQ
- 提取码:whwo
1.配置免密登陆
由于 MHA manager 通过 SSH 访问所有的 node 节点,各个 node 节点也同样通过 SSH 来相互发送不同的 relay log 文件,所以要在每一个 node 和 manager 上配置 SSH 无密码登陆。
- 在每个节点上分别生成密钥对。
[root@master ~]# ssh-keygen -t rsa #一路回车即可
- 每台节点分别将自己的公钥发送到另外的三台节点。(下面以 master 主机为例)
[root@master ~]# ssh-copy-id 192.168.1.2
[root@master ~]# ssh-copy-id 192.168.1.3
[root@master ~]# ssh-copy-id 192.168.1.4
2.安装 MHA 软件包
准备工作:四台机器都要做
[root@manager ~]# mkdir /root/mha
[root@manager ~]# cd /root/mha
[root@manager mha]# ls
mha4mysql-manager-0.57-0.el7.noarch.rpm mhapath.tar.gz mha4mysql-node-0.57-0.el7.noarch.rpm
[root@manager mha]# tar zxf mhapath.tar.gz
[root@manager mha]# cat <<END > /etc/yum.repos.d/CentOS7.repo
[centos]
name=centos7
baseurl=file:///mnt
enabled=1
gpgcheck=0
[mha]
name=mha
baseurl=file:///root/mha/mhapath
enabled=1
gpgcheck=0
END
[root@manager mha]# mount /dev/cdrom /mnt/
1)在各节点上安装 mha4mysql-node
[root@manager ~]# yum -y install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager --skip-broken --nogpgcheck
[root@manager ~]# rpm -ivh /root/mha/mha4mysql-node-0.57-0.el7.noarch.rpm
2)在管理节点上安装 manager 节点
[root@manager ~]# yum -y install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker perl-CPAN
[root@manager ~]# rpm -ivh /root/mha/mha4mysql-manager-0.57-0.el7.noarch.rpm
3)manager 管理工具
在 manager 节点安装完成后会生成一些管理工具,manager 的主要管理工具有:
masterha_check_ssh
:检查 MHA 的 SSH 配置状况。masterha_check_repl
:检查 MySQL 复制状况。masterha_manager
:启动 MHA。masterha_check_status
:检查当前 MHA 运行状态。masterha_master_monitor
:检查 Master 是否宕机。masterha_master_switch
:控制故障转移(自动或者手动)。masterha_conf_host
:添加或删除配置的 server 信息。
3.配置主从复制
1)主服务器上配置
[root@master ~]# cat <<END >> /etc/my.cnf
log-bin=mysql-bin-master
server-id=1
END
[root@master ~]# systemctl restart mysqld
[root@master ~]# mysql -uroot -p123456
mysql> grant replication slave on *.* to repl@'192.168.1.%' identified by '123456';
mysql> grant all privileges on *.* to root@'192.168.1.%' identified by '123456';
mysql> flush privileges;
mysql> exit
2)从服务器配置
[root@slave1 ~]# cat <<END >> /etc/my.cnf
log-bin=mysql-slave1 #slave2改为2
server-id=2 #slave2改为3
log_slave_updates=1
END
[root@slave1 ~]# systemctl restart mysqld
[root@slave1 ~]# mysql -uroot -p123456
mysql> grant replication slave on *.* to repl@'192.168.1.%' identified by '123456';
mysql> grant all privileges on *.* to root@'192.168.1.%' identified by '123456';
mysql> flush privileges;
mysql> exit
3)建立主从复制
两台从节点操作一致
[root@slave1 ~]# mysql -uroot -p123456
mysql> change master to
master_host='192.168.1.1',
master_user='repl',
master_password='123456';
mysql> start slave;
mysql> show slave status\G;
4.设置 MySQL 程序及 binglog 程序的软连接
[root@master ~]# ln -s /usr/local/mysql/bin/mysql /usr/bin/mysql
[root@master ~]# ln -s /usr/local/mysql/bin/mysqlbinlog /usr/local/bin/mysqlbinlog
5.在两台 Slave 设置临时只读和不清除中继日志
[root@slave1 ~]# mysql -uroot -p123456 -e 'set global read_only=1'
[root@slave1 ~]# mysql -uroot -p123456 -e 'set global relay_log_purge=0'
6.配置 MHA 工作目录及配置文件
[root@manager ~]# mkdir -p /etc/masterha
[root@manager ~]# mkdir -p /var/log/masterha/app1
[root@manager ~]# vim /etc/masterha/app1.cnf
[server default]
manager_workdir=/var/log/masterha/app1 #设置 manager 的工作目录
manager_log=/var/log/masterha/app1/manager.log #设置 manager 的日志文件
master_binlog_dir=/usr/local/mysql/data/ #设置 master 保存 binlog 的位置,以便 MHA 可以找到 master 的日志
user=root #设置监控 mysql 的用户
password=123456 #设置监控 mysql 用户的密码
ping_interval=1 #设置监控主库,发送 ping 包的时间间隔
remote_workdir=/tmp #设置远端 mysql 在发生切换时 binlog 的保存位置
repl_user=repl #设置 mysql 中用于复制的用户
repl_password=123456 #设置 mysql 中用于复制的用户密码
ssh_user=root #设置 ssh 的登录用户名
[server1]
hostname=192.168.1.1
port=3306
[server2]
hostname=192.168.1.2
port=3306
candidate_master=1 #设置当前节点为候选的 master
check_repl_delay=0 #当落后 master 100M 的 relay logs 时,MHA 将不会选择该 slave 作为一个新的 master
[server3]
hostname=192.168.1.3
port=3306
7.检查 MHA 的环境是否工作正常
1)检测 SSH 连接是否配置正常
[root@manager ~]# masterha_check_ssh --conf=/etc/masterha/app1.cnf
2)在管理节点检查复制配置
- 为了让 MHA 正常工作,所有的 master 和 slave 必须在配置文件中正确配置。
[root@manager ~]# masterha_check_repl --conf=/etc/masterha/app1.cnf
三、MHA 的管理
MySQL 中主从的工作状态检测及切换是由 manager 节点来完成的,MHA 安装完成以及检测通过后就可以根据自己的需求开启以及停止 manager。
1.启动 Manager
Manager 是通过 masterha_manager
命令开启,启动后需要将它放在后台运行。
[root@manager ~]# 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 &
2.检测 Manager 的工作状态
当 MHA manager 启动监控以后,如果没有异常则不会打印任何信息。我们可通过 masterha_check_status
命令检查 manager 的状态。
[root@manager ~]# masterha_check_status --conf=/etc/masterha/app1.cnf
3.在 MHA 环境中配置 VIP
通过 MHA 进行故障转以后,连接 MySQL 数据库的服务并不知道 MySQL 复制环境中进行了故障的转移,同时连 MySQL 的服务也无法知晓主节点是哪一个,此时,可以通过配置 VIP 的方式让所有的应用程序连接 VIP,当 MySQL 故障切换时,VIP 会自动漂移到新的主节点。
1)在 master 上配置 VIP
[root@master ~]# ifconfig ens33:1 192.168.1.188 netmask 255.255.255.0 up
[root@master ~]# ifconfig ens33:1
2)修改 MHA 配置文件,使其支持 VIP
[root@manager ~]# vim /etc/masterha/app1.cnf
在 [server default] 项下面添加:
master_ip_failover_script=/usr/bin/master_ip_failover
3)编写 VIP 自动切换脚本
[root@master ~]# vim /usr/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.1.188/24';
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down";
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 \"`;
}
sub stop_vip() {
return 0 unless ($ssh_user);
`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";
}
[root@manager ~]# chmod +x /usr/bin/master_ip_failover #添加可执行权限
再次检测,结果应该和上面检测结果一样才对
[root@manager ~]# masterha_check_repl --conf=/etc/masterha/app1.cnf
4.开启监控
[root@manager ~]# 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 &
[root@manager ~]# masterha_check_status --conf=/etc/masterha/app1.cnf
5.验证故障切换
1)关闭 master 上的 数据库
[root@master ~]# systemctl stop mysqld
2)查看 Manager 日志
[root@manager ~]# tail -n10 /var/log/masterha/app1/manager.log
3)在 192.168.1.2 主机中查看 MHA VIP 是否漂移
[root@slave1 ~]# ifconfig ens33:1