【问题标题】:Understanding auto-vacuum and when it is triggered了解 auto-vacuum 及其触发时间
【发布时间】:2021-05-10 10:36:07
【问题描述】:

我们注意到我们的一个表在 PG 12 上显着增长。该表是非常频繁更新的目标,包含多种列类型,包括一个非常大的 text 列(通常包含超过 50kb 的数据) - 我们运行一个本地 cron 作业来查找早于 X 时间的行并将 text 列设置为空值(因为在 X 时间之后我们不再需要该特定列的数据)。

我们知道,由于 MVCC 模型,这实际上并没有释放磁盘空间,但我们希望 auto-vacuum 能够解决这个问题。令我们惊讶的是,在没有自动真空运行的情况下,该表继续增长(现在超过 40GB)。手动运行真空已经解决了这个问题,我们不再看到增长。

这导致我调查其他表,我意识到我根本不了解自动真空是如何触发的。

这是我对它的工作原理的理解,希望有人可以分开:

  • 我查找其中包含大量死元组的表: select * from pg_stat_all_tables ORDER BY n_dead_tup desc;
  • 我将 tableX 识别为 33169557 个死元组(n_dead_tup 列)。
  • 我运行select * from pg_class ORDER BY reltuples desc; 来检查表tableX 上的估计行数
  • 我通过 reltuples 列识别了 1725253 行。
  • 我确认我的 autovacuum 设置:autovacuum_vacuum_threshold = 50 和 autovacuum_vacuum_scale_factor = 0.2
  • 我应用公式threshold + pg_class.reltuples * scale_factor,所以,50 + 1725253 * 0.2 返回 345100.6

据我了解,一旦找到 ~345100 个死元组,自动真空将在此表上启动。但是tableX 已经有多达 33169557 个死元组了!,这张桌子上的 last_autovacuum 是在 2 月。

欢迎任何澄清。

【问题讨论】:

标签: postgresql autovacuum


【解决方案1】:

你的算法绝对正确。

以下是可能出现问题的一些原因:

  • autovacuum 运行,但速度太慢,无法完成

    如果您没有看到正在运行的 autovacuum,那不是您的问题。

  • autovacuum 运行,但长时间运行的打开事务阻止它删除死元组

  • 其他表需要更紧急地清理(以避免事务 ID 回绕),所以三个工作人员忙于其他事情

  • autovacuum 运行,但与表上的高并发锁冲突(LOCK TABLE、ALTER TABLE、...)

    这会让 autovacuum 放弃,稍后再试。

  • autovacuum 已禁用,可能仅适用于该表

【讨论】:

  • 我可以在日志中查找什么(或任何类型的日志级别要求),以便我们了解 autovacuums 失败的原因吗?
  • 您可以将log_autovacuum_min_duration设置为0。
  • 这是不久前的事了,但我们的系统中有另一个应用程序具有与此处描述的完全相同的行为(功能实现在项目之间共享)、相同的表结构、完全相同的行为 -唯一的区别是它在 PG 13 上运行,而这个问题的版本是 12。我可以看到 autovacuum 在 PG13 表版本上非常频繁地启动,而 PG12 表在几个月内没有被自动清空......你知道吗这些主要版本之间是否解决了某些问题?
  • 是的,我添加了参数autovacuum_vacuum_insert_threshold和autovacuum_vacuum_scale_factor。
猜你喜欢
  • 2011-11-16
  • 1970-01-01
  • 1970-01-01
  • 2011-10-07
  • 2021-05-20
  • 2020-03-19
  • 1970-01-01
  • 1970-01-01
  • 2021-03-04
相关资源
最近更新 更多