在日常使用 MySQL 的过程中, 会遇到 CPU 使用率过高甚至达到 100% 的情况. CPU 飙升会导致数据库无法连接, 事务无法提交等一系列问题. 本文基于日常问题处理介绍造成 CPU 飙升的原因以及解决方法.
排查流程及解决方案
业务突增
客户业务突增导致 CPU 负载飙升, 定位方法可以查看监控指标: 每秒执行操作数, 每秒执行事务数. 如果这两个指标的变化与 CPU 的变化趋势能对应上, 说明客户业务有突增.
例如: 客户反馈数据库一点 CPU 出现飙升, 通过查询监控中的每秒执行操作数以及每秒执行事务数发现在对应的时间点有突增, 由此分析 CPU 的上升是由于客户本身的业务导致.
每秒执行操作数和事务数统计
解决方案
实例的 QPS 高, 需要结合慢查询进行分析, 看下 SQL 是否有优化的空间, 如果 SQL 较为简单, 执行效率也比较高, 此时, SQL 执行优化的效果也不会很好, 需要从应用架构以及实力规格等因素来解决问题:
1. 升级实例规格, 增加 CPU 资源.
2. 增加只读实例, 将对数据一致性不敏感的查询 (比如商品种类查询, 列车车次查询) 转移到只读实例上, 分担主实例压力.
3. 定期归档历史数据, 采用分库分表或者分区的方式减小查询访问的数据量.
4. 尽量优化查询, 减少查询的执行成本(逻辑 IO, 执行需要访问的表数据行数), 提高应用可扩展性.
慢查询
查看监控运行线程, 运行线程数如果运行线程数的变化趋势与 CPU 的变化趋势能够对应上, 可以说明数据库吞吐已经出现问题, 可能存在有慢查询(运行线程数一般大于 20 就有问题), 可以通过监控中可以看到慢查询的数量.
运行线程数和慢查询数监控
执行效率低的 SQL 一般会被记录在慢查询中. 如果想要确定具体是那些 SQL 查询效率低, 可以在控制台下载慢查询日志. 如果慢查询日志为空, 可以将慢查询阈值调低(long_query_time 这个参数在控制台调整, 一般调整到 0.5s 就可以), 这样慢 SQL 就会记录到慢日志里面, 然后在下载慢查询日志就可以分析具体是那些 SQL 执行效率较低.
解决方案
实例出现 CPU 飙升, 但 QPS(每秒执行的查询次数)不高; 查询执行效率低, 执行时需要扫描大量表中数据. 此时可能是由于存在慢查询导致, 查询执行效率低, 为了获取预期的结果就需要访问大量的数据, 导致平均逻辑 IO 增高, 此时就会是 CPU 利用率过高.
此时需要 DBA, 定位效率低的查询, 优化查询的执行效率, 降低查询执行的成本.
具体定位的过程可以参考:
1. 通过在控制台下载慢查询日志, 定位效率低的 SQL 并进行优化
2. 也可以通过 show processlist; 或 show full processlist; 命令查看当前执行的查询, 反复执行, 找到慢查询的 process ID , 运行 kill 慢查询的 id 命名杀掉慢查询进程.
总结
MySQL 处在高负载环境下, 磁盘 IO 读写过多, 肯定会占用很多资源, 必然会使 CPU 占用过高. CPU 过高, 可以做如下方案进行优化:
1. 打开慢查询日志, 查询是否是某个 SQL 语句占用过多资源, 如果是的话, 可以对 SQL 语句进行优化, 比如优化 insert 语句, 优化 group by 语句, 优化 order by 语句, 优化 join 语句等等;
2. 考虑索引问题;
3. 定期分析表, 使用 optimize table;
4. 优化数据库对象;
5. 考虑是否是锁问题;
6. 调整一些 MySQL Server 参数, 比如 key_buffer_size,table_cache,innodb_buffer_pool_size,innodb_log_file_size 等等;
7. 如果数据量过大, 可以考虑使用 MySQL 集群或者搭建高可用环境.
来源: https://www.qcloud.com/developer/article/1483450