AUTOVACUUM 守护进程由多个进程组成,这些进程通过从数据库中删除过时的数据或元组来回收存储。它检查具有大量插入、更新或删除记录的表,并根据配置设置清理这些表
您可以通过运行以下查询来确定数据库中的表是否需要清理:
SELECT datname, age(datfrozenxid) FROM pg_database ORDER BY age(datfrozenxid) desc limit 20;
当您连接到数据库时,运行以下查询将有助于查看 autovacuum 认为符合清理条件的表的列表:
WITH vbt AS (SELECT setting AS autovacuum_vacuum_threshold FROM pg_settings WHERE name = 'autovacuum_vacuum_threshold') , vsf AS (SELECT setting AS autovacuum_vacuum_scale_factor FROM pg_settings WHERE name = 'autovacuum_vacuum_scale_factor') , fma AS (SELECT setting AS autovacuum_freeze_max_age FROM pg_settings WHERE name = 'autovacuum_freeze_max_age') , sto AS (select opt_oid, split_part(setting, '=', 1) as param, split_part(setting, '=', 2) as value from (select oid opt_oid, unnest(reloptions) setting from pg_class) opt) SELECT '"'||ns.nspname||'"."'||c.relname||'"' as relation , pg_size_pretty(pg_table_size(c.oid)) as table_size , age(relfrozenxid) as xid_age , coalesce(cfma.value::float, autovacuum_freeze_max_age::float) autovacuum_freeze_max_age , (coalesce(cvbt.value::float, autovacuum_vacuum_threshold::float) + coalesce(cvsf.value::float,autovacuum_vacuum_scale_factor::float) * c.reltuples) as autovacuum_vacuum_tuples , n_dead_tup as dead_tuples FROM pg_class c join pg_namespace ns on ns.oid = c.relnamespace join pg_stat_all_tables stat on stat.relid = c.oid join vbt on (1=1) join vsf on (1=1) join fma on (1=1) left join sto cvbt on cvbt.param = 'autovacuum_vacuum_threshold' and c.oid = cvbt.opt_oid left join sto cvsf on cvsf.param = 'autovacuum_vacuum_scale_factor' and c.oid = cvsf.opt_oid left join sto cfma on cfma.param = 'autovacuum_freeze_max_age' and c.oid = cfma.opt_oid WHERE c.relkind = 'r' and nspname <> 'pg_catalog' and ( age(relfrozenxid) >= coalesce(cfma.value::float, autovacuum_freeze_max_age::float) or coalesce(cvbt.value::float, autovacuum_vacuum_threshold::float) + coalesce(cvsf.value::float,autovacuum_vacuum_scale_factor::float) * c.reltuples <= n_dead_tup -- or 1 = 1 ) ORDER BY age(relfrozenxid) DESC LIMIT 50;
一些参数会影响 autovacuum 的行为,运行以下查询会显示一些直接影响 autovacuum 及其行为的参数的值:
SELECT name, setting, unit, short_desc FROM pg_settings WHERE name IN ( 'autovacuum_max_workers', 'autovacuum_analyze_scale_factor', 'autovacuum_naptime', 'autovacuum_analyze_threshold', 'autovacuum_analyze_scale_factor', 'autovacuum_vacuum_threshold', 'autovacuum_vacuum_scale_factor', 'autovacuum_vacuum_threshold', 'autovacuum_vacuum_cost_delay', 'autovacuum_vacuum_cost_limit', 'vacuum_cost_limit', 'autovacuum_freeze_max_age', 'maintenance_work_mem', 'vacuum_freeze_min_age');
虽然这些都会影响 autovacuum,但其中一些最重要的是:
maintenance_mork_mem
autovacuum_freeze_max_age
autovacuum_max_workers
autovacuum_vacuum_cost_delay
Autovacuum_vacuum_cost_limit
以下是其中一些重要选项的定义/解释:
Autovacuum_freeze_max_age 指定表的 pg_class.relfrozenxid 字段在强制执行 VACUUM 操作以防止表内的事务 ID 回绕之前可以达到的最大年龄(以事务为单位)。请注意,即使在 autovacuum 以其他方式禁用时,系统也会启动 autovacuum 进程以防止回绕。
autovacuum_max_workers (integer) 此选项指定可能在任何时候运行的最大自动清理进程数,因为清理不会在单个自动清理进程中发生。默认值为三 (3)。
autovacuum_vacuum_cost_limit 此选项指定将在自动 VACUUM 操作中使用的成本限制值。如果指定了 -1(这是默认值),则将使用常规的 Vacuum_cost_limit 值。请注意,该值会按比例分配给正在运行的 autovacuum 工作人员(如果有多个工作人员),因此每个工作人员的限制总和不会超过此变量的值。
autovacuum_vacuum_cost_delay 此选项指定将在自动 VACUUM 操作中使用的成本延迟值。如果指定了 -1,将使用常规的 Vacuum_cost_delay 值。默认值为 20 毫秒。
autovacuum_vacuum_scale_factor 此选项指定触发 autovacuum 的频率。如果您希望 autovacuum 更频繁地运行,我建议 autovacuum_vacuum_scale_factor 使用较小的值(例如 0.02 或 0.01)。此参数的值越小,autovacuum 每次处理的死元组数就越少。对于大型表,这意味着 autovacuum 可以花费更少的 I/O 和更少的时间来完成。
注意:对于小型表,可能会担心 autovacuum 会不必要地频繁运行并产生开销。如果您的表具有不同的大小或不同的写入模式,我建议您在表级别使用不同的值设置此参数,而不是在数据库级别设置一个值。有关 Autovacuum 选项的进一步定义,请查看此文档 [2]
[1]Autovacuum 调整 - https://www.2ndquadrant.com/en/blog/autovacuum-tuning-basics/ [2]进一步 Autovacuum 选项定义 - https://www.postgresql.org/docs/9.6/runtime- config-autovacuum.html#GUC-AUTOVACUUM-MAX-WORKERS