【发布时间】:2021-02-24 19:54:51
【问题描述】:
首先,我知道依赖应用层的手动清理很奇怪,但这就是我们决定运行它的方式。 我有以下堆栈:
- HikariCP
- JDBC
- AWS 中的 Postgres 11
现在问题来了。当我们重新开始使用 autovacuum=off 的全新表时,手动真空工作正常。我可以看到 dead_tuples 的数量增长到阈值然后又回到 0。这些表在并行连接中被大量更新(也正在使用 HOT)。在某些时候,死行的数量就像 100k 跳到阈值并回到 100k。 n_dead_tuples 慢慢爬升。
现在最糟糕的是,当您从 pg 控制台发出真空时,所有死元组都被清除,但奇怪的是,当应用程序发出真空时它是成功的,但部分清除了“阈值量记录”,但不是全部? 现在我很确定以下几点:
- 分析未运行,也未自动清空
- 没有长时间运行的事务
- 没有进行复制
- 这些表是“私有的”
从控制台发出真空与自动提交与 JDBC 有什么区别?为什么从控制台发出的真空正在清理 ALL 元组,而来自 JDBC 的真空只能部分清理它? JDBC 真空是在具有默认隔离级别的池中的新连接中运行的,是的,更新是并行进行的,但这与从控制台执行真空时相同。
来自池的连接是否以某种方式损坏并且看不到更新?隔离是问题吗? 能见度地图损坏? 索引引用旧元组?
旁注:我观察到与 autovacuum on 和成本限制相同的行为,例如 4000-8000 ,阈值默认值 + 5% 。起初 n_dead_tuples 接近 0 大约 4-5 小时......第二天桌子是 86gigs,有数百万死元组。所有其他表都被吸尘并正常...
PS:我会尝试在 JDBC 中记录一个 vac 详细信息。 PS2:因为我们是在 AWS 上运行的,会不会是备份导致它停止清理?
PS3:当提到真空时,我指的是简单真空,而不是完全真空。我们不会发布完全真空。
【问题讨论】:
-
这听起来不太可能。是的,
VACUUM (VERBOSE)会提供信息。将autovacuum_vacuum_cost_delay = 0设置为最大速度。 -
我以前没有做过vaccum,所以我觉得这很有趣。你能显示代码你实际上是如何触发 FULL Vacuum 的吗?还看postgresql.org/docs/current/…,似乎有很多可以尝试的选项。 stackoverflow.com/questions/46982548/…
-
我没有使用全真空
-
"现在最糟糕的是,当你从 pg 控制台发出真空时,所有死元组都被清除了,但奇怪的是,当应用程序发出真空时它是成功的,但部分清除了“阈值数量记录”,但不是全部?你具体看到了什么让你这么想?
-
@jjanes 虽然一切都已启动并运行,但我可以看到应用程序正在清理,但 n_dead 从 50k-100k 变回 50k...从控制台抽真空,n_dead 下降到 0... .. 过了一会儿,它开始蠕动 10-60,然后从 20-70 回到 20k,依此类推
标签: java postgresql jdbc hikaricp vacuum