问题描述
RDS MySQL/MariaDB TX 版使用过程中,会遇到CPU使用率过高甚至达到100%的情况。
问题原因
应用提交查询操作或数据修改操作时,系统需要执行大量的逻辑读操作,其中逻辑IO包含执行查询所需访问表的数据行数。所以系统需要消耗大量的CPU资源以维护从存储系统读取到内存中的数据一致性。
提示:大量行锁冲突、行锁等待或后台任务也有可能会导致实例的CPU使用率过高,但这些情况出现的概率非常低,本文不做讨论。
解决方案
阿里云提醒您:
- 如果您对实例或数据有修改、变更等风险操作,务必注意实例的容灾、容错能力,确保数据安全。
- 如果您对实例(包括但不限于ECS、RDS)等进行配置与数据修改,建议提前创建快照或开启RDS日志备份等功能。
- 如果您在阿里云平台授权或者提交过登录账号、密码等安全信息,建议您及时修改。
下文通过一个简化的模型来说明系统资源、语句执行成本以及QPS(Query Per Second 每秒执行的查询数)之间的关系。
- 条件:应用模型恒定,即应用没有修改。
- avg_lgc_io:执行每条查询需要的平均逻辑IO。
- total_lgc_io:实例的CPU资源在单位时间内能够处理的逻辑IO总量。
- 关系公式:
total_lgc_io = avg_lgc_io × QPS
即单位时间CPU资源 = 查询执行的平均成本 × 单位时间执行的查询数量
。
您可以利用数据管理(DMS)解决MySQL/MariaDB TX实例CPU使用率过高的问题。下文主要介绍使用DMS来解决CPU使用率过高的问题,如何通过CloudDBA来解决CPU使用率过高的问题,可以参见文档利用CloudDBA解决MySQL实例CPU使用率过高的问题。
数据管理工具提供了辅助排查并解决实例性能问题的功能,主要有以下几种:
- 实例诊断报告。
- SQL窗口提供的查询优化建议和查看执行计划。
- 实例会话。
其中,实例诊断报告是排查和解决MySQL/MariaDB TX实例性能问题的最佳工具。无论何种原因导致的性能问题,建议您首先参考下实例诊断报告,尤其是诊断报告中的SQL优化、会话列表和慢SQL汇总。
避免出现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实例的压力。
- 对于查询数据比较静态、查询重复度高、查询结果集小于1MB 的应用,考虑开启查询缓存(Query Cache)。
说明:能否从开启查询缓存(Query Cache)中获益需要经过测试,具体设置请参见RDS MySQL 版查询缓存(Query Cache)的设置和使用。
- 定期归档历史数据、采用分库分表或者分区的方式减小查询访问的数据量。
- 尽量优化查询,减少查询的执行成本,提高应用可扩展性。
- 现象描述
- 查询执行成本(查询访问表数据行数avg_lgc_io)高
- 现象描述
- 特征:实例的QPS不高。查询执行效率低、执行时需要扫描大量表中数据、优化余地大。
- 表现:存在慢查询,QPS和CPU使用率曲线变化不吻合。
- 原因分析:由于查询执行效率低,为获得预期的结果即需要访问大量的数据即平均逻辑IO高,在QPS并不高的情况下(例如网站访问量不大),就会导致实例的CPU使用率高。
- 解决方案
解决该状况的原则是:定位效率低的查询、优化查询的执行效率、降低查询执行的成本。- 通过以下方式定位效率低的查询:
- 通过
show processlist;
或show full processlist;
SQL语句查看当前执行的查询,如下图所示。
对于查询时间长、运行状态为Sending data、Copying to tmp table、Copying to tmp table on disk、Sorting result、Using filesort等的会话可能均包含有性能问题的查询。
- 若在QPS高导致CPU使用率高的场景中,查询执行时间通常比较短,
show processlist;
命令或实例会话中可能会不容易捕捉到当前执行的查询。可以通过执行以下SQL语句进行查询。explain [$SQL]
说明:[$SQL]为有性能问题的SQL查询语句。
- 您可以通过执行类似
kill [$ID];
的命令来终止长时间执行的会话,终止会话请参见RDS MySQL 版如何终止会话。关于长时间执行会话的管理,请参见RDS MySQL 版管理长时间运行查询。说明:[$ID]为该查询语句对应的会话ID。
- 若在QPS高导致CPU使用率高的场景中,查询执行时间通常比较短,
- 通过DMS查看当前执行的查询,查询步骤如下。
- 在DMS控制台上登录数据库。
- 选择
- 单击SQL列中的查询文本,即可显示完整的查询和其执行计划,如下图所示。
- 通过
- 得到需要优化的查询后,可以通过DMS控制台上SQL诊断来获取查询的优化建议。诊断报告同样适用于排查历史实例CPU使用率高的问题。
- 在DMS控制台上登录数据库。
- 选择
- 单击 SQL诊断,即可得到优化建议,如下图所示。
- 根据优化建议添加索引,确认查询执行成本就会大幅减少,实例CPU使用率100%的问题解决。
- 通过以下方式定位效率低的查询:
- 现象描述
适用于
- 云数据库RDS MySQL版