我有一个 14.7 TB Postgres(9.1) 数据库,它必须长时间承受大量写入。我知道我需要密切管理我的事务 ID 以防止数据库锁定。最近我注意到查询速度变慢了,并且看到在我们的大型只读表上运行了多个自动清理,并带有“(防止回绕)”下标。我停止了正在运行的软件并执行了一个vacuumdb -F -a
命令。但是,当我运行时,select current_query from pg_stat_activity
我看到 autovacuum 进程仍在运行,即使在手动清理期间也是如此。我尝试杀死 autovacuumsselect pg_cancel_backend(pid)
并且他们死了,但然后立即重新启动。我的问题:
- autovacuum 是否应该在手动数据库清理期间继续运行?
- 如何有效地停止这些 autovacuum 进程?
- 为什么这些 autovacuums 会继续在只读表上运行?有什么可以吸尘的?
Autovacuum 是由表上的表统计信息触发的,只要你手动
VACUUM (FREEZE)
不做,这些是不会更新的。这就是为什么反环绕自动清理进程仍将启动的原因。但这不是什么大问题:
VACUUM
任何时候只有一个人可以在桌子上跑步。现在,anti-wraparound autovacuum 工作人员在阻止另一个进程时不会放弃,在这种情况下是你的手册VACUUM
。但是,如果你杀死了 anti-wraparound autovacuum worker,你的手册VACUUM
会得到锁,现在是重新启动的 anti-wraparound autovacuum worker 被阻塞。查看pg_locks
以验证它们是否正在等待锁定 (granted = FALSE
)。现在您
vacuumdb
一个接一个地处理一个表,因此您必须准备好在它开始处理下一个表并被那里的新 autovacuum 工作人员阻止时立即杀死它。VACUUM
在那些大型只读表上手动启动可能比使用 更容易vacuumdb
,因为这样您就可以控制何时清空哪个表。确保设置
maintenance_work_mem
高以加快速度VACUUM
。您还应该autovacuum_vacuum_cost_delay
至少在这些大表上设置为 2ms 或更低,以便将来的 autovacuum 运行更快地完成。为了减少未来的痛苦,
autovacuum_freeze_max_age
大幅降低受影响的桌子。然后下一个反环绕真空将更快启动并且完成得更快。最重要的是,尽快升级到 v13,因为从该版本开始,仅插入表也将定期进行清理,这应该可以解决问题。