深入分析MySQL假死故障

序言

那是大半年前的一次线上DB故障。凌晨刚躺下就被call起来,经过紧张刺激,大脑高速运转的40分钟后,得出几个结论:

  1. 靠谱的基建团队很重要!
  2. 压力之下排查问题,大脑容易卡顿!
  3. 人在事上练!

问题表象

2023-12-xx 01:10时用户反馈APP系统崩了,列表查不出来。同事发日志截图看很清晰的获取数据库连接报错。当时想的是最近有没有发版,导致的?咨询了同事查看了线上工作负载的更新时间是7天前,代表不是最近发版导致的问题。

运行了7天都好好的,突然发现连接池打满了,获取链接超时,自然所有系统的查询都出不来了。但什么原因?一时没有头绪,只能赶快尝试恢复服务(线上还是以立即止损为第一要求),边让同事重启服务试试。发现重启后一瞬间也出现连接池打满的错误。

怀疑方向和排查

我们的数据库分为了几个逻辑库,工单、用户、商务等,在页面上只有工单库相关业务出现了阻塞。这几个逻辑库都在同个数据库实例上。究竟是什么原因导致连接池打满?当时想到的是:1.工单服务和DB的网络不通  2.DB负载很高,无法响应新连接。

查看了DB当时的负载,CPU和IO都是正常范围不算高。那很可能就是网络不通?查看工单服务所在241主机,发现网络IO是有异常,进出流量都突然下跌了。佐证了网络连通性很有问题!仿佛看到了点希望,然后让运维同事将工单服务放到236机器,241的下掉。发现236机器也出现拿不到链接问题。

很快拉了云服务供应商的运维群,运维登录241用telnet命令测试235主库,两台机网络是连通的。此时心有点凉了,重启服务不行,网络没问题,DB负载不高,近期没发版。没头绪了...

柳暗花明

DBA甩了张慢SQL截图在群里,发现有3条SQL执行了9个多小时... 然后还有个备份任务显示waitting for table flush

32515秒,这3条SQL就是某个同事下午执行的查询报表的语句。sending data代表SQL正在执行,边读数据边放到MySQL的send buf中,此时不一定是在发送数据给客户端,也有可能是在等锁。

把这3条慢SQL都干掉,然后把备份进程干掉。DB就自动恢复正常。网上查了些资料也的确是这个慢SQL和备份进程因获取MDL读写锁问题导致故障。第二天DBA也在UAT库模拟复现了这个问题。

原理学习和验证

回顾整个过程,刚开始猜测的两个方向的确是有可能的。但是看了DB负载比较低之后就放弃了排查DB本身问题,几条慢SQL有时可能并不会引发DB的负载大规模升高。但问题在于如果慢SQL在短时间内积压,就会造成雪崩效应。

这里先普及一个知识,MySQL的MDL锁,也称元数据锁。元数据锁是server层的锁,表级锁,每执行一条DML、DDL语句时都会申请MDL锁,DML操作需要MDL读锁,DDL操作需要MDL写锁(MDL加锁过程是系统自动控制,无法直接干预,读读共享,读写互斥,写写互斥),申请MDL锁的操作会形成一个队列,队列中写锁获取优先级高于读锁。一旦出现写锁等待,不但当前操作会被阻塞,同时还会阻塞后续该表的所有操作。事务一旦申请到MDL锁后,直到事务执行完才会将锁释放。

这次慢SQL碰上备份,慢SQL先获取了表的MDL读锁,备份程序innodbbackupex也需要获取表的MDL写锁,因为慢SQL迟迟没有结束所以备份程序只能进入队列排队获取MDL写锁,因为队列中存在了MDL写锁请求,后续的DML语句也因此被阻塞,因为获取MDL写锁请求高于MDL读锁请求。

总结:服务DB连接池打满的可能:

  1. 网络不通
  2. 突发流量导致负载高
  3. 慢SQL
  4. MDL表锁

参考文章:

https://blog.51cto.com/u_16099316/7137136icon-default.png?t=O83Ahttps://blog.51cto.com/u_16099316/7137136

Waiting for table flush故障处理-优快云博客文章浏览阅读4.6k次。一 原理总结官方手册中关于Flush tables的介绍:Closes all open tables, forces all tables in use to be closed, and flushes the query cache. FLUSH TABLES also removes all query results from the query cache, like the ..._waiting for table flushicon-default.png?t=O83Ahttps://blog.youkuaiyun.com/yabingshi_tech/article/details/103385299

https://blog.itpub.net/29654823/viewspace-2944599/icon-default.png?t=O83Ahttps://blog.itpub.net/29654823/viewspace-2944599/

mysql阻塞-Waiting for table flush - 墨天轮业务反馈mysql无法访问,随即show processlist查看,发现存在大量Waiting for table flush的select sql线程。找到阻塞源并kill后,业务恢复正常。阻塞源是一个running状态的select sql,已经运行了20个小时,还未执行完成。理论上select sql之间是不会阻塞的,可本例又是如何产生的呢?icon-default.png?t=O83Ahttps://www.modb.pro/db/613516

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值