当 MySQL CPU 使用率达到 100% 时,需要系统性地排查。以下是紧急排查步骤和优化建议:
一、紧急处理步骤
1. 快速查看当前运行进程
-- 查看正在执行的查询
SHOW FULL PROCESSLIST;
-- 或使用 sys 库(MySQL 5.7+)
SELECT * FROM sys.processlist WHERE command != 'Sleep' ORDER BY time DESC LIMIT 10;
2. 识别高消耗查询
-- 查看运行时间长的查询
SELECT * FROM information_schema.processlist
WHERE COMMAND != 'Sleep' AND TIME > 10
ORDER BY TIME DESC;
-- 查看当前锁等待
SELECT * FROM sys.innodb_lock_waits;
3. 检查性能模式(Performance Schema)
-- 查看高负载 SQL
SELECT * FROM sys.statement_analysis
ORDER BY avg_latency DESC LIMIT 5;
-- 查看全表扫描
SELECT * FROM sys.statements_with_full_table_scans LIMIT 5;
二、定位问题根源
1. 系统层面检查
# 查看系统负载
top -c
htop
# 确认是否为 MySQL 进程
pidstat -p <mysql_pid> 1 5
# I/O 状态(可能因 I/O 等待导致 CPU 堆积)
iostat -xm 2
2. MySQL 内部诊断
-- 查看当前 QPS/TPS
SHOW GLOBAL STATUS LIKE 'Questions';
SHOW GLOBAL STATUS LIKE 'Com_commit';
SHOW GLOBAL STATUS LIKE 'Com_rollback';
-- 检查临时表和文件排序
SHOW GLOBAL STATUS LIKE 'Created_tmp%';
SHOW GLOBAL STATUS LIKE 'Sort_merge_passes';
三、常见原因及解决方案
| 可能原因 | 检查方法 | 应急措施 |
|---|---|---|
| 1. 低效 SQL | EXPLAIN分析执行计划,检查全表扫描 | 紧急终止查询:KILL <query_id> |
| 2. 锁竞争 | SHOW ENGINE INNODB STATUS查看锁等待 | 优化事务,减少锁持有时间 |
| 3. 配置不当 | 检查 tmp_table_size/join_buffer_size等 | 调整参数,重启实例 |
| 4. 并发突增 | 监控连接数:SHOW STATUS LIKE 'Threads_connected' | 限制连接:max_connections |
| 5. 硬件瓶颈 | 监控磁盘 I/O、内存使用 | 升级硬件/优化查询 |
四、深入分析工具
1. 开启慢查询日志(临时)
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 2; -- 设置 2 秒以上为慢查询
-- 分析慢日志
mysqldumpslow -s t /path/to/slow.log
pt-query-digest /path/to/slow.log
2. 使用 pt-query-digest 分析
# 实时捕获查询
pt-query-digest --processlist h=localhost --interval 0.01 --print
3. 检查索引效率
-- 查看未使用的索引
SELECT * FROM sys.schema_unused_indexes;
-- 查看冗余索引
SELECT * FROM sys.schema_redundant_indexes;
五、预防措施
- 设置监控报警
- 监控 CPU 使用率、慢查询数、连接数
- 设置阈值自动告警
- 定期优化
-- 定期分析表 ANALYZE TABLE critical_table; -- 优化碎片化表 OPTIMIZE TABLE fragmented_table; - 架构优化
- 读写分离
- 热点数据缓存(Redis)
- 分库分表
六、紧急恢复顺序
- 立即终止:长时间运行的异常查询
- 快速回滚:如果是新上线查询导致,紧急回滚变更
- 扩容:临时增加 CPU 资源
- 降级:关闭非核心查询功能
- 限流:控制应用端并发请求数
注意:生产环境操作前,确保有备份和回滚方案。建议在测试环境复现问题后再进行参数调整。