微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

了解自动真空以及何时触发

如何解决了解自动真空以及何时触发

我们注意到我们的一个表在 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_vacuum_threshold = 50autovacuum_vacuum_scale_factor = 0.2
  • 我应用公式 threshold + pg_class.reltuples * scale_factor,因此,50 + 1725253 * 0.2 返回 345100.6

据我所知,一旦找到 ~345100 个死元组,就会在这张表上启动自动真空。但是 tableX 已经有 33169557 个死元组了!,这个表上的 last_autovacuum 是在二月份。

欢迎任何澄清。

解决方法

你的算法是绝对正确的。

以下是可能出错的一些原因:

  • autovacuum 运行,但速度太慢以至于永远无法完成

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

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

  • 其他表需要更紧急地清空(以避免事务ID回绕),所以三个worker都忙于其他事情

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

    这会让 autovacuum 放弃并稍后重试。

  • autovacuum 被禁用,可能只针对那个表

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。