php 判断心跳包报错,第29问:MySQL 的复制心跳说它不想跳了
问题
最近年末,你们的数据库常常跑批量大事务,会发现复制忽然断开,报错“心跳与本地信息不兼容”: 会是什么缘由?php
实验
咱们先来复现一下,再进行分析。html
宽油,作一对主从数据库:
mysql
咱们先造一个 500M 的空文件,下一步有用: sql
再制造一张大表,这里用到了以前的造表法,不一样的是使用了一个 longblob 字段,让少数的几行记录就能占用很大的 binlog 空间,方便咱们后面作实验。数据库
这里的 longblob 字段,用到了上一步咱们作的空文件, 网络
这样咱们得到了一个行数较少,但体积很大的表。tcp
如今起两个会话,一个事务造表 t2,一个事务造表 t3,并同时提交操做,如下举例其中一个事务: spa
这样就得到了一个超大的 binlog,一共 32G,前 16G 是一个事务,后 16G 是另外一个事务。 线程
小贴士
一个事务超过 binlog 的限制大小(最大 1G),就会在事务后直接切换到新的 binlog。设计
在同一个 binlog 中,咱们想让一个超大事务后再记录一个事务,因此让两个事务同时提交,放在同一个提交组中。
查看一下 master 上的 GTID,最后两个事务分别是 25 和 26:
下面登陆到 slave上,开始表演:
咱们先重置 GTID 和复制状态,而后骗 slave 说它已经接到了 1-25 事务,要从 26 号事务开始传输,也就是从 32G binlog 的中间位置开始传输。
而后开始复制的 IO 线程,过十几秒,就能够看到复制报错:
查看 Error log:
和咱们想要复现的报错同样。
下面咱们来看一下原理:
这个复现中有几个要素:
从报错得知,报错与心跳有关,复制线必须配置复制心跳。
一个 binlog 中包含两个事务,第一个事务超过 4G。(咱们在复现中为了方便,将第二个事务也作成了大事务,这一点不是必须的)。
从大事务后的位置,开始进行 binlog 复制传输。
咱们用 tcpdump 抓个包:
用 wireshark 解开抓包,找到有问题的包(这里怎么找,咱们分析后会有方法):
咱们来分析一下包结构,这里咱们将包的内容誊写下来,方便你们阅读:
将咱们的包对应上去:
将咱们的包对应上去:
接下来是个字符串,明显是一个 binlog 的名字,最后四个字节(下图中用黄色标注)是 checksum,
至此咱们完成了一个心跳包的解析,并无看出严重的问题,不妨往前再找一个心跳包看看规律:
我将重点在图中标注,就是 next\_position 的位置,在这个包中为 0xfa000557,而其下一个包中为 0x19400583,明显后面的 next\_position 比前面的 next_position 小,这个不符合常理。
而 MySQL 的报错 heartbeat is not compatible with local info,也是在报这个问题:心跳包中的 position 不该比当前的 position 小。
那是什么致使了这个问题,咱们注意到 next_position 的字段长只有 4 字节:
也就是说,该字段最大值为 2 的 31 次方,也就是 4G,当前 binlog 的位置大于 4G 时,该字段就会溢出。也就是说,以前咱们看到的位置 0x19400583,实际丢掉了最高的一位,应当是 0x119400583。
这也就致使了 binlog event 传输时,next_position 忽然会变小,心跳机制会检查到这个变化,产生报错。
那咱们怎么解决这个问题?
目前可能的方法有如下两种:
别用大事务,别用大事务,别用大事务。数据库系统原本就不是为大事务设计的,总会踩到很多坑。
停用心跳机制,这个问题并非心跳机制带来的问题,每一个 binlog event 都会带有这个包头。只是心跳机制让问题暴露了出来。若是关掉,提出问题的心跳机制,那么复制对于网络故障就会不敏感,致使更大的问题。这种方式不推荐使用。
复盘
由于文章比较长,咱们对逻辑进行一下复盘:
咱们经过抓包分析,知道 binlog 传输的网络包里,next_position 只有 4 个字节,最大数值为 4G。
咱们在 master 上作了一个超过 4G 的大事务,让 slave 从这个大事务后开始传输。此时 master 会发送一个心跳包。
心跳包中的 next\_position 是 log event 在 binlog 位置,因为这个位置大于 4G,会被截断,致使 next\_position 比实际的小。
slave 收到心跳包,进行检测时发现 next_position 比实际的小,进行报错。
以上只是一种容易复现问题的场景。实际使用中,master 在一段时间不发送数据包后,或者特殊触发条件,都会发送心跳包。
对于一主多从的环境,每条复制链路的心跳是单独发送的,也就会致使多个 slave 的表现会有所不一样,有的 slave 会触发报错,有的 slave 因为 master 没发送心跳包而不会触发报错。
最后送上几个小贴士
1)咱们如何快速找到有问题的包?
报错信息里已经标志了出错的 log position 是 423626115,转换成 16 进制为:0x19400583,找到由此数据的包便可。
2)一位一位读包太麻烦了,怎么办?
好办,先找到 server_id 的十六进制形式,以此为基准日后推定位数就能够。
好比咱们的 server_id 是 19327,很容易找到基准位置。
3)报错里有一段乱码是啥?
最后这四位,是 MySQL 程序有缺陷,将包中的 checksum 做为文件名输出了,对程序逻辑没有影响。
0x11 是 17,对应 ASCII 码 "device control 1 character",键盘表达形式是 "ctrl + Q",打印形式就是 "^Q"。
本文相关的 MySQL 的 bug 列表:
关于 MySQL 的技术内容,大家还有什么想知道的吗?赶忙留言告诉小编吧!
php 判断心跳包报错,第29问:MySQL 的复制心跳说它不想跳了相关推荐
- 【报错笔记】项目使用了JSONArray类,导了import net.sf.json.JSONArray;包报错
项目使用了JSONArray类,导了import net.sf.json.JSONArray;包报错 报错原因:net.sf.json添加的时候需要添加jdk的版本号 解决方案:在pom.xml中添加 ...
- yarn安装依赖包报错 error An unexpected error occurred: “https://registry.npm.taobao.orgnpm/element-ui: get
yarn安装依赖包报错,error An unexpected error occurred: "https://registry.npm.taobao.orgnpm/element-ui: ...
- 解决Pycharm文件夹中同级目录导包报错的问题
报错情况:导包报错,但程序仍然可以运行 https://blog.csdn.net/hanhanwanghaha宝藏女孩 欢迎您的关注! 欢迎关注微信公众号:宝藏女孩的成长日记 让这个可爱的宝藏女孩在 ...
- Mac解压Linux平台tar包报错:tar: Error reading Truncated input file
1.报错:tar: Error reading Truncated input fileMac使用tar命令解压Linux平台tar包报错,需要安装gnu-tar来解压. 2.解决 # brew in ...
- 银河麒麟(linux)wireshark 打开抓包报错 The capture session could not be initiated on interface ‘enp2s0‘(You...
版本:银河麒麟桌面操作系统V10(SP1) 内核:Linux 5.4.18-28.23-bj-generic CPU:Loongson-3A5000 终端输入 uname -m 查看 架构: loon ...
- win10添加计算机语言,Win10添加语言包报错“0x800F0950”怎么办?
Win10添加语言包报错"0x800F0950"怎么办?在使用Win10系统的过程中,有时候我们需要添加语言,来实现一些工作需求,然而有用户遇到添加语言包失败的情况,系统提示错误代 ...
- 安装R包报错 [tcl] grab failed: window not viewable.的解决方案
安装R包报错 [tcl] grab failed: window not viewable.的解决方案 ##方法一:用下代码自己选择镜像 chooseCRANmirror(graphics=F) ## ...
- R安装nCov2019包报错:Failed to install 'unknown package' from GitHub: schannel: failed to receive handsh
在Rstudio中,安装nCov2019包报错:Failed to install 'unknown package' from GitHub: schannel: failed to receive ...
- 引入spring-boot-starter-redis包报错 :unknown
springboot集成redis时,引入spring-boot-starter-redis包报错,maven找不到这个资源.如下图: 我的项目中,spring boot是 用的2.0.4版本. sp ...
最新文章
- Arcgis for JS扩展GraphicLayer实现区域对象的聚类统计与展示
- 系统提示一个程序正在被另一个程序调用,如何知道是被哪个程序调用
- asp.net mvc 中直接访问静态页面
- NOI.AC NOIP模拟赛 第四场 补记
- 中国汽车系统为Alfa Romeo首款紧凑型SUV电动车开发新型转向系统
- 网络安全——计算机网络拓扑图
- fleaphp 快速开发php框架
- 一个优质软件测试工程师简历,疯狂面试5家公司......
- 天地图key申请_国家地理信息公共服务平台 天地图
- ChatGPT插件与简要介绍(已收集70个)了解添加插件后的chatgpt能做什么
- NodeJS 创建静态资源服务器
- 《笑傲江湖》人名解读
- 块存储服务(Cinder)安装配置,这一篇就够了!
- poi doc转docx_文件批量操作之.doc转成.docx
- PPT制作--这不是技巧,而是常识 然而好多人并不知道 (hsyl007转载整理)
- 华师的入学计算机测试题,华师期末考试计算机练习题
- iPhone上Siri无法正常回应如何解决?
- 电脑开机黑屏,只有鼠标能动
- supervisor安装总结
- stc51单片机入门 c语言,STC51单片机入门 (C语言)
热门文章
- 前端学习(564):margin计算规则
- 前端学习(284):纯css实现翻书效果
- http:(3):http响应头信息
- csgo被会话踢出什么鬼_【解决方案】“CSGO游戏—断开连接,VAC无法验证会话”问题解决方案...
- 非类型模板参数(参考《C++ Templates 英文版第二版》)
- php代码里怎么写html代码_菜鸟青铜变白银!Python 项目代码写完了,然后怎么打包和发布?...
- python整数序列求和_Python从菜鸟到高手(14):序列的加法和乘法
- python tornado对接权限中心的sdk封装
- pgd 游戏教程 基地
- Hyperledger中数据存取的实现