CPU
当数据库进程在 CPU 中处于活动状态或正在等待 CPU 时,会发生此事件。
中央处理单元 (CPU) 是运行指令的计算机的组件。例如,CPU 指令执行算术运算并在内存中交换数据。如果查询增加了通过数据库引擎执行的指令的数量,则运行查询所花费的时间将增加。CPU 调度正在为进程提供 CPU 时间。调度由操作系统的内核编排。
该CPU
等待事件表示后端进程在 CPU 中处于活动状态或正在等待 CPU。您知道,当查询显示以下信息时会发生这种情况:
pg_stat_activity
中的state
列是active
。pg_stat_activity
中的wait_event_type
和wait_event
列都是null
。
要查看正在使用或等待 CPU 的后端进程,请运行以下查询。
SELECT * FROM pg_stat_activity
WHERE state = 'active'
AND wait_event_type IS NULL
AND wait_event IS NULL;
从操作系统的角度来看,CPU 在未运行空闲进程时处于活动状态。CPU 在执行计算时处于活动状态,但在等待内存输入/输出时也处于活动状态。这种类型的输入/输出主导着典型的数据库工作负载。
当此事件的发生率超过正常(可能表示性能问题)时,典型的原因包括以下几点。
突然猛增的最可能原因如下:
- 您的应用程序打开了太多与数据库同时连接。这种情况被称为“连接风暴”。
- 您的应用程序工作负载在以下任一方面发生变化:
- 新查询
- 数据集的大小增加
- 索引维护或创建
- 新函数
- 新的运算符
- 并行查询执行增加
- 您的查询执行计划已更改。在某些情况下,更改可能会导致缓冲区增加。例如,查询之前使用索引,而现在正在使用顺序扫描。在这种情况下,查询需要更多的 CPU 才能实现同样的目标。
长期反复出现的事件的最可能原因:
- CPU 上同时运行的后端进程太多。这些进程可以是并行工件。
- 查询执行不佳,因为它们需要大量缓冲区。
如果所有可能的原因都不是实际原因,则可能会发生以下情况:
- CPU 正在换入和换出进程。
- CPU 上下文切换有所增加。
- PostgreSQL 代码缺少等待事件。
如果 CPU
等待事件主导着数据库活动,它不一定表示性能问题。只在性能下降时应对此事件。
使用系统管理工具(如:Linux的top命令,Windows的任务管理器等)检查数据库进程的CPU使用率,调查数据库是否导致 CPU 增加。
您的操作取决于 CPU 等待事件增加期间连接数量是增加还是减少。要查看当前的连接数量,请运行以下查询。
SELECT count(*) FROM pg_stat_activity;
如果连接数量增加,请将消耗 CPU 的后端进程数与主机CPU的数量进行比较。以下是可能的情况:
-
消耗 CPU 的后端进程数量少于主机CPU的数量。
在这种情况下,连接数量不是问题。但是,您仍然可以尝试降低 CPU 利用率。
-
消耗 CPU 的后端进程数量大于主机CPU的数量。
在这种情况下,需考虑以下选项:
- 减少连接到数据库的后端进程的数量。例如,实施连接池解决方案,例如 pgbouncer。
- 升级主机硬件规格以获得更多CPU数量。
您可以使用pg_stat_statements或者log_min_duration_statement
,寻找 SQL 语句与 CPU 使用率之间的相关性。以下是可能的情况:
-
CPU 使用率和 SQL 语句具有相关性。
在这种情况下,找到与 CPU 使用率相关联的主要 SQL 语句,然后查找计划更改。您可以使用下面的方法之一:
- 检查与 CPU 使用率相关联的语句,看看它们是否可以使用更少的 CPU。运行
EXPLAIN
命令,手动解释计划并将其与预期的执行计划进行比较。并将重点放在影响最大的计划节点上。 - 寻找每秒数据块命中量和每秒局部数据块命中量的增加。
- 检查与 CPU 使用率相关联的语句,看看它们是否可以使用更少的 CPU。运行
-
CPU 使用率和 SQL 语句无关。
在这种情况下,请确定是否出现以下任一情况:
-
应用程序正在快速连接到数据库并断开与数据库的连接。
通过打开
log_connections
和log_disconnections
,然后分析 PostgreSQL 日志来诊断此行为。 -
操作系统已超载。
在这种情况下,后端进程使用 CPU 的时间比平时更长。如果操作系统过载,请使用系统管理工具,查看进程列表以及每个进程占用的 CPU 百分比。
-
如果您的工作负载发生了变化,请查找以下类型的更改:
-
新查询
检查是否预计会出现新的查询。如果是,请确保他们的执行计划和每秒执行次数符合预期。
-
数据集的大小增加
确定分区(如果尚未实施)是否有帮助。此策略可能会减少查询需要检索的页数。
-
索引维护或创建
检查维护时间表是否符合预期。最佳实践是在高峰活动之外安排维护活动。
-
新函数
检查这些功能在测试期间是否按预期运行。具体来说,检查每秒执行次数是否符合预期。
-
新的运算符
检查它们在测试期间是否按预期运行。
-
运行并行查询的增加
确定是否出现以下任一情况:所涉及的关系或索引的规模突然增长,因此它们与
min_parallel_table_scan_size
或min_parallel_index_scan_size
显著不同。最近对parallel_setup_cost
或parallel_tuple_cost
进行了更改。最近对max_parallel_workers
或max_parallel_workers_per_gather
进行了更改。