暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PostgreSQL 18: 引入 autovacuum_vacuum_max_threshold

王语嫣 2025-02-08
69

Vacuum/Autovacuum 是每个 PostgreSQL 安装的关键部分之一。如果自动真空配置不正确,迟早会遇到膨胀和性能问题。我们看到的大多数安装都可以使用默认设置正常运行,很多人可能永远不需要调整自动真空的任何参数。另一方面,有些工作负载的默认设置不再适用,您需要调整自动真空处理特定表的方式。PostgreSQL 18 将附带一个名为“autovacuum_vacuum_max_threshold”的新参数,它为您提供了处理特定问题的更多选项。

在查看新参数之前,让我们先看看默认配置中自动清理何时启动。这由两个参数控制:

postgres=# show autovacuum_vacuum_threshold;
 autovacuum_vacuum_threshold 
-----------------------------
 50
(1 row)
 
postgres=# show autovacuum_vacuum_scale_factor;
 autovacuum_vacuum_scale_factor 
--------------------------------
 0.2
(1 row)
复制

这意味着,在触发自动清理之前,大约 20% 的表(autovacuum_vacuum_scale_factor的 0.2 )+ 50 个元组(autovacuum_vacuum_threshold)需要更改。假设这个简单的表有一百万行:

postgres=# \d t
                 Table "public.t"
 Column |  Type   | Collation | Nullable | Default
--------+---------+-----------+----------+---------
 a      | integer |           |          | 
 b      | text    |           |          | 
 
postgres=# select count(*) from t;
  count 
---------
 1000000
(1 row)
复制

…只要更改表的 20% 以上,就很容易触发此问题:

postgres=# select last_autovacuum from pg_stat_all_tables where relname = 't';
       last_autovacuum        
------------------------------
 2025-02-07 07:24:58.40076+01
(1 row)
 
postgres=# select now();
              now              
-------------------------------
 2025-02-07 07:26:48.333006+01
(1 row)
 
postgres=# update t set b = 'xxx' where a < 250000;
UPDATE 249999
 
postgres=# select pg_sleep('60');
 pg_sleep 
----------
  
(1 row)
 
postgres=# select last_autovacuum from pg_stat_all_tables where relname = 't';
        last_autovacuum        
-------------------------------
 2025-02-07 07:27:58.356337+01
(1 row)
复制

其结果是,表中的行越多,自动清理启动所需的时间就越长。您现在就可以通过在表或实例级别全局调整“autovacuum_vacuum_threshold”或“autovacuum_vacuum_scale_factor”或两者来处理此问题。例如,如果您希望在上述表中更改了 10,000 行后自动清理启动,您可以这样做:

postgres=# alter table t set ( autovacuum_vacuum_threshold = 10000 );
ALTER TABLE
postgres=# alter table t set ( autovacuum_vacuum_scale_factor = 0 );
ALTER TABLE
复制

执行与上述相同的测试,但只更改 10001 行:

postgres=# update t set b = 'aaa' where a < 10002;
UPDATE 10001
postgres=# select now();
              now              
-------------------------------
 2025-02-07 07:54:35.295413+01
(1 row)
 
postgres=# select last_autovacuum from pg_stat_all_tables where relname = 't';
        last_autovacuum        
-------------------------------
 2025-02-07 07:27:58.356337+01
(1 row)
 
postgres=# select pg_sleep(60);
 pg_sleep 
----------
  
(1 row)
 
postgres=# select last_autovacuum from pg_stat_all_tables where relname = 't';
       last_autovacuum        
------------------------------
 2025-02-07 07:54:58.69969+01
(1 row)
复制

缺点是,您需要手动处理。随着“autovacuum_vacuum_max_threshold”的引入,PostgreSQL 将以更“默认”的方式处理这些情况。此参数的默认值相当高:

postgres=# show autovacuum_vacuum_max_threshold;
 autovacuum_vacuum_max_threshold 
---------------------------------
 100000000
(1 row)
复制

为了看到它的实际效果,让我们重置上面的表级别设置,并设置 autovacuum_vacuum_max_threshold:

postgres=# alter table t reset ( autovacuum_vacuum_scale_factor );
ALTER TABLE
postgres=# alter table t reset ( autovacuum_vacuum_threshold );
ALTER TABLE
postgres=# alter table t set ( autovacuum_vacuum_max_threshold = 10000 );
ALTER TABLE
复制

这将产生完全相同的效果:

postgres=# update t set b = 'qqq' where a < 10002;
UPDATE 10001
postgres=# select now();
              now              
-------------------------------
 2025-02-07 08:02:51.582044+01
(1 row)
 
postgres=# select last_autovacuum from pg_stat_all_tables where relname = 't';
       last_autovacuum        
------------------------------
 2025-02-07 07:54:58.69969+01
(1 row)
 
postgres=# select pg_sleep(60);
 pg_sleep 
----------
  
(1 row)
 
postgres=# select last_autovacuum from pg_stat_all_tables where relname = 't';
        last_autovacuum        
-------------------------------
 2025-02-07 08:02:58.809895+01
(1 row)
复制

原文地址:https://www.dbi-services.com/blog/postgresql-18-introduce-autovacuum_vacuum_max_threshold/
原文作者:Daniel Westermann

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论