​MySQL 一个让你怀疑人生的hang死现象

在利用MySQL binlog进行基于时间点恢复时,出现长时间挂死现象。通过排查发现,问题源于MySQL客户端在处理大事务binlog时内存分配效率低下,导致hang死。分析涉及查看线程状态、内存和CPU使用情况,最终通过修改客户端源码解决,同时对比了MySQL 8.0.x和MariaDB的处理方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

[root@localhost ~]# ps aux |grep mysqlbinlog

root 27822 1.3 0.0 24568 3204 pts/2 R+ 15:11 0:04 mysqlbinlog --stop-datetime='2019-07-14 16:30:00' mysql-bin.000014 mysql-bin.000015 mysql-bin.000016 mysql-bin.000017 mysql-bin.000018 mysql-bin.000019

......

  • 然后,查看了当前正在运行的线程状态信息,发现一个sleep长达157269S的线程,这是什么鬼。。大事务未提交吗?窃喜!

1

2

3

4

5

6

7

8

admin@localhost : test 02:18:27> show processlist;

+----+-------+-----------+------+---------+--------+----------+------------------+

| Id | User | Host | db | Command | Time | State | Info |

+----+-------+-----------+------+---------+--------+----------+------------------+

| 14 | admin | localhost | test | Query | 0 | starting | show processlist |

| 15 | admin | localhost | test | Sleep | 157269 | | NULL |

+----+-------+-----------+------+---------+--------+----------+------------------+

rows in set (0.00 sec)

  • 接着,我们查看了事务和锁信息

1

2

3

4

5

6

# 先查看事务信息

admin@localhost : test 03:02:36> select from information_schema.innodb_trx\G

Empty set (0.00 sec) # 纳尼!!,居然不存在事务正在运行

# 然后查看锁信息

admin@localhost : test 03:30:25> select from information_schema.innodb_locks;

Empty set, 1 warning (0.00 sec) # WTF!!居然也没有锁信息

  • 至此,排查视乎陷入了僵局。既然不存在大事务,也没有锁信息,用于恢复数据的客户端连接也处于Sleep状态,那就表示此时数据库未做任何事情(该数据库是一个用于数据恢复的临时库,并没有任何其他访问业务,也并没有监控、心跳等,只有2个连接,一个是我们登录上去排查问题的连接,另外一个就是使用mysqlbinlog命令恢复数据的客户端连接),那么,为什么会hang?百思不得其解!
  • 再接着,我们查看了一下系统负载,内存、网络、磁盘都几乎无负载,CPU也没啥负载,但却有一个奇怪的现象,有一个CPU核心的利用率为100%,如下

1

2

3

4

5

6

7

8

9

10

11

12

top - 15:40:50 up 117 days, 8:09, 5 users, load average: 1.97, 1.36, 1.15

Tasks: 496 total, 2 running, 494 sleeping, 0 stopped, 0 zombie

%Cpu0 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st

%Cpu1 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st

# 利用率为100%的CPU核心在这里

%Cpu2 : 34.4 us, 65.6 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st

%Cpu3 : 0.3 us, 0.3 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st

%Cpu4 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st

%Cpu5 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st

%Cpu6 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st

%Cpu7 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st

......

  • 最后,在恢复库中,我们查看了一下GTID信息,发现GTID号不连续,少了一个事务的GTID(3759)

1

2

3

4

5

6

7

admin@localhost : (none) 03:52:08> show master status;

+------------------+----------+--------------+------------------+---------------------------------------------+

| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+------------------+-------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值