• 进入"运维那点事"后,希望您第一件事就是阅读“关于”栏目,仔细阅读“关于Ctrl+c问题”,不希望误会!

MySQL基于MHA高可用测试篇(Binlog模式)

MySQL 彭东稳 8年前 (2017-02-20) 49487次浏览 已收录 0个评论

一、环境准备

下面来测试MHA提供的各种功能,包括自动切换、手动切换、在线切换三种常用模式。下面是MHA manager的启动配置。

注意这里没有设置master_ip_failover_script与master_ip_online_change_script脚本,因为我们这里还没有涉及到VIP,所以可以没有这两个脚本,但仅限于测试。

通过前面简单实验,我们知道mha可以正常切换主从,但是当MySQL正常切换之后,应用中是无法正常自动切换的,这时就需要VIP了。VIP配置可以采用两种方式,一种通过keepalived的方式管理虚拟ip的浮动;另外一种通过脚本方式启动虚拟ip的方式(即不需要keepalived或者heartbeat类似的软件)。

一旦有了VIP,所以也就需要给master_ip_failover_script与master_ip_online_change_script提供脚本了。为了防止脑裂发生,推荐生产环境采用脚本的方式来管理虚拟ip,而不是使用keepalived来完成。但是当我们有了VIP之后,在切换时还有一个问题,我们知道网络模型OSI中二层数据链路是靠MAC地址通信的,所以上层无论三层或二层交换机是缓存有VIP的ARP(MAC和IP对应关系)表,交换机靠这个表来进行数据包的转换转发。所以当我们VIP切换后,上层交换机并不会立马刷新自己的ARP缓存表,这就需要我们人工干预了。

其实就是在我们进行切换时,可以通过使用一个arping命令实现。arping是在局域网中使用ARP请求判断目标主机是否在线的工具。你可以使用IP地址或MAC地址作为它的测试目标(因为APRING程序工作于OSI模型中的第二层,ARP协议的数据包无法通过路由器和网关,所以它只能用来检测局域网中的主机)。其命令语法如下:

常用参数介绍:

-b:用于发送以太网广播帧(FFFFFFFFFFFF)。arping一开始使用广播地址,在收到响应后就使用unicast地址。

-q:quiet output不显示任何信息。

-f:表示在收到第一个响应报文后就退出。

-w timeout:设定一个超时时间,单位是秒。如果到了指定时间,arping还没到完全收到响应则退出。

-c count:表示发送指定数量的ARP请求数据包后就停止。如果指定了deadline选项,则arping会等待相同数量的arp响应包,直到超时为止。

-s source:设定arping发送的arp数据包中的SPA字段的值。如果为空,则按下面处理,如果是DAD模式(冲突地址探测),则设置为0.0.0.0,如果是Unsolicited ARP模式(Gratutious ARP)则设置为目标地址,否则从路由表得出。

-I interface:设置ping使用的网络接口。

整体脚本代码如下,根据环境不同可能需要稍微修改,比如ssh连接的端口号和用户名,能提取的都已经变量化了。

使用方式如下,自动故障切换和在线切换都是使用这个脚本即可,配置如下:

二、测试自动Failover(主要测试new master是补谁的日志)

必须先启动MHA Manager,否则无法自动切换,当然手动切换不需要开启MHA Manager监控。

检查主从复制状态

自动failover模拟测试的操作步骤如下。

1. 使用sysbench生成测试数据

自行安装 sysbench 工具。

在主库(10.99.73.9)上进行sysbench数据生成,在sbtest库下生成sbtest表,共100W记录。

如果是需要产生大量的binlog,使用sysbench模拟压测,持续时间为3分钟,产生大量的binlog。使用如下语句(这里我们不使用):

2. 停掉slave io线程(10.99.73.10)

一定要在master执行sysbench结束之前停掉slave io线程,这样我们才可以模拟查看当10.99.73.10成为new master之后是否会同步old master的binlog。

另外一台slave我们没有停止io线程,所以还在继续接收执行日志。

3. 停掉slave io线程(10.99.73.11)

你可以一直使用show slave status命令查看当前此slave的状态,只要比10.99.73.10同步的数据多就可以停掉io线程了,但是记住不要把master的数据完全同步完了。

4. 杀掉主库mysql进程

模拟主库发生故障,进行自动failover操作。

PS:可以看出master是100万数据,slave(10.99.73.10)只有90万数据,而slave(10.99.73.11)有97万数据,下面看整个MHA的切换过程。

5. 查看MHA切换日志

了解整个切换过程,在10.99.73.7上查看日志。

看到最后如果出现”Master failover to 10.99.73.10(10.99.73.10:3306) completed successfully.”,说明备选master现在已经上位了。并且可以看到两个slave中10.99.73.10成为了new master,而10.99.73.11成为了10.99.73.10的slave。这主要是因为我们刻意把10.99.73.11设置为了no_master,就是不参与选举。如果没有设置no_master的话,那么MHA在进行选择时会根据数据最接近于master的slave。

从上面的输出可以看出整个MHA的切换过程,共包括以下的步骤:

1. 配置文件检查阶段,这个阶段会检查整个集群配置文件配置,找出master和slave。

2. 宕机的master处理,这个阶段包括虚拟ip摘除操作,主机关机操作(可选)。

3. 找出含有最新数据的slave。

4. 复制dead master和最新slave相差的relay log,并保存到MHA Manger具体的目录下。

5. 找出并提升一个slave为新的master。

6. 应用从master保存的二进制日志事件(binlog events)到新的master。

7. 使其他的slave连接新的master进行复制。

6. 验证new master(10.99.73.10)

由此结果可以看出new master跟old master的数据一致,说明mha是根据old master来补齐new master的差异数据的。

7. 切换发送邮件

最后补充一下邮件发送脚本send_report ,如下:

切换后报警信息如下:

MySQL基于MHA高可用测试篇(Binlog模式)

三、手动Failover(MHA Manager必须没有运行)

首先搞一个干净的MySQL复制集群加mha监控(在mha监控端不需要开启mha manager)。手动failover,这种场景意味着在业务上没有启用MHA自动切换功能,当主服务器故障时,人工手动调用MHA来进行故障切换操作。注意:如果MHA manager检测到没有dead的server,将报错,并结束failover,如下报错信息:

进行手动切换命令如下,但是在切换之前我们需要模拟一下slave延迟,然后让切换脚本自动补全relay log。

在主库(10.99.73.9)上进行sysbench数据生成,在sbtest库下生成sbtest表,共100W记录。

主库写入一些数据后,就可以关闭10.99.73.10的io_thread,保持比主库数据量小。

然后就可以关闭10.99.73.9的io_thread,但是要保证10.99.73.9主机的数据比10.99.73.10数据多,但是比10.99.73.9的数据小。

然后等主库压测完事之后查看一下主库状态就关闭mysql进程。

然后就可以在mha主机上进行手动切换了,由于要指定特定的slave为候选master,而此slave还落后非常多,可以在每组服务器上都加上check_repl_delay=0表示忽略复制延迟,不然整个恢复过程会加长。如下配置:

手动切换:

会输出整个切换过程以及会询问你是否进行切换:

上述模拟了master宕机的情况下手动把10.99.73.10提升为主库的操作过程。

查看一下10.99.73.10主机状态。

可以看到10.99.73.10切换为主后,自动补全了old master所有的差异日志。

masterha_master_switch命令参数介绍

--master_state=dead

参数取值:dead or alive。如果设置为alive,就是在线master切换了,这样的场景,master必须是活着的。

--dead_master_host=(hostname)

Dead master的主机信息,包括--dead_master_ip--dead_master_port

--new_master_host=(hostname)

New master的主机信息,这个参数是可选项,如果你想特意指定某台机器作为new master,就设置这个参数。如果--new_master_host没有设置,那么选举master的规则参考automated master failover( candidate_master parameter )。

--interactive=(0|1)

交互式failover,设置为1(默认)。非交互式failover,设置为0。

--skip_change_master(0.56)

只会完成日志补偿,不会进行change master和start slave。如果你想double check slave是否成功的恢复完成,那么设置该参数对你特别有用。

--skip_disable_read_only

如果设置了这个参数,那么新master将还会是只读状态。如果你想手动开启新master的写权限,那么这个参数特别有用。

--last_failover_minute=(minutes)

同masterha_manager里面的参数一样 。

--ignore_last_failover

同masterha_manager里面的参数一样 。

--wait_on_failover_error=(seconds)

同masterha_manager里面的参数一样。这个参数,只对自动或者非交互式的failover有用,如果--interactive=0没有设置,那么这个参数将不起作用。

--remove_dead_master_conf

同masterha_manager里面的参数一样。

--wait_until_gtid_in_sync=(0|1)

这是基于GTID的参数,如果设置为1(默认): MHA会等待,直到所有slave追上新master的gtid。如果设置为0: 那么MHA不会等待slave追上新master。

--ignore_binlog_server_error

MHA忽略任何binlog server的错误。

四、在线进行切换

在许多情况下,需要将现有的主服务器迁移到另外一台服务器上。比如主服务器硬件故障,RAID控制卡需要重建,将主服务器移到性能更好的服务器上等等。维护主服务器引起性能下降, 导致停机时间至少无法写入数据。 另外, 阻塞或杀掉当前运行的会话会导致主主之间数据不一致的问题发生。 MHA 提供快速切换和优雅的阻塞写入,这个切换过程只需要0.5-2s的时间,这段时间内数据是无法写入的。在很多情况下,0.5-2的阻塞写入是可以接受的。因此切换主服务器不需要计划分配维护时间窗口。

MHA在线切换的大概过程:

1. 检查配置文件,主要检测复制设置和确定当前主服务器。

2. 选出新的主服务器。

3. 阻塞当前master的写入操作,主要包括执行 FLUSH TABLES,设置 read_only,kill 所有业务线程,关闭 VIP,最后执行 FLUSH TABLES WITH READ LOCK;一切都是为了保证新的写入无法进入,正在操作的事务回滚。

4. 等待所有从服务器复制完成,然后获取从服务器 POSITION 点(SHOW MASTER STATUS)。

5. 允许写入操作到新的主服务器,主要包括设置 read_only=OFF,RESET SLAVE ALL,设置 VIP。

6. 重新设置老的 master 为 slave,主要包括设置 relay_log_purge=0,change master,unlock tables,start slave 这几个部分。

注意,在线切换的时候应用架构需要考虑以下两个问题:

1. 自动识别master和slave的问题(master的机器可能会切换),如果采用了vip的方式,基本可以解决这个问题。

2. 负载均衡的问题,可以定义大概的读写比例,每台机器可承担的负载比例,当有机器离开集群时,需要考虑这个问题。

为了保证数据完全一致性,在最快的时间内完成切换,MHA的在线切换必须满足以下条件才会切换成功,否则会切换失败。

1. 所有slave的IO线程都在运行。

2. 所有slave的SQL线程都在运行。

3. 所有的show slave status的输出中Seconds_Behind_Master参数小于或者等于running_updates_limit秒,如果在切换过程中不指定running_updates_limit,那么默认情况下running_updates_limit为1秒。

4. 在master端,通过show processlist输出,没有一个更新花费的时间大于running_updates_limit秒。

在线切换步骤如下:

首先,停掉MHA监控:

然后可以在主库(10.99.73.9)上进行sysbench数据生成,在sbtest库下生成sbtest表,共100W记录。

有条件的可以在压测时连接数据指定VIP地址,把socket去掉,添加--mysql-host=10.99.73.100,这就样可以模拟应用在线切换(一边压测一边切换)。

等主库一压测完后。就可以进行在线切换操作(模拟在线切换主库操作,原主库10.99.73.9变为slave,10.99.73.10提升为新的主库)。

其中参数的意思:

--orig_master_is_new_slave

切换时加上此参数是将原master变为slave节点,如果不加此参数,原来的master将不启动。

--running_updates_limit

故障切换时,候选master如果有延迟的话,mha切换不能成功,加上此参数表示延迟在此时间范围内都可切换(单位为s),但是切换的时间长短是由recover时relay日志的大小决定。

--new_master_host & --new_master_port

选择把哪个Slave提升为New Master,如果只有一个Slave节点,此参数可不加,会自动把Slave节点提升New Master节点。

最后查看日志,了解切换过程,最后输出信息如下:

整个切换过程基本与我们上面说的步骤一致,这里面用到了一个master_pos_wait函数,语法:select master_pos_wait(file, pos[, timeout])。一般在主库执行,作为主从切换的判断依据,判断一下返回值>=0,则认为主从同步完成。这里的file和pos对应主库show master status得到的值,代表执行位置。函数逻辑是等待当前从库达到这个位置后返回, 返回期间执行的事务个数。参数timeout可选,若缺省则无限等待,timeout<=0时与缺省的逻辑相同。若为正数,则等待这么多秒,超时函数返回-1。其他返回值,若当前slave为启动或在等待期间被终止,返回NULL;若指定的值已经在之前达到,返回0。

查看10.99.73.10主机切换为master了。

MHA online切换主从状态必须正常,切换后old maser会变成slave,且为read_only模式。

五、二次检测测试

MHA官方提供了一个二次检测脚本,防止误切换。也就是说当MHA主机探测不到Master时,它会调用secondary_check_script脚本进行二次检测Master,如果都探测不到,才进行故障切换。

我的测试方法如下,利用iptables。先拒绝掉MHA访问Master的3306端口,然后看会不会发生切换。

验证结果并没有发送切换,因为此时MHA会调secondary_check_script脚本进行二次检测Master,发现Master处于存活状态。

接着屏蔽二次检测指定的主机,如下:

验证结果,此时真正触发了MHA故障切换,因为满足条件,MHA确定Master已经故障。

六、修复宕机的Master

通常情况下自动切换以后,原master可能已经废弃掉,待原master主机修复后,如果数据完整的情况下,可能想把原来master重新作为新主库的slave,这时我们可以借助当时自动切换时刻的MHA日志来完成对原master的修复。下面是提取相关日志的命令:

获取上述信息以后,就可以直接在修复后的master上执行change master to相关操作,重新作为从库了。


如果您觉得本站对你有帮助,那么可以支付宝扫码捐助以帮助本站更好地发展,在此谢过。
喜欢 (4)
[资助本站您就扫码 谢谢]
分享 (0)

您必须 登录 才能发表评论!