MySQL高可用方案MHA的部署和原理
MHA(Master High Availability)是一套相对成熟的MySQL高可用方案,能做到在0~30s内自动完成数据库的故障切换操作,在master服务器不宕机的情况下,基本能保证数据的一致性。
它由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。其中,MHA Manager可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署在一台slave上。MHA Node则运行在每个mysql节点上,MHA Manager会定时探测集群中的master节点,当master出现故障时,它自动将最新数据的slave提升为master,然后将其它所有的slave指向新的master。
在MHA自动故障切换过程中,MHA试图保存master的二进制日志,从而最大程度地保证数据不丢失,当这并不总是可行的,譬如,主服务器硬件故障或无法通过ssh访问,MHA就没法保存二进制日志,这样就只进行了故障转移但丢失了最新数据。可结合MySQL 5.5中推出的半同步复制来降低数据丢失的风险。
MHA软件由两部分组成:Manager工具包和Node工具包,具体说明如下:
MHA Manager:
1. masterha_check_ssh:检查MHA的SSH配置状况
2. masterha_check_repl:检查MySQL的复制状况
3. masterha_manager:启动MHA
4. masterha_check_status:检测当前MHA运行状态
5. masterha_master_monitor:检测master是否宕机
6. masterha_master_switch:控制故障转移(自动或手动)
7. masterha_conf_host:添加或删除配置的server信息
8. masterha_stop:关闭MHA
MHA Node:
save_binary_logs:保存或复制master的二进制日志
apply_diff_relay_logs:识别差异的relay log并将差异的event应用到其它slave中
filter_mysqlbinlog:去除不必要的ROLLBACK事件(MHA已不再使用这个工具)
purge_relay_logs:消除中继日志(不会堵塞SQL线程)
另有如下几个脚本需自定义:
1. master_ip_failover:管理VIP
2. master_ip_online_change:
3. masterha_secondary_check:当MHA manager检测到master不可用时,通过masterha_secondary_check脚本来进一步确认,减低误切的风险。
4. send_report:当发生故障切换时,可通过send_report脚本发送告警信息。
集群信息
角色 IP地址 ServerID 类型
Master 192.168.244.10 1 写入
Candicate master 192.168.244.20 2 读
Slave 192.168.244.30 3 读
Monitor host 192.168.244.40 监控集群组
注:操作系统均为RHEL 6.7
其中,master对外提供写服务,备选master提供读服务,slave也提供相关的读服务,一旦master宕机,将会把备选master提升为新的master,slave指向新的master
一、在所有节点上安装MHA node
1. 在MySQL服务器上安装MHA node所需的perl模块(DBD:mysql)
# yum install perl-DBD-MySQL -y
2. 在所有的节点上安装mha node
下载地址为:https://code.google.com/p/mysql-master-ha/wiki/Downloads?tm=2
由于该网址在国内被墙,相关文件下载后,放到了个人网盘中,http://pan.baidu.com/s/1boS31vT,有需要的童鞋可自行下载。
# tar xvf mha4mysql-node-0.56.tar.gz
# cd mha4mysql-node-0.56
# perl Makefile.PL
Can't locate ExtUtils/MakeMaker.pm in @INC (@INC contains: inc /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at inc/Module/Install/Can.pm line 6. BEGIN failed--compilation aborted at inc/Module/Install/Can.pm line 6. Compilation failed in require at inc/Module/Install.pm line 283. Can't locate ExtUtils/MakeMaker.pm in @INC (@INC contains: inc /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at inc/Module/Install/Makefile.pm line 4. BEGIN failed--compilation aborted at inc/Module/Install/Makefile.pm line 4. Compilation failed in require at inc/Module/Install.pm line 283. Can't locate ExtUtils/MM_Unix.pm in @INC (@INC contains: inc /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at inc/Module/Install/Metadata.pm line 349.
通过报错可以看出,是相关依赖包没有安装。
# yum install perl-ExtUtils-MakeMaker -y
# perl Makefile.PL
*** Module::AutoInstall version 1.03 *** Checking for Perl dependencies... Can't locate CPAN.pm in @INC (@INC contains: inc /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at inc/Module/AutoInstall.pm line 277.
# yum install perl-CPAN -y
# perl Makefile.PL
*** Module::AutoInstall version 1.03 *** Checking for Perl dependencies... [Core Features] - DBI ...loaded. (1.609) - DBD::mysql ...loaded. (4.013) *** Module::AutoInstall configuration finished. Checking if your kit is complete... Looks good Writing Makefile for mha4mysql::node
# make
# make install
至此,MHA node节点安装完毕,会在/usr/local/bin下生成以下脚本文件
# ll /usr/local/bin/ total 44 -r-xr-xr-x 1 root root 16367 Jul 20 07:00 apply_diff_relay_logs -r-xr-xr-x 1 root root 4807 Jul 20 07:00 filter_mysqlbinlog -r-xr-xr-x 1 root root 8261 Jul 20 07:00 purge_relay_logs -r-xr-xr-x 1 root root 7525 Jul 20 07:00 save_binary_logs
二、在Monitor host节点上部署MHA Manager
# tar xvf mha4mysql-manager-0.56.tar.gz
# cd mha4mysql-manager-0.56
# perl Makefile.PL
# make
# make install
执行完毕后,会在/usr/local/bin下新增以下几个文件
三、配置SSH登录无密码验证
1. 在manager上配置到所有Node节点的无密码验证
# ssh-keygen
一路按“Enter”
# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
2. 在Master(192.168.244.10)上配置
# ssh-keygen
# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
3. 在Candicate master(192.168.244.20)上配置
# ssh-keygen
# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
4. 在Slave(192.168.244.30)上配置
# ssh-keygen
# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
四、搭建主从复制环境
1. 在Master上执行备份
# mysqldump --master-data=2 --single-transaction -R --triggers -A > all.sql
其中,-R是备份存储过程,--triggers是备份触发器 -A代表全库
2. 在Master上创建复制用户
mysql> grant replication slave on *.* to 'repl'@'192.168.244.%' identified by 'repl'; Query OK, 0 rows affected (0.09 sec)
3. 查看备份文件all.sql中的CHANGE MASTER语句
# head -n 30 all.sql
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=120;
4. 将备份文件复制到Candicate master和Slave上
# scp all.sql 192.168.244.20:/root/
# scp all.sql 192.168.244.30:/root/
5. 在Candicate master上搭建从库
# mysql < all.sql
设置复制信息
6. 在Slave上搭建从库
7. slave服务器设置为read only
mysql> set global read_only=1; Query OK, 0 rows affected (0.04 sec)
8. 在Master中创建监控用户
mysql> grant all privileges on *.* to 'monitor'@'%' identified by 'monitor123'; Query OK, 0 rows affected (0.07 sec)
五、 配置MHA
1. 在Monitor host(192.168.244.40)上创建MHA工作目录,并且创建相关配置文件
# mkdir -p /etc/masterha
# vim /etc/masterha/app1.cnf
[server default] manager_log=/masterha/app1/manager.log //设置manager的日志 manager_workdir=/masterha/app1 //设置manager的工作目录 master_binlog_dir=/var/lib/mysql //设置master默认保存binlog的位置,以便MHA可以找到master的日志 master_ip_failover_script= /usr/local/bin/master_ip_failover //设置自动failover时候的切换脚本 master_ip_online_change_script= /usr/local/bin/master_ip_online_change //设置手动切换时候的切换脚本 user=monitor // 设置监控用户 password=monitor123 //设置监控用户的密码 ping_interval=1 //设置监控主库,发送ping包的时间间隔,默认是3秒,尝试三次没有回应的时候进行自动failover remote_workdir=/tmp //设置远端mysql在发生切换时binlog的保存位置 repl_user=repl //设置复制环境中的复制用户名 repl_password=repl //设置复制用户的密码 report_script=/usr/local/bin/send_report //设置发生切换后发送的报警的脚本 secondary_check_script= /usr/local/bin/masterha_secondary_check -s 192.168.244.20 -s 192.168.244.30 --user=root --master_host=192.168.244.10 --master_ip=192.168.244.10 --master_port=3306 //一旦MHA到master的监控之间出现问题,MHA Manager将会判断其它两个slave是否能建立到master_ip 3306端口的连接 shutdown_script="" //设置故障发生后关闭故障主机脚本(该脚本的主要作用是关闭主机防止发生脑裂) ssh_user=root //设置ssh的登录用户名 [server1] hostname=192.168.244.10 port=3306 [server2] hostname=192.168.244.20 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] hostname=192.168.244.30 port=3306
注意:
1> 在编辑该文件时,后面的注释切记要去掉,MHA并不会将后面的内容识别为注释。
2> 配置文件中设置了master_ip_failover_script和secondary_check_script两个选项,对应的文件在上面提供的百度云盘中有。
2. 设置relay log清除方式(在每个Slave上)
mysql> set global relay_log_purge=0; Query OK, 0 rows affected (0.00 sec)
MHA在发生切换过程中,从库在恢复的过程中,依赖于relay log的相关信息,所以我们这里要将relay log的自动清楚设置为OFF,采用手动清楚relay log的方式。
在默认情况下,从服务器上的中继日志会在SQL线程执行完后被自动删除。但是在MHA环境中,这些中继日志在恢复其它从服务器时可能会被用到,因此需要禁用中继日志的自动清除。改为定期手动清除SQL线程应用完的中继日志。
在ext3文件系统下,删除大的文件需要一定的时间,这样会导致严重的复制延迟,所以在Linux中,一般都是通过硬链接的方式来删除大文件。
3. 设置定期清理relay脚本
MHA节点中包含了purge_relay_logs脚本,它可以为relay log创建硬链接,执行set global relay_log_purge=1,等待几秒钟以便SQL线程切换到新的中继日志,再执行set global relay_log_purge=0。
下面看看脚本的使用方法:
# purge_relay_logs --user=monitor --password=monitor123 -disable_relay_log_purge --workdir=/tmp/
其中,
--user:mysql用户名
--password:mysql用户的密码
--host: mysqlserver地址
--workdir:指定创建relay log的硬链接的位置,默认的是/var/tmp。由于系统不同分区创建硬链接文件会失败,故需要指定具体的硬链接的位置。
--disable_relay_log_purge:默认情况下,如果relay_log_purge=1,则脚本会直接退出。通过设置这个参数,该脚本会首先将relay_log_purge设置为1,清除掉relay log后,再将该参数设置为0。
设置crontab来定期清理relay log
MHA在切换的过程中会直接调用mysqlbinlog命令,故需要在环境变量中指定mysqlbinlog的具体路径。
# vim /etc/cron.d/purge_relay_logs
0 4 * * * /usr/local/bin/purge_relay_logs --user=monitor --password=monitor123 -disable_relay_log_purge --workdir=/tmp/ >> /tmp/purge _relay_logs.log 2>&1
注意:最好是每台slave服务器在不同时间点执行该计划任务。
4. 将mysqlbinlog的路径添加到环境变量中