1. MySQL高CPU占用问题概述
最近在排查线上数据库性能问题时,经常遇到MySQL实例CPU使用率飙升的情况。作为DBA,快速定位并解决这类问题是基本功。今天我就结合多年实战经验,分享一套完整的MySQL高CPU问题排查方法论。
MySQL CPU使用率过高通常表现为:系统监控显示CPU使用率持续高于80%,甚至达到100%;应用响应变慢,SQL执行时间明显增加;连接数可能激增,甚至出现连接被拒绝的情况。这些问题直接影响业务稳定性,需要立即介入处理。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 问题诊断流程
2.1 实时监控数据采集
首先通过系统命令查看当前CPU使用情况:
bash复制top -c
htop
vmstat 1
重点关注:
- 用户态CPU使用率(us)
- 系统态CPU使用率(sy)
- I/O等待(iowait)
- 空闲CPU(id)
2.2 MySQL进程分析
使用show processlist命令查看当前执行的SQL:
sql复制SHOW FULL PROCESSLIST;
关键指标:
- 执行时间(Time)
- 状态(State)
- 执行的SQL语句(Info)
2.3 慢查询日志分析
检查慢查询日志配置:
sql复制SHOW VARIABLES LIKE 'slow_query%';
分析慢查询日志:
bash复制mysqldumpslow -s t /var/log/mysql/mysql-slow.log
3. 常见原因及解决方案
3.1 索引缺失或不当
典型表现:
- 全表扫描(Using filesort, Using temporary)
- 执行计划显示type=ALL
解决方案:
sql复制EXPLAIN SELECT * FROM users WHERE name LIKE '%张%';
优化建议:
- 为常用查询条件添加合适索引
- 避免在索引列上使用函数
- 优化LIKE查询模式
3.2 锁竞争
诊断方法:
sql复制SHOW ENGINE INNODB STATUS\G
重点关注:
- TRANSACTIONS部分
- LATEST DETECTED DEADLOCK
解决方案:
- 优化事务大小和持续时间
- 合理设置隔离级别
- 使用SELECT...FOR UPDATE替代LOCK IN SHARE MODE
3.3 配置不当
关键参数检查:
sql复制SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
SHOW VARIABLES LIKE 'query_cache%';
优化建议:
- 调整innodb_buffer_pool_size为物理内存的70-80%
- 关闭query_cache(MySQL 8.0已移除)
- 优化join_buffer_size等临时内存参数
4. 高级诊断工具
4.1 Performance Schema
启用性能监控:
sql复制UPDATE performance_schema.setup_instruments SET ENABLED = 'YES';
常用查询:
sql复制SELECT * FROM performance_schema.events_statements_summary_by_digest
ORDER BY SUM_TIMER_WAIT DESC LIMIT 10;
4.2 pt-query-digest
分析工具使用:
bash复制pt-query-digest /var/log/mysql/mysql-slow.log
输出解读重点:
- 响应时间占比
- 执行次数
- 查询模式
5. 预防措施
5.1 监控告警设置
建议监控指标:
- CPU使用率超过80%持续5分钟
- 活跃连接数超过max_connections的80%
- 慢查询数量突增
5.2 定期优化
维护任务:
- 每周分析表统计信息
sql复制ANALYZE TABLE important_table;
- 每月优化碎片化严重的表
sql复制OPTIMIZE TABLE fragmented_table;
5.3 架构优化
长期方案:
- 读写分离
- 分库分表
- 引入缓存层
6. 实战案例分享
最近处理的一个案例:某电商平台大促期间MySQL主库CPU持续100%。通过show processlist发现大量如下查询:
sql复制SELECT * FROM orders WHERE status='pending' AND create_time > DATE_SUB(NOW(), INTERVAL 7 DAY);
问题分析:
- 该查询缺少(status,create_time)联合索引
- 大促期间pending订单量激增
- 全表扫描导致CPU飙升
解决方案:
- 紧急添加复合索引
sql复制ALTER TABLE orders ADD INDEX idx_status_ctime(status,create_time);
- 优化查询只返回必要字段
- 增加查询缓存时间
优化后效果:
- CPU使用率从100%降至40%
- 查询响应时间从3s降至50ms
- 系统稳定性显著提升
7. 经验总结
- 预防胜于治疗:建立完善的监控体系
- 索引是把双刃剑:不是越多越好
- 配置参数需要根据业务特点调整
- 定期进行性能测试和瓶颈分析
- 保持MySQL版本更新,获取性能改进
最后分享一个实用技巧:当CPU突然飙升时,可以快速执行以下命令组合获取诊断信息:
bash复制mysqladmin processlist && mysql -e "SHOW ENGINE INNODB STATUS\G" && top -b -n 1
