问题描述

阿里云云数据库RDS MySQL/MariaDB版使用过程中,出现CPU使用率过高甚至达到100%的情况。

问题原因

应用提交查询操作或数据修改操作时,系统需要执行大量的逻辑读操作,其中逻辑IO包含执行查询所需访问表的数据行数。所以系统需要消耗大量的CPU资源以维护从存储系统读取到内存中的数据一致性。本文以CPU使用率为100%的场景为例,介绍了两个引起该状况的原因及其解决方案,即应用负载(QPS)高和慢SQL导致查询成本高。其中由于慢SQL导致查询成本高(查询访问表数据行数多),导致实例CPU使用率高是MySQL非常常见的问题。

说明 大量行锁冲突、行锁等待或后台任务导致实例CPU使用率过高的问题,由于出现的概率非常低,本文不做讨论。
  • 应用负载(QPS)高:
    • 特征:实例的QPS高,查询比较简单,执行效率高,优化余地小。
    • 表现:没有出现慢查询,或者慢查询不是主要原因,且QPS和CPU使用率曲线变化吻合。
    • 常见场景:该状况常见于应用优化过的在线事务交易系统(例如订单系统)、高读取率的热门Web网站应用、第三方压力工具测试(例如Sysbench)等。
  • 慢SQL导致查询成本高(查询访问表数据行数多):
    • 特征:实例的QPS不高,查询执行效率低、执行时需要扫描大量表数据、优化余地大。
    • 表现:存在慢查询,QPS和CPU使用率曲线变化不吻合。
    • 原因分析:由于查询执行效率低,为获得预期的结果需要访问大量的数据导致平均逻辑IO高,因此在QPS并不高的情况下(例如网站访问量不大),也会导致实例的CPU使用率偏高。

解决方案

根据您实际情况选择对应的解决方法。

应用负载(QPS)高

对于因应用负载高导致CPU使用率高的状况,使用SQL进行优化的余地不大,建议您从应用架构、实例规格等方面来处理问题。请参考以下方法:

  • 升级实例规格,增加CPU资源,详情请参见变更配置
  • 增加只读实例,将对数据一致性不敏感的查询(比如商品种类查询、列车车次查询)转移到只读实例上,分担主实例压力,详情请参见创建MySQL只读实例
  • 使用阿里云PolarDB-X云原生分布式数据库,自动进行分库分表,将查询压力分担到多个RDS实例上。
  • 使用阿里云云数据库Memcache或者云数据库Redis,尽量从缓存中获取常用的查询结果,减轻RDS实例的压力。
  • 对于查询数据比较静态、查询重复度高、查询结果集小于1MB的应用,考虑开启查询缓存(Query Cache)。
    说明 能否从开启查询缓存(Query Cache)中获益需要经过测试,具体设置请参见RDS MySQL查询缓存(Query Cache)的设置和使用
  • 定期归档历史数据、采用分库分表或者分区的方式减小查询访问的数据量。尽量优化查询,减少查询的执行成本,提高应用可扩展性。

慢SQL导致查询成本高

解决该问题的原则:定位效率低的查询、优化查询的执行效率、降低查询执行的成本。

  1. 通过以下方式定位效率低的查询:
    • 执行以下SQL语句,查看当前执行的查询语句。
      show processlist;
      show full processlist;

      系统显示类似如下结果:

      执行结果

      查询时间长、运行状态为Sending dataCopying to tmp tableCopying to tmp table on diskSorting resultUsing filesort的查询会话可能均包含性能问题。

      • 若在QPS高导致CPU使用率高的场景中,查询执行时间通常比较短,show processlist;命令或实例会话中可能会不容易捕捉到当前执行的查询。但是您可以通过执行以下SQL语句进行查询。
        explain [$SQL]
        说明 [$SQL]为有性能问题的SQL查询语句。
      • 您可以通过执行类似kill [$ID];的命令来终止长时间执行的会话,终止会话请参见RDS MySQL如何终止会话。关于长时间执行会话的管理,请参见RDS MySQL如何管理长时间执行的查询
        说明 [$ID]为该查询语句对应的会话ID。
    • 通过数据库自治服务DAS查看当前执行的查询:
      1. 登录DAS控制台
      2. 依次单击目标实例右侧的性能 > 实例会话实例会话
      3. 单击SQL列中的查询文本,即可显示完整的查询和其执行计划。
  2. 得到需要优化的查询语句后,可以通过DMS控制台上的SQL诊断来获取优化建议。诊断报告同样适用于排查历史实例CPU使用率高的问题:
    1. 通过DMS控制台登录实例
    2. 单击页面上方的SQL窗口,选择对应的库。
    3. 将查询语句粘贴到SQL窗口,单击SQL诊断,即可得到优化建议。SQL
  3. 根据您实际情况,选择优化建议进行处理。例如添加索引,确认执行查询成本会大幅减少。

更多信息

性能问题排查并解决功能

数据管理工具提供了辅助排查并解决实例性能问题的功能,主要有以下几种。其中,实例诊断报告是排查和解决MySQL/MariaDB实例性能问题的最佳工具。无论何种原因导致的性能问题,建议您首先查看实例诊断报告,尤其是诊断报告中的SQL优化、会话列表和慢SQL汇总。

避免出现CPU使用率达到100%的原则

如何避免CPU使用率达到100%的处理方法如下:

  • 设置CPU使用率告警,保证实例CPU使用率有一定的冗余度。
  • 应用设计和开发过程中,需要考虑查询的优化,遵守MySQL优化的一般优化原则,降低查询的逻辑IO,提高应用可扩展性。
  • 新功能、新模块上线前,需要使用生产环境数据进行压力测试,建议使用阿里云性能测试PTS
  • 新功能、新模块上线前,建议使用生产环境数据进行回归测试。
  • 建议经常关注和使用诊断报告功能,详情请参见RDS访问实例诊断报告

系统资源算法

下文通过一个简化的模型来说明系统资源、SQL语句执行成本以及QPS(Query Per Second每秒执行的查询数)之间的关系:

  • 条件:应用模型恒定,即应用没有修改。
  • avg_lgc_io:执行每条查询需要的平均逻辑IO。
  • total_lgc_io:实例的CPU资源在单位时间内能够处理的逻辑IO总量。
  • 关系公式:total_lgc_io = avg_lgc_io × QPS,即单位时间CPU资源总量 = 执行查询的平均逻辑IO × 单位时间执行的查询数量

相关文档

利用CloudDBA解决MySQL实例CPU使用率过高的问题

适用于

  • 云数据库RDS MySQL版
  • 云数据库RDS MariaDB版