0

我遇到过几次我的读取查询被卡住了几个小时,并且在检查pg_stat_activity它时wait_event_typeIOWait. 每次发生这种情况时,都会在该表上运行一个活动的 autovacuum。该表是使用 pg_partman 的分区表,我使用的是 Postgres 11。

简化版查询

SELECT *
FROM bookings
WHERE user_id=? AND user_type=?

查询有一个索引,例如

CREATE index_user_id_user_type ON bookings(user_id, user_type)

我注意到 Postgres 14 对分区表(https://www.postgresql.org/docs/14/release-14.html)上的 autovacuum 进行了优化,这让我更加怀疑 autovacuum 确实是IOWait 的这个卡住/挂起查询

Autovacuum 现在分析分区表 (Yuzuko Hosoya, Álvaro Herrera)

来自分区的插入、更新和删除元组计数现在传播到它们的父表,因此 autovacuum 知道何时处理它们。

这可能是由自动真空引起的吗?

  • 如果是,为什么?有没有办法避免这种情况?
  • 如果不是,可能是什么原因?

编辑(1)添加表模式和解释计划

表架构

CREATE TABLE public.bookings (
   order_number text not null,
   event_timestamp with time zone not null,
   customer_id text not null,
   driver_id text,
   ...
) PARTITION BY RANGE (event_timestamp);

解释计划:https ://explain.depesz.com/s/y3YH

4

1 回答 1

2

等待事件证明您正在等待 I/O。VACUUM做很多 I/O。这两个事实共同强烈地指向了过载 I/O 系统的方向。

如果在 Linux 上,您可以通过观察 CPU 时间的 I/O 等待百分比来验证vmstat 1:如果该值始终超过 10,则您有一个证明。

要么提高 I/O 容量,要么通过降低autovacuum_vacuum_cost_limit. 我推荐第一个,因为如果 autovacuum 太慢,你可能会遇到更严重的问题。

于 2021-06-10T06:15:09.180 回答