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