MySQL CPU飙到680%:一次「僵尸查询」引发的雪崩

一、事故现场

下午3点,运维监控大屏突然变红。

严重告警\] [MySQL CPU使用率](https://link.juejin.cn?target=https%3A%2F%2Fzhida.zhihu.com%2Fsearch%3Fcontent_id%3D273195248%26content_type%3DArticle%26match_order%3D1%26q%3DMySQL%2BCPU%25E4%25BD%25BF%25E7%2594%25A8%25E7%258E%2587%26zhida_source%3Dentity "https://zhida.zhihu.com/search?content_id=273195248&content_type=Article&match_order=1&q=MySQL+CPU%E4%BD%BF%E7%94%A8%E7%8E%87&zhida_source=entity"):60% \[严重告警\] MySQL CPU使用率:280% \[紧急告警\] MySQL CPU使用率:680% 从60%到680%,只用了5-10分钟。业务系统开始出现明显卡顿。 • 用户反馈:页面加载变慢,点击无响应 • 运维反馈:数据库连接堆积,[慢SQL](https://link.juejin.cn?target=https%3A%2F%2Fzhida.zhihu.com%2Fsearch%3Fcontent_id%3D273195248%26content_type%3DArticle%26match_order%3D1%26q%3D%25E6%2585%25A2SQL%26zhida_source%3Dentity "https://zhida.zhihu.com/search?content_id=273195248&content_type=Article&match_order=1&q=%E6%85%A2SQL&zhida_source=entity")告警不断 • 应用日志:大量超时错误,[线程池](https://link.juejin.cn?target=https%3A%2F%2Fzhida.zhihu.com%2Fsearch%3Fcontent_id%3D273195248%26content_type%3DArticle%26match_order%3D1%26q%3D%25E7%25BA%25BF%25E7%25A8%258B%25E6%25B1%25A0%26zhida_source%3Dentity "https://zhida.zhihu.com/search?content_id=273195248&content_type=Article&match_order=1&q=%E7%BA%BF%E7%A8%8B%E6%B1%A0&zhida_source=entity")打满 ![](https://oss.xyyzone.com/jishuzhan/article/2044607415266639873/0c38b59b58f23c226c5a468fc643c688.webp) **图1:MySQL CPU飙升趋势(60% → 680%,约10分钟)** ****二、排查思路:先止血,再定位根因**** 这次CPU飙升和普通的慢查询不一样------增长速度太快,而且越往后越卡。直觉告诉我,这不是单一慢查询的问题。 ****排查原则:先止血保命,再全面排查,最后聚焦根因。**** ![](https://oss.xyyzone.com/jishuzhan/article/2044607415266639873/a4a5e2da72adc462eb8099ebb1292f00.webp) **图2:MySQL CPU飙升排查流程图** ****2.1 第一步:止血------确认影响范围**** ****① 确认业务影响**** 先判断是全部业务受影响还是部分接口: ## 查看当前连接数 mysql -e "SHOW STATUS LIKE 'Threads_connected';" +-----------------+-------+ \| Variable_name \| Value \| +-----------------+-------+ \| Threads_connected \| 487 \| \<-- 正常值应该在50-100左右 +-----------------+-------+ ****② 查看是否有大量慢查询**** ## 查看慢查询数量 mysql -e "SHOW GLOBAL STATUS LIKE 'Slow_queries';" +---------------+-------+ \| Variable_name \| Value \| +---------------+-------+ \| Slow_queries \| 1247 \| \<-- 异常偏高 +---------------+-------+ ![](https://oss.xyyzone.com/jishuzhan/article/2044607415266639873/4f204f236cbe1f746d8222592396b9df.webp) **图3:慢SQL堆积趋势(系统越来越卡)** ****2.2 第二步:系统层排查**** ****系统层资源充足,CPU飙升是MySQL自身造成的。**** ****2.3 第三步:MySQL层深度排查**** ****① 查看当前所有连接**** mysql -e "[SHOW PROCESSLIST](https://link.juejin.cn?target=https%3A%2F%2Fzhida.zhihu.com%2Fsearch%3Fcontent_id%3D273195248%26content_type%3DArticle%26match_order%3D1%26q%3DSHOW%2BPROCESSLIST%26zhida_source%3Dentity "https://zhida.zhihu.com/search?content_id=273195248&content_type=Article&match_order=1&q=SHOW+PROCESSLIST&zhida_source=entity")\\G" ![](https://oss.xyyzone.com/jishuzhan/article/2044607415266639873/7293308225be11d58a35abc1fe69d53d.webp) **图4:SHOW PROCESSLIST输出(大量长时间运行查询)** 发现异常: ****多个查询运行时间超过30分钟,而且State显示各种锁等待。**** ****② 用AI帮忙分析PROCESSLIST**** PROCESSLIST有几百行,人工看太费劲。让AI帮忙分析: 【当前症状】 * MySQL CPU从60%飙升到680%,5-10分钟内 * Threads_connected: 487(正常50-100) * Slow_queries: 1247 * 多个查询Time超过1800秒,状态为Locked/metadata lock 【请分析】 1. 这些长时间运行的查询,最可能的原因是什么? 2. "Locked" 和 "Waiting for table metadata lock" 是什么关系? 3. CPU飙升和这些锁等待有什么关联? ****③ 查看[InnoDB状态](https://link.juejin.cn?target=https%3A%2F%2Fzhida.zhihu.com%2Fsearch%3Fcontent_id%3D273195248%26content_type%3DArticle%26match_order%3D1%26q%3DInnoDB%25E7%258A%25B6%25E6%2580%2581%26zhida_source%3Dentity "https://zhida.zhihu.com/search?content_id=273195248&content_type=Article&match_order=1&q=InnoDB%E7%8A%B6%E6%80%81&zhida_source=entity")**** mysql -e "SHOW ENGINE INNODB STATUS\\G" 关注以下关键信息: ****2.4 第四步:抽丝剥茧------定位根因**** ![](https://oss.xyyzone.com/jishuzhan/article/2044607415266639873/e55694a9d126c2756cc2fbb28491f484.webp) **图5:根因链条------大查询被KILL后的雪崩效应** ****经过完整的排查,根因链条清晰了:**** ****① 最初的触发点:大查询被KILL但进程未退出**** -- 查看是否有过被KILL的查询 SELECT \* FROM [information_schema](https://link.juejin.cn?target=https%3A%2F%2Fzhida.zhihu.com%2Fsearch%3Fcontent_id%3D273195248%26content_type%3DArticle%26match_order%3D1%26q%3Dinformation_schema%26zhida_source%3Dentity "https://zhida.zhihu.com/search?content_id=273195248&content_type=Article&match_order=1&q=information_schema&zhida_source=entity").INNODB_TRX WHERE TRX_STATE = 'RUNNING'; -- 查看事务运行时间 SELECT id, time, state, info FROM information_schema.PROCESSLIST WHERE time \> 300; ****发现:有一个查询运行超过1小时(Time=3600+),这个查询在之前被手动KILL了,但进程清理未完成。**** ****② 连锁反应:工作流阻塞 + 新请求堆积**** 大查询被KILL后,清理进程仍在消耗CPU。同时: • 工作流依赖该查询结果,无法继续执行 • 工作流线程被阻塞在[表锁](https://link.juejin.cn?target=https%3A%2F%2Fzhida.zhihu.com%2Fsearch%3Fcontent_id%3D273195248%26content_type%3DArticle%26match_order%3D1%26q%3D%25E8%25A1%25A8%25E9%2594%2581%26zhida_source%3Dentity "https://zhida.zhihu.com/search?content_id=273195248&content_type=Article&match_order=1&q=%E8%A1%A8%E9%94%81&zhida_source=entity")上 • 新的工作流请求不断堆积 • 数据库连接数不断攀升(487个) ****③ 雪崩效应:系统越来越卡**** ① 大查询被KILL,清理进程占用CPU ② 表锁未释放,工作流无法提交 ③ 新请求堆积,连接数暴涨 ④ 新请求也变成慢查询 ⑤ CPU从60% → 280% → 680% ⑥ 系统越来越卡 → 雪崩 ****三、解决方案:分步处理**** ****① 第一步:KILL僵尸查询**** 先清理掉那些长时间运行且无意义的查询: -- 找出运行超过30分钟的查询 SELECT CONCAT('KILL ', id, ';') FROM information_schema.PROCESSLIST WHERE Command != 'Binlog Dump' AND Time \> 1800; -- 或者直接KILL特定ID KILL 15234; -- Time=2847秒的查询 KILL 15235; -- Time=2156秒的查询 KILL 15240; -- Time=1890秒的查询 ****② 第二步:释放表锁**** 如果KILL后锁仍未释放,需要强制解锁: -- 查看当前锁状态 SHOW OPEN TABLES WHERE In_use \> 0; -- 查看[元数据锁](https://link.juejin.cn?target=https%3A%2F%2Fzhida.zhihu.com%2Fsearch%3Fcontent_id%3D273195248%26content_type%3DArticle%26match_order%3D1%26q%3D%25E5%2585%2583%25E6%2595%25B0%25E6%258D%25AE%25E9%2594%2581%26zhida_source%3Dentity "https://zhida.zhihu.com/search?content_id=273195248&content_type=Article&match_order=1&q=%E5%85%83%E6%95%B0%E6%8D%AE%E9%94%81&zhida_source=entity") SELECT \* FROM information_schema.INNODB_METRICS WHERE NAME LIKE 'metadata_lock%'; -- 等待锁超时自动释放 SET GLOBAL innodb_lock_wait_timeout = 50; -- 调整为50秒 ****③ 第三步:扩容临时应对**** 如果CPU仍然高,可以临时扩容: ## 在负载均衡层限制流量 ## 或者临时增加MySQL服务器资源 ## 监控CPU下降情况 ****④ 第四步:索引优化(根因解决)**** 找到那条运行1小时的查询,分析为什么会这么慢: -- 查看慢查询日志 SHOW VARIABLES LIKE 'slow_query_log%'; -- 查看执行计划 EXPLAIN SELECT \* FROM order_logs WHERE create_time \> '2024-01-01' ...; 可能的问题: ****四、效果验证**** ****五、预防措施**** ****六、AI辅助排查prompt模板**** 遇到MySQL CPU飙升时,这个prompt可以直接用: 【事故描述】 MySQL CPU从正常值飙升到XX%,系统变卡/无响应 【已有的排查信息】 * SHOW PROCESSLIST结果:\[粘贴关键行

  • SHOW ENGINE INNODB STATUS结果:[粘贴关键段落]

  • Threads_connected: XX

  • Slow_queries: XX

【请分析】

  1. 最可能的3个根因方向

  2. 长时间运行的查询最可能是什么问题?

  3. "Locked"/"metadata lock" 和CPU飙升有什么关系?

  4. 应该优先KILL哪些查询?

七、经验总结

这次MySQL CPU飙升的特殊之处在于------表面上是要优化慢查询,实际上是一个被KILL的查询引发的连锁反应。

这类问题的排查要点:

• 不要只看慢查询数量,要看PROCESSLIST中Time最长的那些

• 长时间运行的查询即使被KILL,清理过程也可能消耗大量资源

• 表锁/元数据锁会阻塞后续请求,形成雪崩效应

• 监控要关注连接数变化趋势,比CPU告警更早发现问题

排查顺序建议:

① SHOW PROCESSLIST → 找Time最长的查询

② SHOW ENGINE INNODB STATUS → 看锁等待情况

③ information_schema表 → 查事务和锁详情

④ KILL僵尸查询 → 止血

⑤ EXPLAIN慢查询 → 找根因

⑥ 加索引/优化SQL → 治本

相关推荐
浪客川2 小时前
【百例RUST - 006】一文理解所有权和切片
开发语言·后端·rust
香香甜甜的辣椒炒肉2 小时前
Spring JDBC 万能模板
java·后端·spring
常利兵2 小时前
从0到1:Spring Boot 中WebSocket实战揭秘,开启实时通信新时代
spring boot·后端·websocket
m0_694845572 小时前
VoxCPM部署教程:构建AI语音交互系统
服务器·人工智能·后端·自动化
Rust研习社2 小时前
Rust 是如何判断对象是否相等的?一起来聊一聊 PartialEq 与 Eq
后端·rust·编程语言
我叫黑大帅2 小时前
TCP 长连接服务:登录注册认证体系实战指南
后端·面试·go
丶西红柿丶2 小时前
python中的文件操作
后端
我叫黑大帅3 小时前
TCP通信 - 处理 TCP 流中的消息分片
后端·面试·go
卜夋3 小时前
Rust 所有权概念
后端·rust