【问题标题】:Danger in killing autovacuum: VACUUM queries (to prevent wraparound)杀死 autovacuum 的危险:VACUUM 查询(防止回绕)
【发布时间】:2013-08-04 23:55:17
【问题描述】:
有一个 autovacuum 查询需要很长时间才能运行,并阻止了 alter 查询运行。
在这个 autovacuum 进程完成之前杀死它有什么危险?
PID查询
16967 | autovacuum: VACUUM public.articles (防止环绕)
我是这样杀死它的:
select pg_terminate_backend(16967) from pg_stat_activity;
【问题讨论】:
标签:
database
postgresql
autovacuum
【解决方案1】:
您可以发出pg_cancel_backend(16967) 而不是“pg_terminate_backend()”(我的理解没有那么严重)。一旦你杀死了那个 autovacuum 进程,它就会重新启动,你可能已经注意到了,特别是因为它是出于上述原因启动的(这是为了防止回绕)。如果您手动发出VACUUM public.articles,vacuum 将更快地完成,但会以更高的磁盘 I/O 为代价。这是一个笼统的答案,但结果通常是这样。
【解决方案2】:
最好在情况变得更糟之前进行真空吸尘。有时,您必须这样做以防止数据丢失。您可能想知道当 wraparound id 发生故障时所有数据都去了哪里。数据仍将在数据库中,但将被隐藏并且在 vaccum 过程完成之前无法访问。所以让它通过自动真空或手动真空来完成。
【解决方案3】:
如果您只需要执行一次更改表,则将其杀死一次可能没有什么坏处。您应该在 psql 中的同一行提交 cancel 和 alter table,以便在另一个 autovacuum 启动并再次阻止它之前,alter table 有机会启动。
取消 autovacuum 很有可能会导致 txid 回绕和数据库紧急关闭,这将需要一些工作和停机时间来清理。但如果发生这种情况,几乎可以肯定,无论如何你已经在进行一场死亡竞赛了。
如果您经常这样做,那么您将为自己积累大量问题,包括前面提到的死亡竞赛和紧急关闭。
顺便说一句,您的选择 pg_terminate_backend(16967) 上不应该有 FROM 子句。