1、故障现象
- 某客户反馈,在利用binlog日志的解析内容做基于时间点的恢复时,出现hang死(超过12小时那种),恢复过程无法继续,而且100%重现
- 基于时间点恢复的实现方式为:使用mysqlbinlog命令指定一个结束时间点,解析binlog并使用管道直接导入数据库中执行(例如:mysqlbinlog binlog_file | mysql -uroot -pxx)
- 对此,我们收集了最基本的一些环境信息(注:这是客户环境),如下
- 数据库版本:MySQL 5.7.26
- 操作系统:CentOS 7.2 x64
- 服务器配置:
* CPU:8 vcpus
* 磁盘:磁盘阵列
* 内存:16G - 数据库关键参数:buffer pool为物理内存的一半,row格式复制
- 数据库复制拓扑:一主一 从,恢复数据的过程是使用从库的数据全量快照 + 从库的binlog实现,恢复目标服务器是另外一台单独的数据库服务器,该服务器只用于临时恢复数据,不存在复制拓扑,未配置监控或心跳检测
- 通过简单的询问,确认系统负载不高,数据库也几乎无负载。综合这些信息,在未看到现场之前,我们进行了简单的推理,认为该hang死现象很可能是由于大事务导致的,所以,我们一上去现场就直接围绕数据库进行排查,几经周折,终于发现了问题的原因,而且也找到了解决问题的方法。但,导致hang死的原因远没有想象的那么简单,而且具有一定的迷惑性,我们对此进行一个简单的总结并分享给大家
- PS1:下文中的数据为复现数据,复现的服务器配置如下(数据库使用沃趣最佳实践配置模板)
- CPU:32 vcpus
- 内存:256G
- 磁盘:1.6T LSI FLASH卡
- 网络:万兆网络
- PS2:留意下文代码段中的中文注释
2、分析排查
- 首先,查看mysqlbinlog进程,可以看到它正在运行着
1 2 3 |
|
-
然后,查看了当前正在运行的线程状态信息,发现一个sleep长达157269S的线程,这是什么鬼。。大事务未提交吗?窃喜!
1 2 3 4 5 6 7 8 |
|
-
接着,我们查看了事务和锁信息
1 2 3 4 5 6 |
|
- 至此,排查视乎陷入了僵局。既然不存在大事务,也没有锁信息,用于恢复数据的客户端连接也处于Sleep状态,那就表示此时数据库未做任何事情(该数据库是一个用于数据恢复的临时库,并没有任何其他访问业务,也并没有监控、心跳等,只有2个连接,一个是我们登录上去排查问题的连接,另外一个就是使用mysqlbinlog命令恢复数据的客户端连接),那么,为什么会hang?百思不得其解!
-
再接着,我们查看了一下系统负载,内存、网络、磁盘都几乎无负载,CPU也没啥负载,但却有一个奇怪的现象,有一个CPU核心的利用率为100%,如下
1 2 3 4 5 6 7 8 9 10 11 12 |
|
-
最后,在恢复库中,我们查看了一下GTID信息,发现GTID号不连续,少了一个事务的GTID(3759)
1 2 3 4 5 6 7 |
|