Every Day of a DBA,第130期: PostgreSQL 19 新特性:自动清理监控 pg_stat_autovacuum_scores 视图
是PostgreSQL内置系统视图,为当前数据库中的每个表(包含TOAST表)返回一行数据,展示表的自动清理(autovacuum)实时分数;autovacuum会基于分数优先级处理表,分数越高,清理优先级越高。该视图同时标识autovacuum是否会对表执行VACUUM清理、ANALYZE分析,以及表是否存在事务ID回卷风险。该视图的计算逻辑与autovacuum工作进程完全一致,但使用实时数据
作者:bytehouse
Oracle ACE、PostgreSQL ACE
10+年数据库架构与运维实战经验
公众号:bytehouse
墨天轮专栏:bytehouse
CSDN:Young DBA
一、视图官方定义
pg_stat_autovacuum_scores 是PostgreSQL内置系统视图,为当前数据库中的每个表(包含TOAST表)返回一行数据,展示表的自动清理(autovacuum)实时分数;autovacuum会基于分数优先级处理表,分数越高,清理优先级越高。
该视图同时标识autovacuum是否会对表执行VACUUM清理、ANALYZE分析,以及表是否存在事务ID回卷风险。
该视图的计算逻辑与autovacuum工作进程完全一致,但使用实时数据源;而autovacuum工作进程会预加载待处理表列表,两者数据源可能存在差异。因此,该视图无法100%准确预测autovacuum的处理对象和执行顺序,仅作为参考依据。
This view contains one row for each table in the current database, showing the current autovacuum scores for that specific table. It also shows whether autovacuum would vacuum or analyze the table. view shows the current scores of all tables in the current database. One row for each table in the current database, showing the current autovacuum scores for that specific table. See pg_stat_autovacuum_scores for details. The pg_stat_autovacuum_scores view will contain one row for each table in the current database (including TOAST tables), showing the current autovacuum scores for that specific table. Autovacuum prioritizes tables deemed eligible for processing based on their score, with higher scores indicating higher priority. See for more information. While this view generates its results the same way that autovacuum workers do, it does so using the current source information, which might differ from the source information that an autovacuum worker sees when it gathers its list of tables to process. Therefore, this view is not a completely reliable indicator of which tables autovacuum will process and what order it will process them.
二、视图SQL定义
CREATE VIEW pg_stat_autovacuum_scores AS SELECT s.oid AS relid, n.nspname AS schemaname, c.relname AS relname, s.score, s.xid_score, s.mxid_score, s.vacuum_score, s.vacuum_insert_score, s.analyze_score, s.do_vacuum, s.do_analyze, s.for_wraparound FROM pg_stat_get_autovacuum_scores() s JOIN pg_class c on c.oid = s.oid LEFT JOIN pg_namespace n ON n.oid = c.relnamespace;
三、视图字段说明
| 字段名 | 类型 | 含义 |
|---|---|---|
| relid | oid | 表的唯一对象标识符(OID) |
| schemaname | name | 表所属模式名称 |
| relname | name | 表名称 |
| score | float8 | 总优先级分数(所有子分数最大值) |
| xid_score | float8 | 事务ID老化分数(基于事务ID冻结阈值) |
| mxid_score | float8 | 多事务ID老化分数(基于多事务冻结阈值) |
| vacuum_score | float8 | 常规VACUUM分数(基于死元组、更新/删除量) |
| vacuum_insert_score | float8 | 插入清理分数(基于批量插入数据量) |
| analyze_score | float8 | ANALYZE分析分数(基于数据变更行数阈值) |
| do_vacuum | bool | 是否需要执行VACUUM清理 |
| do_analyze | bool | 是否需要执行ANALYZE分析 |
| for_wraparound | bool | 是否因事务ID回卷风险需要强制清理 |
PostgreSQL的autovacuum不是随机执行,而是基于分数排序处理表,这个视图完全复刻了autovacuum worker的评分逻辑,评分维度包含6大核心指标:
| 分数字段 | 含义 | 计算依据 |
|---|---|---|
score |
总优先级分数(最大值) | 所有子分数的最高值,决定最终优先级 |
xid_score |
事务ID老化分数 | 表的事务ID距离冻结阈值的时长 |
mxid_score |
多事务ID老化分数 | 多事务ID距离冻结阈值的时长 |
vacuum_score |
常规VACUUM分数 | 表的死元组数量、更新删除量 |
vacuum_insert_score |
插入清理分数 | 表的批量插入数据量 |
analyze_score |
ANALYZE分析分数 | 表的数据变更行数阈值 |
关键判断标识
-
do_vacuum:布尔值,true表示表满足条件,需要执行VACUUM; -
do_analyze:布尔值,true表示表满足条件,需要执行ANALYZE; -
for_wraparound:布尔值,true表示表存在事务ID回卷风险,必须强制清理(数据库防崩溃机制)。
相关视图:
-
pg_stat_xact_user_tables
-
pg_statio_all_tables
四、内核核心函数:pg_stat_get_autovacuum_scores
该C函数是视图的数据计算核心,完全复刻autovacuum的评分与判断逻辑,遍历数据库表并计算清理分数、判断清理需求。
+/*
+ * pg_stat_get_autovacuum_scores
+ *
+ * Returns current autovacuum scores for all relevant tables in the current
+ * database.
+ */
+Datum
+pg_stat_get_autovacuum_scores(PG_FUNCTION_ARGS)
+{
+ int effective_multixact_freeze_max_age;
+ Relation rel;
+ TableScanDesc scan;
+ HeapTuple tup;
+ ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
+
+ InitMaterializedSRF(fcinfo, 0);
+
+ /* some prerequisite initialization */
+ effective_multixact_freeze_max_age = MultiXactMemberFreezeThreshold();
+ recentXid = ReadNextTransactionId();
+ recentMulti = ReadNextMultiXactId();
+
+ /* scan pg_class */
+ rel = table_open(RelationRelationId, AccessShareLock);
+ scan = table_beginscan_catalog(rel, 0, NULL);
+ while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL)
+ {
+ Form_pg_class form = (Form_pg_class) GETSTRUCT(tup);
+ AutoVacOpts *avopts;
+ bool dovacuum;
+ bool doanalyze;
+ bool wraparound;
+ AutoVacuumScores scores;
+ Datum vals[10];
+ bool nulls[10] = {false};
+
+ /* skip ineligible entries */
+ if (form->relkind != RELKIND_RELATION &&
+ form->relkind != RELKIND_MATVIEW &&
+ form->relkind != RELKIND_TOASTVALUE)
+ continue;
+ if (form->relpersistence == RELPERSISTENCE_TEMP)
+ continue;
+
+ avopts = extract_autovac_opts(tup, RelationGetDescr(rel));
+ relation_needs_vacanalyze(form->oid, avopts, form,
+ effective_multixact_freeze_max_age, 0,
+ &dovacuum, &doanalyze, &wraparound,
+ &scores);
+ if (avopts)
+ pfree(avopts);
+
+ vals[0] = ObjectIdGetDatum(form->oid);
+ vals[1] = Float8GetDatum(scores.max);
+ vals[2] = Float8GetDatum(scores.xid);
+ vals[3] = Float8GetDatum(scores.mxid);
+ vals[4] = Float8GetDatum(scores.vac);
+ vals[5] = Float8GetDatum(scores.vac_ins);
+ vals[6] = Float8GetDatum(scores.anl);
+ vals[7] = BoolGetDatum(dovacuum);
+ vals[8] = BoolGetDatum(doanalyze);
+ vals[9] = BoolGetDatum(wraparound);
+
+ tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, vals, nulls);
+ }
+ table_endscan(scan);
+ table_close(rel, AccessShareLock);
+
+ return (Datum) 0;
+}
这是视图的核心计算逻辑,完全复刻autovacuum worker的判断逻辑,分步解析:
(1)初始化环境
effective_multixact_freeze_max_age = MultiXactMemberFreezeThreshold(); recentXid = ReadNextTransactionId(); recentMulti = ReadNextMultiXactId();
-
获取多事务冻结阈值、最新事务ID、最新多事务ID;
-
这些是计算表老化程度、分数的基础参数。
(2)扫描系统表pg_class
遍历数据库中所有表的元数据,筛选符合清理条件的表:
if (form->relkind != RELKIND_RELATION && form->relkind != RELKIND_MATVIEW && form->relkind != RELKIND_TOASTVALUE) continue; if (form->relpersistence == RELPERSISTENCE_TEMP) continue;
筛选规则:
-
仅保留:普通表、物化视图、TOAST系统表;
-
跳过临时表(autovacuum不处理临时表)。
(3)核心计算:判断是否需要清理+计算分数
avopts = extract_autovac_opts(tup, RelationGetDescr(rel)); relation_needs_vacanalyze( form->oid, avopts, form, effective_multixact_freeze_max_age, 0, &dovacuum, &doanalyze, &wraparound, &scores );
-
extract_autovac_opts:提取表的自定义autovacuum配置(优先级高于全局配置); -
relation_needs_vacanalyze:内核核心函数,计算所有分数、判断是否需要清理/分析/回卷保护。
(4)返回结果集
将计算好的OID、分数、布尔标识,组装为结果集返回给SQL视图。
更多推荐
所有评论(0)