如何排查并解决 Amazon RDS for MySQL 或 Amazon Aurora MySQL 实例上的 CPU 利用率过高问题?

3 分钟阅读
0

我的 Amazon Relational Database Service(Amazon RDS)for MySQL 数据库实例或 Amazon Aurora MySQL 兼容版实例的 CPU 利用率很高。如何排查并解决 CPU 利用率过高问题?

简短描述

CPU 利用率的增加可能是由多种因素引起的,例如,用户启动的繁重工作负载、多个并发查询或长时间运行的事务。

要确定 Amazon RDS for MySQL 实例中 CPU 利用的来源,请查看下列方法:

  • 增强监控
  • Performance Insights
  • 检测工作负载中 CPU 利用率产生原因的查询
  • 具有已激活监控的日志

确定来源后,分析和优化您的工作负载以降低 CPU 利用率。

解决方法

使用增强监控

增强监控可提供操作系统(OS)级别的视图。此视图有助于从更精细的层面上确定 CPU 负载过高的原因。例如,您可以查看负载平均值、CPU 分布(system%nice%)和操作系统进程列表。

借助增强监控,可以每隔 1、5 和 15 分钟检查 loadAverageMinute 数据。负载平均值大于 vCPU 数量表示该实例处于负载过重的状态。此外,如果负载平均值小于数据库实例类的 vCPU 数量,则 CPU 节流可能不是导致应用程序延迟的原因。在诊断 CPU 使用原因时,请检查负载平均值以避免误报。

例如,如果您的数据库实例使用 db.m5.2xlarge 实例类且预调配 IOPS 为 3000,达到了 CPU 限制,则可以查看以下示例指标来确定 CPU 利用率高的根本原因。在以下示例中,该实例类有 8 个与之关联的 vCPU。对于相同的负载平均值,超过 170 表示计算机在测量的时间范围内处于重负载状态:

负载平均分钟数

15170.25
5391.31
1596.74

CPU 利用率

用户(%)0.71
系统(%)4.9
Nice 值(%)93.92
总计(%)99.97

**注意:**Amazon RDS 会为工作负载提供比在数据库实例上运行的其他任务更高的优先级。为优先处理这些任务,会为工作负载任务指定较高的 Nice 值。因此,在增强监控中,Nice% 表示工作负载对数据库使用的 CPU 量。

在启用增强监控后,您还可以查看与数据库实例关联的操作系统进程列表。增强监控最多可显示 100 个进程。有助于您根据 CPU 和内存使用情况确定对性能影响最大的进程。

在增强监控的操作系统(OS)进程列表部分中,查看操作系统进程RDS 进程。确认 mysqld 或 Aurora 进程的 CPU 利用率百分比。这些指标有助于确认 CPU 利用率增加是由操作系统还是 RDS 进程引起的。或者,还能通过这些指标监控由 mysqld 或 Aurora 引起 CPU 利用率增加的情况。您还可以通过查看 cpuUtilization 的指标来了解 CPU 利用率的划分情况。有关更多信息,请参阅使用增强监控来监控操作系统指标

**注意:**如果您激活性能架构,则可以将操作系统线程 ID 映射到数据库的进程 ID。有关更多信息,请参阅为什么尽管内存足够,我的 Amazon RDS 数据库实例仍在使用虚拟内存?

使用 Performance Insights

可以使用性能详情来确定在实例上运行并导致 CPU 利用率过高的具体查询。首先,激活 Performance Insights for MySQL。然后,可以使用 Performance Insights 来优化您的工作负载。请务必咨询您的 DBA。

要查看可与 Performance Insights 结合使用的数据库引擎,请参阅在 Amazon RDS 上使用性能详情监控数据库负载

使用查询检测工作负载中 CPU 利用率的产生原因

在优化工作负载之前,必须先确定有问题的查询。您可以在出现高 CPU 问题时运行以下查询,从而确定 CPU 利用率过高的根本原因。然后,优化您的工作负载,降低 CPU 利用率。

SHOW PROCESSLIST 命令会显示 MySQL 实例上当前运行的线程。有时,同一组语句可能会继续运行而不完成。这种情况发生时,后续语句必须等待第一组语句完成。这是因为 InnoDB 行级锁定可能正在更新相同的行。有关更多信息,请参阅 MySQL 网站上的 SHOW PROCESSLIST statement

SHOW FULL PROCESSLIST;

**注意:**以主系统用户身份运行 SHOW PROCESSLIST 查询。如果您不是主系统用户,那么您必须拥有 MySQL PROCESS 服务器管理权限,才能查看 MySQL 实例上运行的所有线程。如果没有管理员权限,则 SHOW PROCESSLIST 只会显示与您正在使用的 MySQL 账户关联的线程。

INNODB_TRX 表可提供有关所有当前正在运行的 InnoDB 事务(非只读事务)的信息。

SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;

INNODB_LOCKS 表可提供有关 InnoDB 事务已请求但尚未收到的锁的信息。

对于 MySQL 5.7 或者更早版本:

SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;

对于 MySQL 8.0:

SELECT * FROM performance_schema.data_locks;

INNODB_LOCK_WAITS 表会为每个被阻止的 InnoDB 事务提供一行或多行。

对于 MySQL 5.7 或者更早版本:

SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;

对于 MySQL 8.0:

SELECT * FROM performance_schema.data_lock_waits;

您可以运行类似于以下内容的查询,查看哪些事务正在等待以及哪些事务正在阻止等待事务。有关更多信息,请参阅 MySQL 网站上的 Using InnoDB transaction and locking information

对于 MySQL 5.7 或者更早版本:

SELECT
  r.trx_id waiting_trx_id,
  r.trx_mysql_thread_id waiting_thread,
  r.trx_query waiting_query,
  b.trx_id blocking_trx_id,
  b.trx_mysql_thread_id blocking_thread,
  b.trx_query blocking_query
FROM       information_schema.innodb_lock_waits w
INNER JOIN information_schema.innodb_trx b
  ON b.trx_id = w.blocking_trx_id
INNER JOIN information_schema.innodb_trx r
  ON r.trx_id = w.requesting_trx_id;

对于 MySQL 8.0:

SELECT
  r.trx_id waiting_trx_id,
  r.trx_mysql_thread_id waiting_thread,
  r.trx_query waiting_query,
  b.trx_id blocking_trx_id,
  b.trx_mysql_thread_id blocking_thread,
  b.trx_query blocking_query
FROM       performance_schema.data_lock_waits w
INNER JOIN information_schema.innodb_trx b
  ON b.trx_id = w.blocking_engine_transaction_id
INNER JOIN information_schema.innodb_trx r
  ON r.trx_id = w.requesting_engine_transaction_id;

SHOW ENGINE INNODB STATUS 查询可提供来自标准 InnoDB 监视器的有关 InnoDB 存储引擎状态的信息。有关更多信息,请参阅 MySQL 网站上的 SHOW ENGINE statement

SHOW ENGINE INNODB STATUS;

SHOW [GLOBAL | SESSION] STATUS 可提供有关服务器状态的信息。有关更多信息,请参阅 MySQL 网站上的 SHOW STATUS statement

SHOW GLOBAL STATUS;

**注意:**这些查询已在 Aurora 2.x(MySQL 5.7)、Aurora 1. x(MySQL 5.6)、MariaDB 10.x 上进行了测试。此外,从 MySQL 5.7.14 开始,不再支持 INFORMATION_SCHEMA.INNODB_LOCKS 表,并已在 MySQL 8.0 中移除。INFORMATION_SCHEMA.INNODB_LOCKS 表已替换为 performance_schema.data_locks。有关更多信息,请参阅 MySQL 网站上的 The data_locks table

分析日志并启用监控

当您分析日志或者想要在 Amazon RDS for MySQL 中激活监控时,请考虑下面的方法:

  • 分析 MySQL 常规查询日志,查看 mysqld 在特定时间执行的操作。您还可以查看特定时间内实例上运行的查询,包括有关客户端何时连接或者断开连接的信息。有关更多信息,请参阅 MySQL 网站上的 The General Query Log
    **注意:**当您激活长时常规查询日志时,日志会消耗存储空间,并可能增加性能开销。
  • 分析 MySQL 慢查询日志,找出运行时间超过 long_query_time 秒数的查询。您还可以查看工作负载并分析查询,改善性能和内存消耗。有关更多信息,请参阅 MySQL 网站上的 The Slow Query Log。**提示:**使用慢查询日志或常规查询日志时,请将参数 log_output 设置为 FILE
  • 使用 MariaDB 审核插件来审核数据库活动。例如,您可以跟踪登录数据库的用户或者跟踪对数据库运行的查询。有关更多信息,请参阅 MariaDB 审核插件支持
  • 如果使用 Aurora for MySQL,还可以使用高级审核。审核有助于更好地控制要记录的查询类型。由此可减少日志记录的开销。
  • 使用 innodb_print_all_deadlocks 参数检查死锁和资源锁定。您可以使用此参数在 MySQL 错误日志中记录有关 InnoDB 用户事务中死锁的信息。有关更多信息,请参阅 MySQL 网站上的 innodb_print_all_deadlocks

分析并优化高 CPU 工作负载

在确定导致 CPU 利用率增加的查询后,请优化工作负载,降低 CPU 消耗。

如果发现工作负载不需要的查询,可以使用下列命令终止连接

CALL mysql.rds_kill(processID);

要查找查询的 processID,请运行 SHOW FULL PROCESSLIST 命令。

如果不想结束查询,请使用 EXPLAIN 优化查询。EXPLAIN 命令会显示运行查询所涉及的各个步骤。有关更多信息,请参阅 MySQL 网站上的 Optimizing Queries with EXPLAIN

要查看配置文件的详细信息,请激活 PROFILINGPROFILING 命令可以显示当前会话期间运行的语句的资源使用情况。有关更多信息,请参阅 MySQL 网站上的 SHOW PROFILE statement

要更新表统计信息,请使用 ANALYZE TABLEANALYZE TABLE 命令可以帮助优化器选择一个适当的计划来运行查询。有关更多信息,请参阅 MySQL 网站上的 ANALYZE TABLE statement


相关信息

Amazon RDS for MySQL

Amazon RDS for MariaDB

如何激活和监控 Amazon RDS MySQL 数据库实例的日志?

Tuning Amazon RDS for MySQL with Performance Insights