了解自动吸尘器及其触发时间
Understanding auto-vacuum and when it is triggered
我们注意到我们的一个 table 在 PG 12 上有了显着增长。这个 table 是非常频繁更新的目标,具有多种列类型,包括非常大的 text
列(通常包含超过 50kb 的数据)- 我们 运行 一个本地 cron 作业,它查找早于 X 时间的行并将 text
列设置为空值(因为我们不再在 X 时间后需要该特定列的数据)。
我们知道,由于 MVCC 模型,这实际上并没有释放磁盘 space,但我们希望自动真空能够解决这个问题。令我们惊讶的是,table 在没有自动真空 运行ning 的情况下继续增长(现在价值超过 40gb)。 运行 手动清理解决了这个问题,我们不再看到增长。
这让我调查了其他 tables,我意识到我根本不明白自动真空是如何触发的。
这是我对它的工作原理的理解,希望有人能解释一下:
- 我寻找其中包含大量死元组的 table:
select * from pg_stat_all_tables ORDER BY n_dead_tup desc;
- 我确定
tableX
有 33169557 个死元组(n_dead_tup 列)。
- I 运行 a
select * from pg_class ORDER BY reltuples desc;
检查 table tableX
上估计有多少行
- 我通过
reltuples
列确定了 1725253 行。
- 我确认我的 autovacuum 设置:
autovacuum_vacuum_threshold = 50
和 autovacuum_vacuum_scale_factor = 0.2
- 我应用公式
threshold + pg_class.reltuples * scale_factor
,所以,50 + 1725253 * 0.2
其中 returns 345100.6
据我了解,一旦发现约 345100 个死元组,自动清理将在此 table 上启动。但是 tableX
已经达到了惊人的 33169557 个死元组!,这个 table 上的 last_autovacuum 是在二月份回来的。
欢迎任何澄清。
你的算法完全正确。
以下是可能出错的一些原因:
autovacuum 运行,但速度太慢以至于永远无法完成
如果您没有看到 运行 autovacuum,那不是您的问题。
autovacuum 运行,但长时间的 运行 打开事务阻止它删除死元组
其他tables 需要更紧急地清理(以避免事务 ID 回绕),所以三个工作人员忙于其他事情
autovacuum 运行,但与 table 上的高并发锁冲突(LOCK TABLE
、ALTER TABLE
、...)
这会使 autovacuum 放弃并稍后重试。
autovacuum 已禁用,可能仅针对 table
我们注意到我们的一个 table 在 PG 12 上有了显着增长。这个 table 是非常频繁更新的目标,具有多种列类型,包括非常大的 text
列(通常包含超过 50kb 的数据)- 我们 运行 一个本地 cron 作业,它查找早于 X 时间的行并将 text
列设置为空值(因为我们不再在 X 时间后需要该特定列的数据)。
我们知道,由于 MVCC 模型,这实际上并没有释放磁盘 space,但我们希望自动真空能够解决这个问题。令我们惊讶的是,table 在没有自动真空 运行ning 的情况下继续增长(现在价值超过 40gb)。 运行 手动清理解决了这个问题,我们不再看到增长。
这让我调查了其他 tables,我意识到我根本不明白自动真空是如何触发的。
这是我对它的工作原理的理解,希望有人能解释一下:
- 我寻找其中包含大量死元组的 table:
select * from pg_stat_all_tables ORDER BY n_dead_tup desc;
- 我确定
tableX
有 33169557 个死元组(n_dead_tup 列)。 - I 运行 a
select * from pg_class ORDER BY reltuples desc;
检查 tabletableX
上估计有多少行
- 我通过
reltuples
列确定了 1725253 行。 - 我确认我的 autovacuum 设置:
autovacuum_vacuum_threshold = 50
和autovacuum_vacuum_scale_factor = 0.2
- 我应用公式
threshold + pg_class.reltuples * scale_factor
,所以,50 + 1725253 * 0.2
其中 returns 345100.6
据我了解,一旦发现约 345100 个死元组,自动清理将在此 table 上启动。但是 tableX
已经达到了惊人的 33169557 个死元组!,这个 table 上的 last_autovacuum 是在二月份回来的。
欢迎任何澄清。
你的算法完全正确。
以下是可能出错的一些原因:
autovacuum 运行,但速度太慢以至于永远无法完成
如果您没有看到 运行 autovacuum,那不是您的问题。
autovacuum 运行,但长时间的 运行 打开事务阻止它删除死元组
其他tables 需要更紧急地清理(以避免事务 ID 回绕),所以三个工作人员忙于其他事情
autovacuum 运行,但与 table 上的高并发锁冲突(
LOCK TABLE
、ALTER TABLE
、...)这会使 autovacuum 放弃并稍后重试。
autovacuum 已禁用,可能仅针对 table