近日接到一个故障,主从异步方式,主 crash后,从不可用,检查发现从机Read_Master_Log_Pos与Exec_Master_Log_Pos不一致,似乎还有binlog在回放中,HA在等回放结束,一直保持这个状态。难道从机也出故障了?根本原因是什么?且看下文。

MySQL binlog简介

首先简单了解要下binlog日志,Binary Log是在MySQL3.23.14中引入的,记录MySQL数据修改记录的文件集合。

Binary Log有两个目的:

用于复制。master(主)上的binlog日志发送到slave(从)上,slave执行回放master上的修改动作,保持主从数据一致。

用于数据恢复。对binlog日志文件指定始末位置执行即恢复指定数据。

本文是针对复制流程中的一个改进,不涉及数据恢复。

基于binlog的复制简介

Master上对修改动作生成binlog,Slave机IO拉取对应的binlog到本地生成relay log,然后Slave机SQL线程回放执行。binlog的最小单位为event,master与slave之间以event为单位传输日志,一个或多个event组成一个事务,slave机上以事务为单位回放日志。事务是数据库的常见基本特性,不再介绍,这里主要介绍下binlog中的event。

事务event包含header 和data,Header包含有event的类型,时间,哪个server产生等信息。data有对应类型event的细节,如特定的数据变化。

每个binlog第一个event是描述性event,描述当前文件的格式版本,最后一个event是一个log-rotation event用来指定下一个binary log的文件名。中间的则为常规event,描述各种操作,从event类型上就能比较直观看出event内容,如:XID_EVENT、WRITE_ROWS_EVENT、UPDATE_ROWS_EVENT、DELETE_ROWS_EVENT等。

一个示例如下:

这是GTID模式下,建表和插入数据等events示例。第一个是固定的当前文件头信息,第二个Previous_gtids说明是GTID日志模式,接下来的Gtid event是GTID模式下每个事务的头信息,通过这个不重复且递增的GTID号来保证数据的连续性,一致性,然后是建表并插入数据相关event。

异步复制模式的不足

上面可以看到,binlog中非常清析的记录了所有动作,正常情况下,slave机只要按这顺序执行完成,就能保证主从数据一致。但事务当提交成功后才发日志给slave机,当master出现故障时,slave机收到的日志不一定是完整的,这时没办法完全保证主从数据完全一致,这是异步模式天生的不足,是否有好的解决办法本文不深入,本文要讨论的是当此类故障出现时如何保证外部业务可用的问题。

假如master机掉电了或crash了或操作系统崩溃了,无法恢复使用,此时怎么恢复?先看如下简图:

当master出现问题时,业务将不可用,slave机接收不到binlog,IO线程会处于连接中,HA控制中心确认状态后,会自动把应用流量切到slave机,恢复业务。但是有些情况下,HA控制中心是没办法自我恢复的。如:master在commit之后,开始给slave机传输binlog时,但又没传完,此时master 出现故障,HA需要切换流量到slave,但在切换流量之前,会先等slave机上已经读到的binlog回放完毕。问题就在这里,请看我上面第二节基于binlog的复制简介中加粗字体event为单位事务为单位,在slave机有Exec_Master_Log_Pos记录当前已经执行完成的以事务为单位的日志位置,有Read_Master_Log_Pos记录前已经拉取过来的以event为单位日志位置,当Read_Master_Log_Pos读位置与Exec_Master_Log_Pos执行位置相等就说明slave机上日志已经回放完毕,如果IO线程拉取一个事务的部分event,此时master出现故障不能恢复,slave机会一直等待,此时Read_Master_Log_Pos读位置与Exec_Master_Log_Pos执行位置不一致,HA中心会认为还有日志没回放完,一直等待,正是这个原因造成了本文开头的HA切换不成功故障

HA为什么要等Read_Master_Log_Pos与Exec_Master_Log_Pos一致?虽然异步模式不能完全保证数据不丢失,但要尽量减小丢失。在master并发很大的场景下,主从数据延迟可能会是几十分钟甚至更久,必须要把已经拉取日志回放完毕,减少数据丢失。当出现拉取到不完整事务时,对slave来说是正常状态,可能是网络或其它原因,尝试恢复拉取即可,如果和master通讯恢复正常,slave机是能正常拉取到完整事务的,因此不完整事务状态对slave机说是正常状态。如果master已经不可用,slave机又没拉取完全部事务,Read_Master_Log_Pos与Exec_Master_Log_Pos不一致,HA中心认为回放不完整,不能切换,一直等待。此时甚至DBA上去查看也不好确认slave机状态,如slave机正在回放一个超大事务,需要很长时间,期间master出现故障不可用,此时Read_Master_Log_Pos与Exec_Master_Log_Pos不一致,所有状态在回放过程中不发生改变,无法确定slave机真实状态。

那么当master不可用了,slave机又没拉取完整事务时怎么办?人工检查slave机状态,对比Read_Master_Log_Pos与Exec_Master_Log_Pos,等待一段时间再比较,如果多次比较Exec_Master_Log_Pos没有变化,并且与Read_Master_Log_Pos相差并不大,可以认为已经读取到的日志已经回放完毕,可以把流量切换过来。实际上这不是非常稳妥的方案,操作也需要人工持续观察来做出判断再处理,步骤繁琐,维护成本高,对于云服务厂商,十万甚至百万级别的实例,单点偶尔发小概率事件可能会变成易现大概率事件,需要有更好的处理手段。

Read_Master_Log_Pos更新时机探讨

出现Exec_Master_Log_Pos和Read_Master_Log_Pos不一致的根本原因就在于两个更新时机不一样,一个事务回放结束才更新,一个拉取到event即更新。对于slave机来说,Exec_Master_Log_Pos要等一个事务的全部event拉取过来并且被sql线程回放成功才能更新,但Read_Master_Log_Pos只要有binlog的event被IO线程拉取过来就会改变。而sql回放线程是根据event中标记事务结束或开始的状态对之前事务进行回放,Read_Master_Log_Pos 记录的是当前已经拉取过来的位置,并不影响回放线程。因此可以把Read_Master_Log_Pos更新时机调整到读到完整事务之后再更新,与Exec_Master_Log_Pos更新逻辑保持一致,这样Read_Master_Log_Pos标记的位置就是肯定可以回放的完整事务的位置,不会出现之前那样不完整事务位置造成无法判断真实状态的情况。两种更新方式对比见下图:

当以事务为单位更新Read_Master_Log_Pos 后,无论master什么时机点crash,slave机上Exec_Master_Log_Pos最终都能追上Read_Master_Log_Pos。对于已经被slave机拉取过来的最后一个不完整事务的event,处理逻辑也原来一致,不会继续执行。但HA控制中心已经可以根据各个状态自动做出正确处理的,把流量切入从机,判断逻辑也与原来一样,Read_Master_Log_Pos 与Exec_Master_Log_Pos保持相等即可切换,因为现在任何情况下都成达成这个条件。

修改Read_Master_Log_Pos更新位置注意点

原先逻辑,slave机IO线程并不需要过多解析event,基本上只要确定长度就可,具体内容在sql线程回放时再解析。现在则要在IO线程中确定每个event类型,判断是否是事务结束的event,需要对event做一些解析工作。要修改的点并不多,注意GTID和非GTID区别,考虑row模式和statement差异,对不同情况下事务开始和结束标记理清,在queue_event函数增加处理逻辑即可。

主从复制系列C的更多相关文章

  1. 主从复制系列A

    一.主从原理 Replication 线程   Mysql的 Replication 是一个异步的复制过程,从一个 Mysql instace(我们称之为 Master)复制到另一个 Mysql in ...

  2. 主从复制系列B

    从服务器靠中继日志来接收从主服务器上传回来的日志.并依靠状态文件来记录已经从主服务器接收了哪些日志,已经恢复了哪些日志. 中继日志与二进制日志的格式相同,并且可以用mysqlbinlog读取.SQL线 ...

  3. MySQL 系列(四)主从复制、备份恢复方案生产环境实战

    第一篇:MySQL 系列(一) 生产标准线上环境安装配置案例及棘手问题解决 第二篇:MySQL 系列(二) 你不知道的数据库操作 第三篇:MySQL 系列(三)你不知道的 视图.触发器.存储过程.函数 ...

  4. solr与.net系列课程(七)solr主从复制

    solr与.net系列课程(七)solr主从复制    既然solr是解决大量数据全文索引的方案,由于高并发的问题,我们就要考虑solr的负载均衡了,solr提供非常简单的主从复制的配置方法,那么下面 ...

  5. Redis系列(四):Redis的复制机制(主从复制)

    本篇博客是Redis系列的第4篇,主要讲解下Redis的主从复制机制. 本系列的前3篇可以点击以下链接查看: Redis系列(一):Redis简介及环境安装 Redis系列(二):Redis的5种数据 ...

  6. Mongodb数据库学习系列————(一)Mongodb数据库主从复制的搭建

    Mongodb数据库主从复制的搭建 Writeby:lipeng                                    date:2014-10-22 最近项目上用到了位置查询,在网上 ...

  7. 【FAQ系列】关于SQL_Errno:1677导致主从复制中断的思考和实践

    1.简单介绍该错误发生的背景: 1) 数据库版本:MySQL5.7.19 2) 对一个大表修改字段类型DDL(将主键id int变为bigint),为了不影响主库业务,先在从库上执行DDL操作,然后通 ...

  8. Redis系列八:redis主从复制和哨兵

    一.Redis主从复制 主从复制:主节点负责写数据,从节点负责读数据,主节点定期把数据同步到从节点保证数据的一致性 1. 主从复制的相关操作 a,配置主从复制方式一.新增redis6380.conf, ...

  9. MySQL系列详解六:MySQL主从复制/半同步演示-技术流ken

    前言 随着技术的发展,在实际的生产环境中,由单台MySQL数据库服务器不能满足实际的需求.此时数据库集群就很好的解决了这个问题了.采用MySQL分布式集群,能够搭建一个高并发.负载均衡的集群服务器.在 ...

随机推荐

  1. leetcood学习笔记-55-跳跃游戏

    题目描述: 第一次提交: class Solution: def canJump(self, nums: List[int]) -> bool: if len(nums)<=1: retu ...

  2. 2016.8.15上午纪中初中部NOIP普及组比赛

    2016.8.15上午纪中初中部NOIP普及组比赛 链接:https://jzoj.net/junior/#contest/home/1333 这次比赛不怎么好,因为这套题目我并不是很擅长. 可同学们 ...

  3. 用while实现登录操作(3次过后,输入yes,使counter置0,还可以玩)

    用while实现登录操作(输入yes,使counter置0,还可以玩)#_author:Administrator#date:2019/10/24user_name="star"p ...

  4. python相关软件安装流程图解——linux 安装python3——Python-3.7.1

    请先确保已经安装了虚拟机 python相关软件安装流程图解——虚拟机安装——CentOS-7-x86_64-DVD-1810——CentOS-01下载 https://www.cnblogs.com/ ...

  5. System.Collections.IDictionary.cs

    ylbtech-System.Collections.IDictionary.cs 1.程序集 mscorlib, Version=4.0.0.0, Culture=neutral, PublicKe ...

  6. iOS开发之SceneKit框架--SCNGeometry.h

    1.SCNGeometry简介 SCNGeometry负责呈现三维模型的类,它管理者物体的形状.纹理等.它可以由SCNGeometrySource和SCNGeometryElement来构造, 一个S ...

  7. 左神算法进阶班1_5BFPRT算法

    在无序数组中找到第k大的数1)分组,每N个数一组,(一般5个一组)2)每组分别进行排序,组间不排序3)将每个组的中位数拿出来,若偶数,则拿上 / 下中位数, 成立一个一个新数组.4)新数组递归调用BF ...

  8. mybatis中一对一关系映射

    一对一关系中普通的配置方式 一.多表连接查询语句: <select id="selectStudentWithAddress" parameterType="int ...

  9. [PKUSC2018]神仙的游戏

    题目 画一画就会发现一些奇诡的性质 首先如果\(len\)为一个\(\operatorname{border}\),那么必然对于\(\forall i\in [1,len]\),都会有\(s_i=s_ ...

  10. svg path命令

    参考:https://www.jianshu.com/p/c819ae16d29b         https://www.cnblogs.com/guxuelong/p/7743736.html M ...