PostgreSQL - 查询以确定哪些表当前正在被清理?

Gee*_*esu 7 postgresql vacuum postgresql-9.2

我找到了一个查询来查看真空吸尘器运行的时间,但不是当前正在运行的真空吸尘器.(http://heatware.net/databases/postgres-tables-auto-vacuum-analyze/)

有没有要完成此任务的查询?我知道我可以点击pg_stat_activity,但有些真空吸尘器没有表名,而是有pg_toast.pg_toast_3621837,所以这不会100%有效.

Pau*_*yot 6

使用系统目录可以轻松解决此问题。我建议加入,pg_locks因为 autovacuum 会获取ShareUpdateExclusiveLock它正在处理的表上的锁,以避免从pg_stat_activity.

以下查询列出了自动清空的表,如果正在清空 toast 表,则解决 pg_toast 引用,如Postgres pg_toast in autovacuum 中所述 - 哪个表?@Zeki 链接的问题。

SELECT n.nspname || '.' || c.relname
    FROM pg_namespace n, pg_stat_activity a, pg_locks l, pg_class c
    WHERE
        a.query LIKE 'autovacuum: %'
        AND l.pid = a.pid
        AND l.mode = 'ShareUpdateExclusiveLock'
        AND (c.oid = l.relation OR c.reltoastrelid = l.relation)
        AND n.oid = c.relnamespace
        AND n.nspname <> 'pg_toast';
Run Code Online (Sandbox Code Playgroud)

请注意,虽然pg_stat_activitypg_locks目录是跨数据库共享的,但此查询将仅列出当前数据库中自动清空的表,因为pg_relation它不是共享目录。


Clo*_*eto 2

不是查找表是否正在被清理,而是关闭相关表的自动清理:

alter table table_name_pattern 
set (
    autovacuum_enabled = false,
    toast.autovacuum_enabled = false
);
Run Code Online (Sandbox Code Playgroud)

表模式是一个像tbl*. 查询结束时重新打开自动真空吸尘器

alter table table_name_pattern 
set (
    autovacuum_enabled = true,
    toast.autovacuum_enabled = true
);
Run Code Online (Sandbox Code Playgroud)

编辑回应评论:

查找所涉及的表是否正在被清理的查询是不必要且无用的。如果知道一个或多个相关表正在被清理,那么应该做什么?等待并继续重复查询,直到没有一个被清理?当没有人启动长查询时,一段时间后才发现自动真空吸尘器刚刚再次启动?无关紧要。为什么不直接关闭自动真空吸尘器并避免所有麻烦呢?

以艰难的方式去做并不具有道德优越感,尤其是如果艰难的方式会比简单的方式产生更糟糕的结果。更简单的代码更容易使用和理解,但不一定更容易构建。很多时候情况恰恰相反,需要比复杂的工作更多的智力努力或准备。


如果 autovacuum 设置在事务内更改并且该事务回滚,则设置将恢复到事务开始之前的状态

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
Run Code Online (Sandbox Code Playgroud)

但是事务内部的设置在事务外部不会被看到,所以我猜 autovacuum 仍然会运行。如果这是真的,那么该设置必须在事务之外完成,并由一个作业控制,无论长时间运行的查询发生什么情况,该作业都会将其返回。