Postgres Autovacuum 是否会导致读取查询卡在 IOWait 等待事件中?

问题描述

我遇到过几次我的读取查询被卡住几个小时的情况,当在 pg_stat_activity 上检查时,它有 wait_event_typeIOWait。也会发生这种情况,每次发生这种情况时,该表上都会运行一个活动的自动清理程序。该表是使用 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 知道何时处理它们。

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

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

Edit(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

解决方法

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

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

通过降低 autovacuum_vacuum_cost_limit 提高 I/O 容量或减慢自动清理速度。我推荐第一个,因为如果 autovacuum 太慢,你最终可能会遇到更严重的问题。