当mysql数据库集群中master出现故障时,如果我们不手动进行master的切换,数据库就会瘫痪,这篇博客写的是利用MHA-7实现手动以及自动的主从切换

一、MySQL高可用架构之MHA简介

1.什么是MHA

MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton(现就职于Facebook公司)开发,是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件。在MySQL故障切换过程中,MHA能做到在0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA能在最大程度上保证数据的一致性,以达到真正意义上的高可用。

2.MHA的工作原理

该软件由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。MHA Manager可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署在一台slave节点上。MHA Node运行在每台MySQL服务器上,MHA Manager会定时探测集群中的master节点,当master出现故障时,它可以自动将最新数据的slave提升为新的master,然后将所有其他的slave重新指向新的master。整个故障转移过程对应用程序完全透明。

在MHA自动故障切换过程中,MHA试图从宕机的主服务器上保存二进制日志,最大程度的保证数据的不丢失,但这并不总是可行的。例如,如果主服务器硬件故障或无法通过ssh访问,MHA没法保存二进制日志,只进行故障转移而丢失了最新的数据。使用MySQL 5.5的半同步复制,可以大大降低数据丢失的风险。MHA可以与半同步复制结合起来。如果只有一个slave已经收到了最新的二进制日志,MHA可以将最新的二进制日志应用于其他所有的slave服务器上,因此可以保证所有节点的数据一致性。

目前MHA主要支持一主多从的架构,要搭建MHA,要求一个复制集群中必须最少有三台数据库服务器,一主二从,即一台充当master,一台充当备用master,另外一台充当从库,因为至少需要三台服务器,出于机器成本的考虑,淘宝也在该基础上进行了改造,目前淘宝TMHA已经支持一主一从。

3.MHA的工作步骤

  1. 从宕机崩溃的master保存二进制日志事件(binlog events);
  2. 识别含有最新更新的slave;
  3. 应用差异的中继日志(relay log)到其他的slave;
  4. 应用从master保存的二进制日志事件(binlog events);
  5. 提升一个slave为新的master;
  6. 使其他的slave连接新的master进行复制;

MHA软件由两部分组成,Manager工具包和Node工具包,具体的说明如下。

Manager工具包主要包括以下几个工具:

masterha_check_ssh              ##检查MHA的SSH配置状况
masterha_check_repl             ##检查MySQL复制状况
masterha_manger                 ##启动MHA
masterha_check_status           ##检测当前MHA运行状态
masterha_master_monitor         ##检测master是否宕机
masterha_master_switch          ##控制故障转移(自动或者手动)
masterha_conf_host              ##添加或删除配置的server信息

Node工具包(这些工具通常由MHA Manager的脚本触发,无需人为操作)主要包括以下几个工具:

save_binary_logs                ##保存和复制master的二进制日志
apply_diff_relay_logs           ##识别差异的中继日志事件并将其差异的事件应用于其他的slave
filter_mysqlbinlog              ##去除不必要的ROLLBACK事件(MHA已不再使用这个工具)
purge_relay_logs                ##清除中继日志(不会阻塞SQL线程)

二、部署MHA

实验环境:

  • server1:master数据库
  • server2:slave数据库
  • server3:slave数据库
  • server:mha-manager节点
  • 软件:MHA ==> 点击下载       提取码: au4v

我们在作mha实验之前,需要我们首先将我们的集群配置为基于gtid半同步模式的一主两从,当然这不是硬性要求,配置为一般的一主两从模式也可以,只是半同步模式更有利于减少数据损失,可以查看我之前写的如何配置半同步的博客


接下俩正式进入配置MHA环节

1.server1:

首先编辑配置文件

vim /etc/my.cnf                    ##添加下列内容
log_slave_updates=on
log_bin=binlog

安装mha节点软件,使之成为mha节点(在mha文件夹内,我在文章一开头分享的)

yum install mha4mysql-node-0.58-0.el7.centos.noarch.rpm -y

2.server2:

安装mha节点软件,使之成为mha节点(在mha文件夹内,我在文章一开头分享的)

yum install mha4mysql-node-0.58-0.el7.centos.noarch.rpm -y

3.server3:

安装mha节点软件,使之成为mha节点(在mha文件夹内,我在文章一开头分享的)

yum install mha4mysql-node-0.58-0.el7.centos.noarch.rpm -y

4.server4:

这里我使用lftp将mha软件包download到了我的server4,然后全部安装上

yum install * -y

1.我们作ssh加密,使server4访问servre1,server2,server3都为免密访问,注意,server4的解析一定也要做好

ssh-keygen                        ##获取密钥
ssh-copy-id -i server1:           ##加密server1,对server2和server3作同样操作

然后进行mha设置的编写

mkdir /etc/masterha/
vim /etc/masterha/app1.cnf                        ##这只是个模板,可根据自己需求,进行修改

[server default]
manager_workdir=/etc/masterha        //设置manager的工作目录
manager_log=/var/log/masterha.log    //设置manager的日志
master_binlog_dir=/etc/masterha                  //设置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  //设置手动切换时候的切换脚本
password=123456         //设置mysql中root用户的密码,这个密码是前文中创建监控用户的那个密码
user=root               设置监控用户root
ping_interval=1         //设置监控主库,发送ping包的时间间隔,默认是3秒,尝试三次没有回应的时候自动进行railover
remote_workdir=/tmp     //设置远端mysql在发生切换时binlog的保存位置
repl_password=123456    //设置复制用户的密码
repl_user=repl          //设置复制环境中的复制用户名
report_script=/usr/local/send_report    //设置发生切换后发送的报警的脚本
secondary_check_script= /usr/local/bin/masterha_secondary_check -s server03 -s server02            
shutdown_script=""      //设置故障发生后关闭故障主机脚本(该脚本的主要作用是关闭主机放在发生脑裂,这里没有使用)
ssh_user=root           //设置ssh的登录用户名

[server1]
hostname=192.168.0.50
port=3306

[server2]
hostname=192.168.0.60
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.0.70
port=3306
[root@192.168.0.20 ~]#

接下来这个是我配置的

主从切换mysql原理 mysql 主从切换工具_主从切换mysql原理

主从切换mysql原理 mysql 主从切换工具_vip_02

  接下来进行测试

masterha_check_ssh --conf=/etc/masterha/app1.cnf        ##检查ssh是否无密登陆,可以根据报错,进行纠错

但是这里比较好的做法是,直接分发密钥 ,然后查看用用户是否拥有权限

masterha_check_repl --conf=/etc/masterha/app1.cnf        ##出现报错,如下

Fri Mar  1 23:45:47 2019 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Fri Mar  1 23:45:47 2019 - [info] Reading application default configuration from /etc/masterha/app1.cnf..
Fri Mar  1 23:45:47 2019 - [info] Reading server configuration from /etc/masterha/app1.cnf..
Fri Mar  1 23:45:47 2019 - [info] MHA::MasterMonitor version 0.58.
Fri Mar  1 23:45:47 2019 - [error][/usr/share/perl5/vendor_perl/MHA/Server.pm, ln180] Got MySQL error when connecting 172.25.1.3(172.25.1.3:3306) :1130:Host 'server4' is not allowed to connect to this MySQL server, but this is not a MySQL crash. Check MySQL server settings.
Fri Mar  1 23:45:47 2019 - [error][/usr/share/perl5/vendor_perl/MHA/ServerManager.pm, ln301]  at /usr/share/perl5/vendor_perl/MHA/ServerManager.pm line 297.
Fri Mar  1 23:45:47 2019 - [error][/usr/share/perl5/vendor_perl/MHA/Server.pm, ln180] Got MySQL error when connecting 172.25.1.2(172.25.1.2:3306) :1130:Host 'server4' is not allowed to connect to this MySQL server, but this is not a MySQL crash. Check MySQL server settings.
Fri Mar  1 23:45:47 2019 - [error][/usr/share/perl5/vendor_perl/MHA/ServerManager.pm, ln301]  at /usr/share/perl5/vendor_perl/MHA/ServerManager.pm line 297.
Fri Mar  1 23:45:47 2019 - [error][/usr/share/perl5/vendor_perl/MHA/Server.pm, ln180] Got MySQL error when connecting 172.25.1.1(172.25.1.1:3306) :1045:Access denied for user 'root'@'server4' (using password: YES), but this is not a MySQL crash. Check MySQL server settings.
Fri Mar  1 23:45:47 2019 - [error][/usr/share/perl5/vendor_perl/MHA/ServerManager.pm, ln301]  at /usr/share/perl5/vendor_perl/MHA/ServerManager.pm line 297.
Fri Mar  1 23:45:48 2019 - [error][/usr/share/perl5/vendor_perl/MHA/ServerManager.pm, ln309] Got fatal error, stopping operations
Fri Mar  1 23:45:48 2019 - [error][/usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm, ln427] Error happened on checking configurations.  at /usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm line 329.
Fri Mar  1 23:45:48 2019 - [error][/usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm, ln525] Error happened on monitoring servers.
Fri Mar  1 23:45:48 2019 - [info] Got exit code 1 (Not master dead).

MySQL Replication Health is NOT OK!

应该是权限不够,在server1的数据库进行授权操作

mysql> grant all on *.* to root@'172.25.1.%' identified by 'Mysql1994.';
mysql> flush privileges;

再次检查

masterha_check_repl --conf=/etc/masterha/app1.cnf        ##出现报错,如下

Sat Mar  2 00:06:26 2019 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Sat Mar  2 00:06:26 2019 - [info] Reading application default configuration from /etc/masterha/app1.cnf..
Sat Mar  2 00:06:26 2019 - [info] Reading server configuration from /etc/masterha/app1.cnf..
Sat Mar  2 00:06:26 2019 - [info] MHA::MasterMonitor version 0.58.
Sat Mar  2 00:06:27 2019 - [info] GTID failover mode = 1
Sat Mar  2 00:06:27 2019 - [info] Dead Servers:
Sat Mar  2 00:06:27 2019 - [info] Alive Servers:
Sat Mar  2 00:06:27 2019 - [info]   172.25.1.1(172.25.1.1:3306)
Sat Mar  2 00:06:27 2019 - [info]   172.25.1.2(172.25.1.2:3306)
Sat Mar  2 00:06:27 2019 - [info]   172.25.1.3(172.25.1.3:3306)
Sat Mar  2 00:06:27 2019 - [info] Alive Slaves:
Sat Mar  2 00:06:27 2019 - [info]   172.25.1.2(172.25.1.2:3306)  Version=5.7.24 (oldest major version between slaves) log-bin:disabled
Sat Mar  2 00:06:27 2019 - [info]     GTID ON
Sat Mar  2 00:06:27 2019 - [info]     Replicating from 172.25.1.1(172.25.1.1:3306)
Sat Mar  2 00:06:27 2019 - [info]     Primary candidate for the new Master (candidate_master is set)
Sat Mar  2 00:06:27 2019 - [info]   172.25.1.3(172.25.1.3:3306)  Version=5.7.24 (oldest major version between slaves) log-bin:disabled
Sat Mar  2 00:06:27 2019 - [info]     GTID ON
Sat Mar  2 00:06:27 2019 - [info]     Replicating from 172.25.1.1(172.25.1.1:3306)
Sat Mar  2 00:06:27 2019 - [info]     Not candidate for the new Master (no_master is set)
Sat Mar  2 00:06:27 2019 - [info] Current Alive Master: 172.25.1.1(172.25.1.1:3306)
Sat Mar  2 00:06:27 2019 - [info] Checking slave configurations..
Sat Mar  2 00:06:27 2019 - [info]  read_only=1 is not set on slave 172.25.1.2(172.25.1.2:3306).
Sat Mar  2 00:06:27 2019 - [warning]  log-bin is not set on slave 172.25.1.2(172.25.1.2:3306). This host cannot be a master.
Sat Mar  2 00:06:27 2019 - [info]  read_only=1 is not set on slave 172.25.1.3(172.25.1.3:3306).
Sat Mar  2 00:06:27 2019 - [warning]  log-bin is not set on slave 172.25.1.3(172.25.1.3:3306). This host cannot be a master.
Sat Mar  2 00:06:27 2019 - [info] Checking replication filtering settings..
Sat Mar  2 00:06:27 2019 - [info]  binlog_do_db= , binlog_ignore_db= 
Sat Mar  2 00:06:27 2019 - [info]  Replication filtering check ok.
Sat Mar  2 00:06:27 2019 - [error][/usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm, ln364] None of slaves can be master. Check failover configuration file or log-bin settings in my.cnf
Sat Mar  2 00:06:27 2019 - [error][/usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm, ln427] Error happened on checking configurations.  at /usr/bin/masterha_check_repl line 48.
Sat Mar  2 00:06:27 2019 - [error][/usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm, ln525] Error happened on monitoring servers.
Sat Mar  2 00:06:27 2019 - [info] Got exit code 1 (Not master dead).

MySQL Replication Health is NOT OK!

 根据报错:没有slave可以成为master,故推断出是my.cnf配置错误,修改server2和server3的配置文件,修改为下图

server2

主从切换mysql原理 mysql 主从切换工具_主从切换mysql原理_03

server3

主从切换mysql原理 mysql 主从切换工具_mha_04

然后重启server2和servre3的数据库,再次检查

主从切换mysql原理 mysql 主从切换工具_主从切换mysql原理_05

ok了

三、测试

在server3上查看mha的状态

masterha_check_status --conf=/etc/masterha/app1.cnf

主从切换mysql原理 mysql 主从切换工具_主从切换mysql原理_06

接下俩我们进行手动切换测试

1.手动切换主从

我们首先故意停止掉server1的mysqld服务,假装master坏掉,然后在server4(mha_manager节点)输入下列命令

masterha_master_switch --master_state=dead --conf=/etc/masterha/app1.cnf --dead_master_host=172.25.1.1 --dead_master_port=3306 --new_master_host=172.25.1.2  --new_master_port=3306

在这个过程中,会询问你两次,下图为检测到了master已死,是否继续

主从切换mysql原理 mysql 主从切换工具_vip_07

这个是询问你是否将master从172.25.1.1切换到172.25.1.2

输入yes后,发现master切换到了server2

主从切换mysql原理 mysql 主从切换工具_mysql_08

此时查看server3的slave状态

主从切换mysql原理 mysql 主从切换工具_mysql_09

此时如果我将servre1开启之后,只需要将server2设置为master即可,参照之前设置slave的办法

2.自动切换主从

将server1设置为server2的slave之后,我们进行自动切换的实验

server3:

nohup masterha_manager --conf=/etc/masterha/app1.cnf &> /dev/null &

这样mha的监控程序就进入了后台,可以通过命令查询

主从切换mysql原理 mysql 主从切换工具_主从切换_10

此时,我们故意停止server2(master),当在server4出现下图中的东西的时候,就表示切换成功了

主从切换mysql原理 mysql 主从切换工具_主从切换_11

此时查看server3的slave状态,就会发现master已经切换到了server1

主从切换mysql原理 mysql 主从切换工具_mysql_12

3.带vip的自动主从切换

这里需要两个脚本  ==> 点击下载 提取码: xpbe

在这里我们只需要将这两个脚本放在server4的/usr/local/bin/下,然后在解除/etc/masterha/app1.cnf文件的两行的注释

主从切换mysql原理 mysql 主从切换工具_mysql_13

在master上设置vip

ip addr add 172.25.1.100/24 dev eth0

然后使用上面的手动或者自动进行测试,就会发现master和vip一块进行了切换,这里不再展示,大家自己尝试