最近一位同学遇到的案例:凌晨数据库意外宕机,要求在一主两从的基础上,搭建MHA做故障切换。在部署测试中遇到一些问题找到我,交流的过程挖出一些之前忽略的坑,感谢这位同学无私分享!
• GTID环境,KILL主库,新主库和从库丢失数据(之前已知)
• 在数据库进程挂掉、数据库服务器关机或重启、开启防火墙、关闭网络服务等状况下,测试MHA是否正常切换(之前没考虑脑裂问题)
• 线上部分环境GTID,Auto_Position=0,故障切换会变成GTID,Auto_Position=1(之前没考虑)
• 梳理故障切换流程(之前梳理)

一、GTID环境,KILL主库,新主库和从库丢失数据

需在配置文件将Master/Binlog Server配置到[binlogN],才能补全Dead Master上的差异数据,否则只应用到Latest Slave
发散:[binlogN]指定到Binlog Server,kill -9 master_mysqld,MHA是从Binlog Server上获取还是从Dead Master上获取差异binlog?
指定到Binlog Server就从Binlog Server上获取,指定到Dead Master就到Dead Master获取;如果没有指定,就不会补全差异数据

二、MHA切换测试

在数据库进程挂掉,数据库服务器关机或重启、开启防火墙、关闭网络服务等状况下,测试MHA是否正常切换
MySQL5.7.21,基于Row+Gtid搭建的一主两从复制结构:Master132->{Slave133、Slave134};VIP在132上,mha-manager 0.56在134上

测试场景 XX.132 XX.133 XX.134 说明
132:kill -9 mysqld 不可用 主 从 MHA正常切换,数据不丢失
132:关闭或重启132服务器 不可用 主 从 MHA正常切换,数据可能丢失
134:iptables -I INPUT -s XX.132 -j DROP 可用 主 从 MHA正常切换,原主库正常访问,133成为新主库,132和133同时存在VIP
132:service network stop/ifconfig eth0 down 不可用 主 从 MHA正常切换,数据可能丢失

注:上述表格是配置[binlogN]指定到Binlog Server,没有指定secondary_check_script的测试结果
关闭数据库服务器,数据可能丢失的原因:Binlog Server是异步,高并发下binlog延迟可以理解
开启防火墙,模拟主库与mha-manager不通讯,出现脑裂。配置文件添加"secondary_check_script=masterha_secondary_check -s remote_host1 -s remote_host2",remote_host1、remote_host2尽量与mha-manager、MySQL Server处于不同网段

三、GTID,Auto_Position=0,故障切换变成GTID,Auto_Position=1

3.1、Auto_Position

线上部分环境GTID,Auto_Position=0,故障切换会变成GTID,Auto_Position=1
• 有何风险
如果S1从库的GTIDs存在空洞,S2从库的GTIDs正常,随着时间推移,S2将S1上GTIDs空洞对应的binlog删除。此时发生故障切换,且选择S2做为新Master,在S1 change master to S2 master_auto_position=1会报错

Got fatal error  from master when reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.'

从库存在GTIDs空洞可能会导致切换异常:VIP正常切换,新主可用,新从到新主之间的复制报错,只有修复主从报错,才会做后续操作(new master cleanup、Failover Report、send mail)
• 为何不直接修改为GTID,Auto_Position=1
Slave GTIDs<Master GTIDs,如果Diff GTIDs对应的binlog在Master已被purge,修改为Auto_Position=1会继续报错
Slave GTIDs>Master GTIDs,5.7下主从直接报错
• 如何解决
修改源码~~~

shell> vim /usr/share/perl5/vendor_perl/MHA/ServerManager.pm
return if ( $_->{use_gtid_auto_pos} );
-->修改为
#return if ( $_->{use_gtid_auto_pos} ); shell> vim /usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm
if ( !$_server_manager->is_gtid_auto_pos_enabled() ) {
$log->info("GTID (with auto-pos) is not supported");
-->修改为
if ( $_server_manager->is_gtid_auto_pos_enabled() != ) {
$log->info("GTID (with auto-pos) is not supported");

为啥这样修改表示看不懂,感谢顺子(另一位同学)分享~
注意:传统复制(gtid_mode=off),MHA不会利用Binlog Server补全差异数据(又是一个坑●-●)

Binlog Server
Starting from MHA version 0.56, MHA supports new section [binlogN]. In binlog section, you can define mysqlbinlog streaming servers. When MHA does GTID based failover, MHA checks binlog servers, and if binlog servers are ahead of other slaves, MHA applies differential binlog events to the new master before recovery. When MHA does non-GTID based (traditional) failover, MHA ignores binlog servers.

3.2、什么情况会出现GTID空洞

1、从库暂停Slave Thread->主库写数据->主库flush log、purge log->从库启动Slave Thread->报错,缺失binary log
手工执行change master_auto_position=0;change binlog file & pos;
2、搭建复制时change master_auto_position=0;->复制过程暂停Slave Thread->change new_file & new_pos->从库启动Slave Thread
master_auto_position=1,Slave连接Master时,会把Executed_Gtid_Set中的GTIDs发给Master,Master会跳过Executed_Gtid_Set,把没有执行过的GTIDs发送给Slave
情况1:再次change master_auto_position=1;它依旧会去查找那些被purge的binlog,然后抛出错误
情况2:再次change master_auto_position=1;只要主上对应binlog没被purge,它能自动将空洞GTID补全
前提:Master没有对GTIDs空洞相应的记录进行DML操作,不然复制早就报错了,可能就错过这个坑~不过仔细想想,从库本来就有空洞,复制也没报错,侧面反映Master没有对GTIDs空洞相应的记录进行DML操作
扩展阅读:[MySQL FAQ]系列 — 5.6版本GTID复制异常处理一例

3.3、relay-log是如何获取及应用

Slave GTIDs>Master GTIDs,relay-log是如何获取及应用

• GTID,auto_position=
Master
Executed_Gtid_Set:90b30799--11e7--000c29c1025c:-
Slave
set global Gtid_Purged='90b30799-9215-11e7-8645-000c29c1025c:1-6:8-24';
-->Master写入一条数据
Master
Executed_Gtid_Set:90b30799--11e7--000c29c1025c:-
Slave
Retrieved_Gtid_Set: 90b30799--11e7--000c29c1025c:
Executed_Gtid_Set: 90b30799--11e7--000c29c1025c:-:-

新写入的binlog会写到从库的relay-log,但是不会应用(可以通过查看数据、解析日志确认)!

• GTID,auto_position=
change master to master_auto_position=;
启动复制报错
Last_IO_Error: Got fatal error from master when reading data from binary log: Slave has more GTIDs than the master has, using the master`s SERVER_UUID. This may indicate that the end of the binary log was truncated or that the last binary log file was lost, e.g., after a power or disk failure when sync_binlog != . The master may or may not have rolled back transactions that were already replica

relay-log获取
Auto_Position=0,如果开启relay-log自动修复机制,发生crash时根据relay_log_info中记录的已执行的binlog位置从master上重新获取写入relay-log
Auto_Position=1,Slave连接Master时,会把Executed_Gtid_Set中的GTIDs发给Master,Master会跳过Executed_Gtid_Set,把没有执行过的GTIDs发送给Slave。如果Slave上的GTIDs大于Master上的GTIDs,5.7下直接报错,5.6下不会报错(有环境的自行验证,顺便看看relay-log会不会有记录写入)
relay-log应用
如果relay-log中的GTIDs包含在Executed_Gtid_Set里,则不会apply-log

四、故障切换流程

MHA在传统复制和GTID复制下,主库发生故障,如何选举New Master,如何修复差异数据
详细流程请参考:MHA-手动Failover流程(传统复制&GTID复制)

MHA-Failover(GTID,Auto_Position=0)的更多相关文章

  1. MHA failover GTID 专题

    https://yq.aliyun.com/articles/238882?spm=5176.8067842.tagmain.18.73PjU3 摘要: MHA failover GTID 专题 这里 ...

  2. MySQL MHA FailOver后,原Master节点自动以Slave角色加入解群的研究与实现

    MHA是一套MySQL高可用管理软件,除了检测Master宕机后,提升候选Slave为New Master之外(漂虚拟IP),还会自动让其他Slave与New Master 建立复制关系.MHA Ma ...

  3. MHA ssh检查,repl复制检查和在线切换日志分析

    一.SSh 检查日志分析 执行过程及对应的日志: 1.读取MHA manger 节点上的配置文件 2.根据配置文件,得到各个主机的信息,逐一进行SSH检查 3.每个主机都通过SSH连接除了自己以外的其 ...

  4. MS SQL 错误 :17883,严重度: 1,状态: 0

    公司一台老旧的SQL SERVER 2000 数据库,一周内会出现若干次(一次或多次)CPU 持续100%,导致应用程序没有反应的情况,如下图所示: 错误信息如下所示: 日期 2013/7/12 2: ...

  5. 在win7-64bit环境下,boa-constructor 0.6.1 的palette面板中没有控件图标的解决方法

    在win7-64bit环境下,boa-constructor 0.6.1 的palette面板中没有控件图标,空白一片.将面板窗口拉大,发现那些图标在很下面的位置,X轴的排列与正常状态一致. 软件环境 ...

  6. 用仿ActionScript的语法来编写html5——终篇,LegendForHtml5Programming1.0开源库件

    一,LegendForHtml5Programming1.0库件是什么?它是一个javascript库,它模仿了ActionScript的语法,用于html5的开发,目前实现的功能相对较少,还不能称之 ...

  7. 编写一函数用来实现左右循环移位。函数原型为move(value,n);n>0时右移n位,n<0时左移|n|位。

    #include<stdio.h> #include<stdlib.h> int main(){ setbuf(stdout,NULL); int move(int,int); ...

  8. 动态IP无法获取默认网关,显示0.0.0.0的解决办法

    IP地址使用自动获取IP方式,可以获取到IP地址和子网掩码,默认网关无法获取,显示0.0.0.0,通过修复Winsock和LSP可以解决该问题,具体步骤如下:一.修复winsock1.单击开始> ...

  9. SATA1.0,2.0,3.0区别

    外观没区别,接口都一样,线也一样,就是传输速率不一样,控制芯片不一样SATA1.0理论传输速度为1.5Gbit/s SATA2.0理论传输速度为3Gbit/sSATA2.0理论传输速度为6Gbit/s ...

随机推荐

  1. Bootstrap手风琴效果

    前面的话 Bootstrap 框架中 Collapse插件(折叠)其实就是我们常见的手风琴效果.当单击一个触发元素时,在另外一个可折叠区域进行显示或隐藏,再次单击时可以反转显示状态.经典的场景是多个折 ...

  2. CSS等高布局的7种方式

    前面的话 等高布局是指子元素在父元素中高度相等的布局方式.等高布局的实现包括伪等高和真等高,伪等高只是看上去等高而已,真等高是实实在在的等高.本文将介绍边框模拟.负margin这两种伪等高以及tabl ...

  3. filebeat 配置文件参数

      filebeat 配置 所有的 beats 组件在 output 方面的配置都是一致的,之前章节已经介绍过.这里只介绍 filebeat 在 input 段的配置,如下: filebeat: sp ...

  4. AOP 获取 RequestContextHolder

    转载: http://blog.csdn.net/lexang1/article/details/52619215 在使用spring时,经常需要在普通类中获取session,request等对像. ...

  5. PHP 判断浏览器语言

    详情请参看代码 作用:判断当前的浏览器语言.接收传入参数.拼接字符串 <?php $lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'],0,2); if ...

  6. 监控(3)进程通用shell

    #! /bin/bash proc_name="beam.smp" #进程名 proc_num() #查询进程数{ num=`ps -ef | grep $proc_name | ...

  7. Java内存模型基础

    Java内存模型的基础 并发编程模型的两个关键问题 在并发编程种,需要处理两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实体).通信是指线程之间以何种机制来交换信息.在 ...

  8. spring-data-jpa与mybatis的对比

    Spring Data JPA 与 MyBatis对比 Spring Data JPA是Spring Data的子模块.使用Spring Data,使得基于“repositories”概念的JPA实现 ...

  9. kubernetes Dashboard 使用RBAC 权限认证控制

    kubernetes RBAC实战 环境准备 先用kubeadm安装好kubernetes集群,[包地址在此](https://market.aliyun.com/products/56014009/ ...

  10. ElasticSearch 之 dis_max tie_break的应用

    1. 插入数据 PUT /my_index/my_type/ { "title": "Quick brown rabbits", "body" ...