不要查找表是否正在进行清理,而是关闭涉及表的自动清理功能:
alter table table_name_pattern
set (
autovacuum_enabled = false,
toast.autovacuum_enabled = false
);
模式是像
tbl*
这样的全局匹配模式。在查询结束时,自动清理打开。
alter table table_name_pattern
set (
autovacuum_enabled = true,
toast.autovacuum_enabled = true
);
根据评论进行编辑:
查询涉及的表是否正在被清理是不必要且无用的。如果已知一个或多个涉及的表正在被清理,那么应该怎么做?等待并重复查询直到没有任何表在被清理?然后再开始长时间的查询,只是发现自动清理又重新启动了?这没有意义。为什么不直接关闭自动清理并避免所有麻烦呢?
在使用方法上,没有通过困难的方式就具有道德优越性,特别是如果通过困难的方式得到的结果比简单方式更差。简单的代码更易于使用和理解,但构建起来不一定更容易。很多时候恰好相反,需要更多的智力努力或准备工作。
如果在事务内更改自动清理设置,并且该事务被回滚,则该设置将恢复到事务开始前的状态。
drop table if exists t;
create table t (id int);
begin;
alter table t
set (
autovacuum_enabled = false,
toast.autovacuum_enabled = false
);
\d+ t
Table "public.t"
Column | Type | Modifiers | Storage | Stats target | Description
id | integer | | plain | |
Has OIDs: no
Options: autovacuum_enabled=false
rollback;
\d+ t
Table "public.t"
Column | Type | Modifiers | Storage | Stats target | Description
id | integer | | plain | |
Has OIDs: no
但是,在事务内部设置的参数在事务外部不可见,所以我猜自动清理仍然会运行。如果这是真的,那么设置必须在事务之外完成,并由一个作业控制,无论长时间运行的查询发生什么情况,都将其恢复为原来的设置。