用户在使用 MySQL 实例时,会遇到 CPU 使用率过高甚至达到 100% 的情况。本文将介绍造成该状况的常见原因以及解决方法,并通过 CPU 使用率为 100% 的典型场景,来分析引起该状况的原因及其相应的解决方案。
常见原因
系统执行应用提交查询(包括数据修改操作)时需要大量的逻辑读(逻辑 IO,执行查询所需访问的表的数据行数),所以系统需要消耗大量的 CPU 资源以维护从存储系统读取到内存中的数据一致性。
说明:大量行锁冲突、行锁等待或后台任务也有可能会导致实例的 CPU 使用率过高,但这些情况出现的概率非常低,本文不做讨论。
本文通过一个简化的模型来说明系统资源、语句执行成本以及 QPS(Query Per Second 每秒执行的查询数)之间的关系:
条件:应用模型恒定(应用没有修改)。
avg_lgc_io:执行每条查询需要的平均逻辑 IO。
total_lgc_io:实例的 CPU 资源在单位时间内能够处理的逻辑 IO 总量。
关系公式:total_lgc_io = avg_lgc_io x QPS -- 单位时间 CPU 资源 = 查询执行的平均成本 x 单位时间执行的查询数量
解决方法
数据管理(DMS)工具提供了几种辅助排查并解决实例性能问题的功能,主要有:
实例诊断报告
SQL 窗口提供的查询优化建议和查看执行计划
实例会话
其中,实例诊断报告是排查和解决 MySQL 实例性能问题的最佳工具。无论何种原因导致的性能问题,建议您首先参考下实例诊断报告,尤其是诊断报告中的 SQL 优化、会话列表和慢 SQL 汇总分。
另外,如果您需要阿里云的技术支持来解决 CPU 使用率高的状况,请参见
https://market.aliyun.com/store/1682301.html。
避免出现 CPU 使用率达到 100% 的一般原则
设置 CPU 使用率告警,实例 CPU 使用率保证一定的冗余度。
应用设计和开发过程中,要考虑查询的优化,遵守 MySQL 优化的一般优化原则,降低查询的逻辑 IO,提高应用可扩展性。
新功能、新模块上线前,要使用生产环境数据进行压力测试(可以考虑使用阿里云 PTS 压力测试工具)。
新功能、新模块上线前,建议使用生产环境数据进行回归测试。
建议经常关注和使用 DMS 中的诊断报告。
注意:关于如何访问 DMS 中的诊断报告,请参见
RDS 如何访问诊断报告。
典型示例
以 CPU 使用率为 100% 的典型场景为例,本文介绍了两个引起该状况的原因及其解决方案,即应用负载(QPS)高和查询执行成本(查询访问表数据行数 avg_lgc_io)高。其中,由于查询执行成本高(查询访问表数据行数多)而导致实例 CPU 使用率高是 MySQL 非常常见的问题。
应用负载(QPS)高
现象描述
特征:实例的 QPS(每秒执行的查询次数)高,查询比较简单、执行效率高、优化余地小。
表现:没有出现慢查询(或者慢查询不是主要原因),且 QPS 和 CPU 使用率曲线变化吻合。
常见场景:该状况常见于应用优化过的在线事务交易系统(例如订单系统)、高读取率的热门 Web 网站应用、第三方压力工具测试(例如 Sysbench)等。
解决方案
对于由应用负载高导致的 CPU 使用率高的状况,使用 SQL 查询进行优化的余地不大,建议您从应用架构、实例规格等方面来解决,例如:
升级实例规格,增加 CPU 资源。
增加只读实例,将对数据一致性不敏感的查询(比如商品种类查询、列车车次查询)转移到只读实例上,分担主实例压力。
使用阿里云 DRDS 产品,自动进行分库分表,将查询压力分担到多个 RDS 实例上。
使用阿里云 Memcache 或者云 Redis 产品,尽量从缓存中获取常用的查询结果,减轻 RDS 实例的压力。
对于查询数据比较静态、查询重复度高、查询结果集小于 1 MB 的应用,考虑开启查询缓存(Query Cache)。
注意:能否从开启查询缓存(Query Cache)中获益需要经过测试,具体设置请参见
RDS for MySQL 查询缓存(Query Cache)的设置和使用。
定期归档历史数据、采用分库分表或者分区的方式减小查询访问的数据量。
尽量优化查询,减少查询的执行成本(逻辑 IO,执行需要访问的表数据行数),提高应用可扩展性。
查询执行成本(查询访问表数据行数 avg_lgc_io)高
现象描述
特征:实例的 QPS(每秒执行的查询次数)不高;查询执行效率低、执行时需要扫描大量表中数据、优化余地大。
表现:存在慢查询,QPS 和 CPU 使用率曲线变化不吻合。
原因分析:由于查询执行效率低,为获得预期的结果即需要访问大量的数据(平均逻辑 IO高),在 QPS 并不高的情况下(例如网站访问量不大),就会导致实例的 CPU 使用率高。
解决方案
解决该状况的原则是:定位效率低的查询、优化查询的执行效率、降低查询执行的成本。
操作步骤
通过如下方式定位效率低的查询:
通过 show processlist; 或 show full processlist; 命令查看当前执行的查询,如下图所示:
[url=http://docs-aliyun.cn-hangzhou.oss.aliyun-inc.com/assets/pic/51587/cn_zh/1489657470048/%E6%9F%A5%E7%9C%8B%E5%BD%93%E5%89%8D%E6%89%A7%E8%A1%8C%E7%9A%84%E6%9F%A5%E8%AF%A2.png][/url]
单击查看报告,查看优化建议。
注意:对于 CPU 使用率高的问题,建议关注诊断报告的 SQL 优化、会话列表和慢 SQL 汇总部分。
根据优化建议,添加索引,查询执行成本就会大幅减少(如下图所示,从 900 亿行减小到 30 万行,查询成本降低 30 万倍),实例 CPU 使用率 100% 的问题解决。