我的 Amazon RDS for MySQL 实例存在 CPU 使用率高的问题,如何排查并解决?

上次更新日期:2021 年 8 月 13 日

对于 MySQL 数据库实例,我的 Amazon Relational Database Service (Amazon RDS) 上的 CPU 使用率很高。我该如何排查并解决高 CPU 使用率的问题?

简短描述

CPU 使用率的提高可能由多种因素造成,例如用户启动的繁重工作负载、多个并发查询或长时间运行的事务。

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

  • 增强监控
  • Performance Insights
  • 检测工作负载中 CPU 使用率的产生原因的查询
  • 启用监控的日志

在确定产生原因之后,您可以分析和优化工作负载,以减少 CPU 使用率。

解决方法

使用增强监控

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

注意:如果启用性能架构,则可以将操作系统线程 ID 映射到数据库的进程 ID。有关更多信息,请参阅在内存足够时,为什么我的 Amazon RDS 数据库实例会使用交换内存?

使用性能详情

您可以使用性能详情来识别在实例上运行且导致高 CPU 使用率的确切查询。首先,启用适用于 MySQL 的性能详情。然后,您可以在咨询 DBA 后使用性能详情来优化工作负载。

要查看哪些数据库引擎可以与性能详情结合使用,请参阅在 Amazon RDS 上使用性能详情进行监控

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

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

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

SHOW FULL PROCESSLIST;

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

INNODB_TRX 表提供有关当前正在执行且并非只读事务的 InnoDB 事务的信息。

SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;

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

SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;

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

SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;

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

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;

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

SHOW ENGINE INNODB STATUS;

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

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 中移除。performance_schema.data_locks 表取代了 INFORMATION_SCHEMA.INNODB_LOCKS 表。有关更多信息,请参阅 MySQL 网站上的 data_lock 表

分析日志并启用监控

当您分析日志或希望在 Amazon RDS for MySQL 中启用监控时,请考虑以下方法:

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

分析和优化高 CPU 工作负载

确定导致 CPU 使用率增加的查询后,请优化工作负载以减少 CPU 消耗量。

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

CALL mysql.rds_kill(processID);

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

如果您不想强制终止查询,则使用 EXPLAIN 来优化查询。EXPLAIN 命令显示了查询执行中涉及的各个步骤。有关更多信息,请参阅 MySQL 网站上的使用 EXPLAIN 优化查询

要查看资料的详细信息,请启用 PROFILINGPROFILING 命令可以指示在当前会话期间运行的语句的资源使用情况。有关更多信息,请参阅 MySQL 网站上的 SHOW PROFILE 语句

要更新任何表统计信息,请使用 ANALYZE TABLEANALYZE TABLE 命令有助于优化程序选择适当的执行计划。有关更多信息,请参阅 MySQL 网站上的 ANALYZE TABLE 语句