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

一、事故现场

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

严重告警 MySQL CPU使用率:60%

严重告警 MySQL CPU使用率:280%

紧急告警 MySQL CPU使用率:680%

从60%到680%,只用了5-10分钟。业务系统开始出现明显卡顿。

• 用户反馈:页面加载变慢,点击无响应

• 运维反馈:数据库连接堆积,慢SQL告警不断

• 应用日志:大量超时错误,线程池打满

图1:MySQL CPU飙升趋势(60% → 680%,约10分钟)

二、排查思路:先止血,再定位根因

这次CPU飙升和普通的慢查询不一样------增长速度太快,而且越往后越卡。直觉告诉我,这不是单一慢查询的问题。

排查原则:先止血保命,再全面排查,最后聚焦根因。

图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 | <-- 异常偏高

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

图3:慢SQL堆积趋势(系统越来越卡)

2.2 第二步:系统层排查

系统层资源充足,CPU飙升是MySQL自身造成的。

2.3 第三步:MySQL层深度排查

① 查看当前所有连接

mysql -e "SHOW PROCESSLIST\G"

图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状态

mysql -e "SHOW ENGINE INNODB STATUS\G"

关注以下关键信息:

2.4 第四步:抽丝剥茧------定位根因

图5:根因链条------大查询被KILL后的雪崩效应

经过完整的排查,根因链条清晰了:

① 最初的触发点:大查询被KILL但进程未退出

-- 查看是否有过被KILL的查询

SELECT * FROM information_schema.INNODB_TRX WHERE TRX_STATE = 'RUNNING';

-- 查看事务运行时间

SELECT id, time, state, info FROM information_schema.PROCESSLIST WHERE time > 300;

发现:有一个查询运行超过1小时(Time=3600+),这个查询在之前被手动KILL了,但进程清理未完成。

② 连锁反应:工作流阻塞 + 新请求堆积

大查询被KILL后,清理进程仍在消耗CPU。同时:

• 工作流依赖该查询结果,无法继续执行

• 工作流线程被阻塞在表锁

• 新的工作流请求不断堆积

• 数据库连接数不断攀升(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;

-- 查看元数据锁

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 → 治本

相关推荐
高级程序源3 小时前
django校企合作实习基地管理系统82506-计算机课程设计、毕业设计
vue.js·后端·python·mysql·django·课程设计·pygame
盖伦发发3 小时前
Redis 核心教学: 数据结构, 缓存设计, 分布式锁
java·redis·后端·软件工程
卷毛的技术笔记3 小时前
RocketMQ事务消息:我把分布式事务这层窗户纸捅破了
java·分布式·后端·java-rocketmq
铁皮饭盒4 小时前
网页端, 40mb离线模型, 自动抠图, 不用 Python,不用服务器,不用 API Key, 不用显卡
前端·javascript·后端
IT_陈寒4 小时前
Redis并发写入踩坑记录:别让超时设置坑了你
前端·人工智能·后端
Bs_MoneyMagnet4 小时前
基于springboot+vue的图书馆预约系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·毕业设计·图书管理系统·计算机毕业设计
console.log('npc')4 小时前
03 — 核心框架:App 与中间件
后端·node.js·express
小蒜学长4 小时前
基于小程序的绘画作品创作与分享社区系统的设计与实现(代码+数据库+LW)
java·spring boot·后端·绘画作品·创作分享社区
江湖十年4 小时前
Go GOPROXY 兜底链的坑:从一次诡异的 CI lint 失败说起
后端·面试·go
考虑考虑12 小时前
docker compose V2版本新属性
运维·后端·自动化运维