postgresql Postgres:自动吸尘和自动吸尘环绕.什么时候开始?

nnsrf1az  于 2022-12-23  发布在  PostgreSQL
关注(0)|答案(2)|浏览(114)

我有'autovacuum_freeze_max_age',默认值为200 000 000。理论上,我发现一个规则,自动真空绕回开始时:

If age(relfrozenxid) > autovacuum_freeze_max_age

但是,通常的自动真空何时启动?我如何计算时间:
1.何时启动检查床上的常规自动真空?
1.自动真空何时变为自动真空绕回?确实是在年龄(relfrozenxid)〉自动真空冻结最大年龄之后?

eivgtgni

eivgtgni1#

如文件所述,触发正常自动真空
如果自最后一个VACUUM以来废弃的元组的数目超过"真空阈值",则表被清空。

vacuum threshold = vacuum base threshold + vacuum scale factor * number of tuples

其中真空基础阈值是autovacuum_vacuum_threshold,真空比例因子是autovacuum_vacuum_scale_factor,并且元组的数量是pg_class.reltuples
如果自上一次清空以来插入的元组数超过了定义的插入阈值,也会清空表,该阈值定义为:

vacuum insert threshold = vacuum base insert threshold + vacuum insert scale factor * number of tuples

其中真空插入基本阈值是autovacuum_vacuum_insert_threshold,并且真空插入比例因子是autovacuum_vacuum_insert_scale_factor。
第二部分仅适用于PostgreSQL v13及更高版本。
此外,
如果表的relfrozenxid值大于旧的vacuum_freeze_table_age事务,则执行积极的真空以冻结旧元组并推进relfrozenxid;否则,仅扫描自上次真空以来已修改的页。
因此,如果表中有足够旧的行,则由正常机制触发的autovacuum工作线程运行可以作为防绕回VACUUM运行。
最后,
始终清空relfrozenxid值大于autovacuum_freeze_max_age事务旧值的表
因此,如果一个包含旧的活动元组的表在正常处理过程中从未被自动清空,那么即使自动清空被禁用,也会为它触发一个特殊的防绕回自动清空运行。如果存在早于vacuum_multixact_freeze_table_age的多事务,也会强制执行这样的自动清空运行,请参阅此处。从PostgreSQL v14开始,如果表中未冻结的行早于vacuum_failsafe_age,防绕回自动真空将跳过索引清除以进行更快的处理。
是的,这很复杂。

ftf50wuq

ftf50wuq2#

进行查询,显示死循环(简单真空启动时)和真空环绕时:

with dead_tup as ( 
 SELECT st.schemaname || '.' || st.relname tablename,
         st.n_dead_tup dead_tup,
         current_setting('autovacuum_vacuum_threshold')::int8 +
         current_setting('autovacuum_vacuum_scale_factor')::float * c.reltuples
         max_dead_tup,
         (current_setting('autovacuum_vacuum_threshold')::int8 +
         current_setting('autovacuum_vacuum_scale_factor')::float * c.reltuples - st.n_dead_tup) as left_for_tr_vacuum,
         st.last_autovacuum,
         c.relnamespace,
         c.oid
  FROM   pg_stat_all_tables st,
         pg_class c
  WHERE  c.oid = st.relid
  AND    c.relkind IN ('r','m','t')
  AND    st.schemaname not like ('pg_temp%'))
SELECT  c.oid::regclass as table,
        current_setting('autovacuum_freeze_max_age')::int8 -
        age(c.relfrozenxid) as xid_left,
        pg_relation_size(c.oid) as relsize, 
        dt.dead_tup,
        dt.max_dead_tup,
        dt.left_for_tr_vacuum,
        dt.last_autovacuum 
from (pg_class c 
      join pg_namespace n on (c.relnamespace=n.oid)
      left join dead_tup dt on (c.relnamespace=dt.relnamespace and c.oid=dt.oid))
where c.relkind IN ('r','m','t') --and (age(c.relfrozenxid)::int8 > (current_setting('autovacuum_freeze_max_age')::int8 * 0.8))
      AND n.nspname not like ('pg_temp%')
order by 2

相关问题