PostgreSQL 教程: 优化 autovacuum 以避免事务 ID 回卷的问题

五月 31, 2024

摘要:在本教程中,您将学习如何在 PostgreSQL 中调整 autovacuum,以避免事务 ID 回卷的问题。

目录

通常,autovacuum 会处理事务 ID 回卷的问题,并在表中最老的事务 ID 早于 autovacuum_freeze_max_age 个事务,或最老的组合事务 ID 早于 autovacuum_multixact_freeze_max_age 个事务时,启动一个特殊的 “防回卷” 的 autovacuum 工作进程。

确保防回卷的 VACUUM 可以冻结所有表中的元组

同样,您必须确保没有任何东西阻止 autovacuum 冻结旧元组和推进pg_database.datfrozenxidpg_database.datminmxid。这些阻塞来源可能是:

  • 运行时间很长的数据库会话,保持了一个打开的事务,或创建了临时表(autovacuum 无法处理临时表)。
  • 数据损坏,这可能导致所有 autovacuum 工作进程出现错误和故障。

为防止数据损坏,请使用良好的硬件,并及时更新到最新的 PostgreSQL 次版本。

为防回卷的 VACUUM,优化接收 UPDATE 或 DELETE 的表

在接收UPDATEDELETE的表上,您所要做的就是查看 autovacuum 是否运行得足够快,以便及时完成(可参阅优化 autovacuum 以清理死元组)。

为防回卷的 VACUUM,优化仅接收 INSERT 的表

从 PostgreSQL 13 开始,在这种情况下没有特别的注意事项,因为在此类表上会定期运行 autovacuum。

在此之前,仅进行插入的表是有问题的:因为没有死元组,正常的 autovacuum 运行永远不会触发。然后,一旦超过autovacuum_freeze_max_ageautovacuum_multixact_freeze_max_age,可能会突然启动一次大规模的 autovacuum 运行,冻结整个大表,这要花费很长时间和消耗大量 I/O。

为了避免这种情况,请对这样的表降低autovacuum_freeze_max_age

ALTER TABLE insert_only SET (autovacuum_freeze_max_age = 10000000);

分区

对于非常大的表,建议使用分区。这样做的好处是,您可以让多个 autovacuum 工作进程并行处理多个分区,这样整个分区表的完成速度就比单个 autovacuum 工作进程更快。

如果有许多分区,应该增加 autovacuum_max_workers,即 autovacuum 工作进程的最大数量。

分区还可以帮助清理接收大量更新的表,只要更新会影响到所有分区即可。

了解更多

PostgreSQL 优化