MHA 高可用
MySQL-MMM 适用于对数据的一致性要求不是很高,但又想最大程度地保证业务可用性的场景。
MHA 概述
MHA (Master High Availability) 目前在 MySOL 高可用方面是一个相对成熟的解决方案,它由日本人 youshimaton 开发,是一套优秀的 MySQL 故障切换和主从提升的高可用软件。在 MySQL 故障切换过程中,MHA 能做到0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA 能最大程度上保证数据库的一致性,以达到真正意义上的高可用。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7FZXPNyP-1687789524073)(C:\Users\12389\AppData\Roaming\Typora\typora-user-images\image-20230621141918979.png)]
MHA 由两部分组成: MHA Manager (管理节点)和MHA Node(数据节点)。MHA Manager 可以部署在一台独立的机器上管理多个 Master-Slave 群集,也可以部署在一台 Slave 上。当 Master 出现故障时,它可以自动将最新数据的 Slave 提升为新的 Master ,然后将所有的其他的 Slave 重新指向新的 Master。整个故障转移过程对应用程序是完全透明的。
MHA 特点
-
自动故障切换过程中,MHA试图从宕机的主服务器上保存二进制日志,最大程度的保证数据不丢失
-
使用半同步复制,可以大大降低数据丢失的风险
-
目前MHA支持一主多从架构,最少三台服务,即一主两从;淘宝优化后 可以最少两台服务器,即一主一从
MHA 部署
案例环境
基于一主两从部署MHA,主从同步已配置
1 安装MHA
①在所有服务器上都安装 MHA 依赖的环境,首先安装 epel
源
yum install -y epel-release
# 注意,如果是本地yum源,需要从新配置网络yum源才能下载
②安装MHA Manger
依赖的perl
模块
yum install -y perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker perl-CPAN
③在所有主机安装Node组件
# 需要的源码包
mha4mysql-node-0.58.tar.gz
tar zxvf mha4mysql-node-0.58.tar.gz
cd mha4mysql-node-0.58
# ExtUtils::Makemaker模块基于make构建,这个模块构建的发行版使用一个叫Makefile.PL的文件来控制构建流程
perl Makefile.PL # 运行Makefile.PL来创建Makefile文件
make
make install
④在MHA-manager
主机上安装manager组件
# 需要的源码包
# manager有0.57和0.58版本,分别对应mysql的5.6和5.7版本,建议用0.57以上
mha4mysql-manager-0.58.tar.gz
tar zxvf mha4mysql-manager-0.58.tar.gz
cd mha4MHA-manager-0.58
perl Makefile.PL
make
make install
重要:manager 安装后在/usr/local/bin
下面会生成几个工具
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 信息。
2 配置无密码登录
①在manager上配置到所有节点的无密码认证
ssh-keygen -t rsa
-t dsa | ecdsa | ed25519 | rsa | rsa1
指定要创建的密钥的类型。可能的值为
协议版本1的“ rsa1”和“ dsa”,“ ecdsa”,“ ed25519”或
协议版本2的“ rsa”
ssh-copy-id 192.168.153.131
ssh-copy-id 192.168.153.136
ssh-copy-id 192.168.153.137
②在 MySQL 服务器上配置互相免密码登录
# master
ssh-keygen -t rsa
ssh-copy-id 192.168.153.136
ssh-copy-id 192.168.153.137
# slave1
ssh-keygen -t rsa
ssh-copy-id 192.168.153.131
ssh-copy-id 192.168.153.137
# slave2
ssh-keygen -t rsa
ssh-copy-id 192.168.153.131
ssh-copy-id 192.168.153.136
3 配置 MHA 高可用
①在 manager 节点上复制相关脚本到/usr/local/bin
目录
# 进入mha4mysql-manager解压包目录
cd mha4mysql-manager-0.58/
cp samples/scripts/* /usr/local/bin
master_ip_failover:自动切换时vip管理的脚本,不是必须,如果我们使用keepalived的,我们可以自己编写脚本完成对vip的管理,比如监控mysql,如果mysql异常,我们停止keepalived就行,这样vip就会自动漂
master_ip_online_change:在线切换时vip的管理,不是必须,同样可以可以自行编写简单的shell完成
power_manager:故障发生后关闭主机的脚本,不是必须
send_report:因故障切换后发送报警的脚本,不是必须,可自行编写简单的shell完成
②使用master_ip_failover
脚本管理VIP地址
vim /usr/local/bin/master_ip_failover
my $vip = '192.168.153.130/24';
my $key = "1";
my $ssh_start_vip = "/sbin/ifconfig eth34:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth34:$key down";
my $exit_code = 0;
③创建 MHA 软件目录并拷贝配置文件
mkdir /etc/masterha
cd mha4mysql-manager-0.58/
cp samples/conf/app1.cnf /etc/masterha/
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的日志,我这里的也就是mysql的数据目录
master_ip_failover_script=/usr/local/bin/master_ip_failover //设置自动failover时候的切换脚本
master_ip_online_change_script=/usr/local/bin/master_ip_online_change //设置手动切换时候的切换脚本
# 需要在所有数据库上创建该账户用以管理
user=mha //设置监控用户root
password=manager //设置mysql中root用户的密码,这个密码是前文中创建监控用户的那个密码
ping_interval=1 //设置监控主库,发送ping包的时间间隔,默认是3秒,尝试三次没有回应的时候自动进行railover
remote_workdir=/tmp //设置远端mysql在发生切换时binlog的保存位置
# 需要在所有从数据库上创建该账号,当主库宕机后,会用该账号来进行新的主从同步
repl_user=myslave //设置复制用户;
repl_password=123456 //设置复制用户的密码
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.153.131 -s 192.168.153.136 //实现多路由监测Master的可用性
shutdown_script="" //设置故障发生后关闭故障主机脚本(该脚本的主要作用是关闭主机放在发生脑裂,这里没有使用)
ssh_user=root //设置ssh的登录用户名
[server1] //主库IP和端口
hostname=192.168.153.131
port=3306
[server2] //从库IP和端口
hostname=192.168.153.136
port=3306
candidate_master=1 //设置为候选master,如果设置该参数以后,发生主从切换以后将会将此从库提升为主库,即使这个主库不是集群中事件最新的slave
check_repl_delay=0 //默认情况下如果一个slave落后master 100M的relay logs的话,MHA将不会选择该slave作为一个新的master,因为对于这个slave的恢复需要花费很长时间,通过设置check_repl_delay=0,MHA触发切换在选择一个新的master的时候将会忽略复制延时,这个参数对于设置了candidate_master=1的主机非常有用,因为这个候选主在切换的过程中一定是新的master
[server3] //从库IP和端口
hostname=192.168.153.137
port=3306
在所有数据库上创建MHA管理账号mha
> grant all privileges on *.* to 'mha'@'192.168.153.%' identified by 'manager';
在其他从数据库中创建用于主从复制的账号myslave
> grant replication slave on *.* to 'myslave'@'192.168.153.%' identified by '123456';
4 检查测试
①在 manager 节点测试 ssh 无密码认证,如果正常最后会输出 successfully
masterha_check_ssh -conf=/etc/masterha/app1.cnf
②测试主从连接情况
masterha_check_repl -conf=/etc/masterha/app1.cnf
报错:None of slaves can be master. Check failover configuration file or log-bin settings in my.cnf
原因提示,从库不能作为主库使用,让检查二进制文件log-bin ,如果一个数据库要作为主库,需要开启二进制文件,所以编辑从库的配置文件my.cnf
,所有从库都需要配置
解决: 在所有slave节点配置二进制日志
vim /etc/my.cnf
# 插入两行
log_bin = master-bin
log-slave-updates = true
————————————————————
systemctl restart mysqld
报错:Can’t exec “mysqlbinlog”: 没有那个文件或目录 at /usr/local/share/perl5/MHA/BinlogManager.pm line 106.
解决: 所有节点创建软连接
ln -s /usr/local/mysql/bin/mysqlbinlog /usr/local/bin/
再一次检测
masterha_check_repl -conf=/etc/masterha/app1.cnf
报错:Checking if super_read_only is defined and turned on…DBD::mysql::st execute failed: Unknown system variable ‘super_read_only’ at /usr/local/share/perl5/MHA/SlaveUtil.pm line 245.
原因:mysql5.6
没有全局的super_read_only
变量
解决办法①:一开始使用的mha0.58
版本有这个选项,换一个低版本mha0.56
的就好了
# 安装包
mha4mysql-manager-0.56.tar.gz
重新编译安装,命令复制过去覆盖就好了
解决办法②:对源代码进行修改。 所有安装MHA的节点都要修改。
vim /usr/local/share/perl5/MHA/SlaveUtil.pm
第244行:my $sth = $dbh->prepare("SELECT \@\@global.super_read_only as Value");
修改为:my $sth = $dbh->prepare("SELECT 0 as Value");
第262行:$dbh->do("SET GLOBAL super_read_only=off;");
注释掉
第275行:$dbh->do("SET GLOBAL super_read_only=on;");
修改为:$dbh->do("SET GLOBAL read_only=on;");
pm文件修改完成后是即时生效的,无需做其他操作 ,因为是只读文件,需要强制保存wq!
报错:sh: mysql: 未找到命令 mysql command failed with rc 127:0!
原因:找不到 MySQL 命令
解决:创建软链接,所有数据库节点都需要
ln -s /usr/local/mysql/bin/mysql /usr/local/bin/
报错:Bareword “FIXME_xxx” not allowed while “strict subs” in use at /usr/local/bin/master_ip_failover line 93.
原因:FIXME_xxx
不被允许
解决:根据提示编辑配置文件/usr/local/bin/master_ip_failover
,找到’FIXME_xxx’并注释
vim /usr/local/bin/master_ip_failover
93 #FIXME_xxx
再次检测,成功!
5 启动 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 &
————————————————————————————————
--remove_dead_master_conf:该参数代表当发生主从切换后,老的主库的 ip 将会从配置文件中移除。
--manger_log:日志存放位置
--ignore_last_failover:在缺省情况下,如果 MHA 检测到连续发生宕机,且两次宕机间隔不足 8 小时的话,则不会进行 Failover,之所以这样限制是为了避免 ping-pong 效应。该参数代表忽略上次 MHA 触发切换产生的文件,默认情况下, MHA 发生切换后会在日志记目录,也就是上面设置的日志 app1.failover.complete 文件,下次再次切换的时候如果发现该目录下存在该文件将不允许触发切换,除非在第一次切换后收到删除该文件,为了方便,这里设置为–ignore_last_failover
查看 MHA 状态,可以看到当前的 master 节点
masterha_check_status --conf=/etc/masterha/app1.cnf
查看 MHA 日志,也以看到当前的 master 是 ‘192.168.153.131’
cat /var/log/masterha/app1/manager.log
6 模拟master故障测试
①手动停止当前的 master
systemctl stop mysqld
②观察 MHA 日志,如果自动切换成功,最后会输出 successfully 字样
tail -f /var/log/masterha/app1/manager.log
正常自动切换一次后,MHA 进程会退出。MHA 会自动修改 app1.cnf 文件内容,将宕机的 mysql 节点删除。查看 Mysql2 是否接管 VIP
vim /etc/masterha/app1.cnf
查看[server1]模块是否删除了
拓展:如主库修复后,可继续使用如下步骤,使其重新加入群集,并将 master 作为从库。
①启动主库
systemctl start mysqld
②重新启动从库同步并设置为只读
mysql> start slave;
mysql> set global read_only=1;
③停掉当前主库(slave1)的同步进程,不然下次作为从库同步会报错
mysql> stop slave;
mysql> reset slave;