排查 Azure Database for PostgreSQL 灵活服务器中的 CPU 利用率过高问题

适用于:Azure Database for PostgreSQL 灵活服务器

本文介绍如何快速识别高 CPU 使用率的根本原因,以及在使用 Azure Database for PostgreSQL 灵活服务器时控制 CPU 利用率的可能补救操作。

本文内容:

  • 关于识别并获取缓解根本原因的建议的故障排除指南。
  • 关于用于识别高 CPU 使用率的工具,例如 Azure 指标、查询存储和 pg_stat_statements。
  • 如何确定根本原因,例如长时间运行的查询和总连接。
  • 如何使用 Explain Analyze、连接池和清空表解决 CPU 使用率过高的问题。

疑难解答指南

使用 Azure Database for PostgreSQL 灵活服务器门户上提供的功能故障排除指南,可以找到可能的根本原因和缓解高 CPU 情况的建议。 如何设置故障排除指南以使用它们,请遵循《设置故障排除指南》。

用于识别高 CPU 利用率的工具

请考虑使用这些工具来识别高 CPU 使用率。

Azure 指标

Azure 指标可作为检查确定日期和时间的 CPU 使用率的良好起点。 指标提供 CPU 使用率过高时有关持续时间的信息。 比较写入 IOP、读取 IOP、读取吞吐量和写入吞吐量与 CPU 使用率的关系图,以找出工作负荷导致高 CPU 的时间。 对于主动监视,可以针对指标配置警报。 有关分步指南,请参阅 Azure 指标

查询存储

查询存储自动捕获查询和运行时统计信息的历史记录,并保留它们以供查看。 它按时间切分数据,以便可以查看时间使用模式。 所有用户、数据库和查询的数据都存储在 Azure Database for PostgreSQL 灵活服务器实例中名为 azure_sys 的数据库中。 有关分步指南,请参阅查询存储

pg_stat_statements

pg_stat_statements 扩展有助于识别占用服务器时间的查询。

平均执行时间

对于 Postgres 版本 13 及更高版本,请使用以下语句按平均执行时间查看前五个 SQL 语句:

SELECT userid::regrole, dbid, query, mean_exec_time
FROM pg_stat_statements
ORDER BY mean_exec_time
DESC LIMIT 5;

总执行时间

执行以下语句,按总执行时间查看前五个 SQL 语句。

对于 Postgres 版本 13 及更高版本,请使用以下语句按总执行时间查看前五个 SQL 语句:

SELECT userid::regrole, dbid, query
FROM pg_stat_statements
ORDER BY total_exec_time
DESC LIMIT 5;

确定根本原因

如果 CPU 消耗级别通常较高,根本原因可能如下:

长时间运行的事务

长时间运行的事务所消耗的 CPU 资源可能导致 CPU 使用率过高。

以下查询有助于识别运行时间最长的连接:

SELECT pid, usename, datname, query, now() - xact_start as duration
FROM pg_stat_activity
WHERE pid <> pg_backend_pid() and state IN ('idle in transaction', 'active')
ORDER BY duration DESC;

总连接数以及按状态排序连接

数据库的大量连接也是另一个问题,可能会导致 CPU 和内存利用率增加。

以下查询提供按状态排序的连接数的相关信息:

SELECT state, count(*)
FROM  pg_stat_activity
WHERE pid <> pg_backend_pid()
GROUP BY 1 ORDER BY 1;

解决 CPU 利用率较高的问题

使用 Explain Analyze、PG Bouncer、连接池和终止长时间运行的事务来解决 CPU 使用率过高的问题。

使用 Explain Analyze

知道长时间运行的查询后,请使用 EXPLAIN 进一步调查查询并进行优化。
有关 EXPLAIN 命令的详细信息,请查看 Explain 计划

PGBouncer 和连接池

如果存在大量空闲连接或大量使用 CPU 的连接,请考虑使用 PgBouncer 等连接池程序。

有关 PgBouncer 的更多详细信息,请查看:

连接池器

最佳做法

Azure Database for PostgreSQL 灵活服务器将 PgBouncer 作为内置连接池解决方案予以提供。 有关详细信息,请参阅 PgBouncer

终止长期运行的事务

可以考虑终止将长时间运行的事务作为选项。

若要终止会话的 PID,需要使用以下查询检测 PID:

SELECT pid, usename, datname, query, now() - xact_start as duration
FROM pg_stat_activity
WHERE pid <> pg_backend_pid() and state IN ('idle in transaction', 'active')
ORDER BY duration DESC;

还可以按其他属性进行筛选,例如 usename(用户名)、datname(数据库名称)等。

获得会话的 PID 后,可以使用以下查询进行终止:

SELECT pg_terminate_backend(pid);

监视清空和表统计信息

使表统计信息保持最新状态有助于提高查询性能。 监视是否正在执行常规清空。

以下查询有助于识别需要清空的表:

select schemaname,relname,n_dead_tup,n_live_tup,last_vacuum,last_analyze,last_autovacuum,last_autoanalyze
from pg_stat_all_tables where n_live_tup > 0;

last_autovacuumlast_autoanalyze 列提供上次自动清空或分析表的日期和时间。 如果未定期清空表,请执行以下步骤来优化自动清空。 有关自动清空故障排除和优化的详细信息,请参阅自动清空故障排除

短期解决方案是对可看到缓慢查询的表执行手动清空分析:

vacuum analyze <table_name>;