如何排查 Amazon RDS 或 Amazon Aurora PostgreSQL 的高 CPU 利用率?

上次更新时间:2020 年 6 月 18 日

如何确定和解决 Amazon Relational Database Service (Amazon RDS) 或 Amazon Aurora PostgreSQL 中高 CPU 利用率的原因?

简短描述

如果您发现负载的 CPU 利用率很高,则可以使用以下工具的组合来确定原因:

本文讨论了如何使用每个工具来确定导致高 CPU 利用率的原因。

解决方法

Amazon CloudWatch 指标

您可以使用 CloudWatch 指标来确定长期的 CPU 模式。将图表 WriteIOPsReadIOPsReadThroughputWriteThroughput 与 CPU 利用率进行比较,以找出工作负载导致高 CPU 利用率的时间。

确定时间范围后,您可以查看与数据库实例关联的增强监控数据。您可以将增强监控设置为每隔 1、5、10、15、30 或 60 秒收集一次数据。这使您可以在比 CloudWatch 更精细的级别收集数据。有关更多信息,请参阅 CloudWatch 指标与增强监控指标的区别

增强监控

增强监控提供操作系统 (OS) 级别的视图,可帮助在粒度级别确定高 CPU 负载的原因。例如,您可以查看负载平均值、CPU 分配(system%nice%)和操作系统进程列表。

通过使用增强监控,以 1 分钟、5 分钟和 15 分钟的间隔检查 loadAverageMinute 数据。如果负载平均值大于 vCPU 数量,这表示该实例负载很重。此外,如果负载平均值小于数据库实例类的 vCPU 数量,则应用程序延迟可能并非由 CPU 限制引起。检查负载平均值,以避免在诊断 CPU 使用原因时出现误报。

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

负载平均分钟
 
15 170.25
5 391.31
1 596.74
CPU 利用率  
用户 (%) 0.71
系统 (%) 4.9
Nice 值 (%) 93.92
总计 (%) 99.97

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

启用增强监控后,还可检查与数据库实例关联的操作系统进程列表。增强监控仅显示 CPU 和内存的前 50 个进程。这可帮助您根据 CPU 和内存使用情况确定哪些进程对性能的影响最大。

您可以将增强监控结果与 pg_stat_activity 结果相结合,以帮助确定查询的资源使用情况

性能详情

检查对应特定时间范围的 SQL 选项卡后,您可以使用 Amazon RDS 性能详情来确定负责数据库负载的查询。

本机 PostgreSQL 视图和目录

在数据库引擎级别,如果问题实时发生,您可以使用 pg_stat_activitypg_stat_statements。这些可帮助您对发送最多流量的计算机、客户端和 IP 地址进行分组。您还可以使用此数据来查看是否存在随时间增加、应用程序服务器增加或者应用程序服务器是否卡住会话或锁定问题的情况。有关更多信息,请参阅有关 pg_stat_activitypg_stat_statements 的 PostgreSQL 文档。要启用 pg_stat_statements,请修改现有的自定义参数组并设置以下值:

  • shared_preload_libraries = pg_stat_statements
  • track_activity_query_size = 2048
  • pg_stat_statements.track = ALL
  • pg_stat_statements.max = 10000

选择立即应用,然后重启数据库实例。然后,在要监控的数据库上运行与以下内容类似的命令:

注意:以下示例在“demo”数据库中安装扩展。

demo=> select current_database();
current_database
------------------
demo
(1 row)
     
demo=> CREATE EXTENSION pg_stat_statements;

设置 pg_stat_statements 后,您可以使用以下方法之一监控输出:

  • total_time 列出查询,并查看哪个查询在数据库中花费的时间最多:
SELECT round(total_time*1000)/1000 AS total_time,query
FROM pg_stat_statements
ORDER BY total_time DESC limit 2;
  • 列出查询及调用总数、总行数和返回的行数:
SELECT query, calls, total_time, rows, 100.0 * shared_blks_hit /
nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent
FROM pg_stat_statements ORDER BY total_time DESC LIMIT 5;
  • 基于每次执行列出查询,以便随时间对查询进行抽样:
SELECT query, calls, total_time/calls as avg_time_ms, rows/calls as avg_rows,
temp_blks_read/calls as avg_tmp_read, temp_blks_written/calls as avg_temp_written
FROM pg_stat_statements
WHERE calls != 0
ORDER BY total_time DESC LIMIT 5;

PostgreSQL 日志记录参数

使用 Amazon RDS for PostgreSQL 启用查询日志记录。然后,检查 PostgreSQL 错误日志,确认您的 log_min_duration_statementlog_statement 参数已设置为适当的值。有关更多信息,请参阅有关错误报告和日志记录的 PostgreSQL 文档。

降低 CPU 使用率

确定导致高 CPU 使用率的查询后,可以使用以下方法进一步降低 CPU 使用率:

  1. 如果有机会进行调整,请使用 EXPLAINEXPLAIN ANALYZE 来识别警告。有关更多信息,请参阅有关 EXPLAIN 的 PostgreSQL 文档。
  2. 如果有重复运行的查询,请使用准备的语句来降低 CPU 的压力。

这篇文章对您有帮助吗?

我们可以改进什么?


需要更多帮助?