PostgreSQL中vacuum主流程分析
发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,本篇内容介绍了"PostgreSQL中vacuum主流程分析"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有
千家信息网最后更新 2026年11月01日PostgreSQL中vacuum主流程分析
本篇内容介绍了"PostgreSQL中vacuum主流程分析"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
一、数据结构
宏定义
Vacuum和Analyze命令选项
/* ---------------------- * Vacuum and Analyze Statements * Vacuum和Analyze命令选项 * * Even though these are nominally two statements, it's convenient to use * just one node type for both. Note that at least one of VACOPT_VACUUM * and VACOPT_ANALYZE must be set in options. * 虽然在这里有两种不同的语句,但只需要使用统一的Node类型即可. * 注意至少VACOPT_VACUUM/VACOPT_ANALYZE在选项中设置. * ---------------------- */typedef enum VacuumOption{ VACOPT_VACUUM = 1 << 0, /* do VACUUM */ VACOPT_ANALYZE = 1 << 1, /* do ANALYZE */ VACOPT_VERBOSE = 1 << 2, /* print progress info */ VACOPT_FREEZE = 1 << 3, /* FREEZE option */ VACOPT_FULL = 1 << 4, /* FULL (non-concurrent) vacuum */ VACOPT_SKIP_LOCKED = 1 << 5, /* skip if cannot get lock */ VACOPT_SKIPTOAST = 1 << 6, /* don't process the TOAST table, if any */ VACOPT_DISABLE_PAGE_SKIPPING = 1 << 7 /* don't skip any pages */} VacuumOption;VacuumStmt
存储vacuum命令的option&Relation链表
typedef struct VacuumStmt{ NodeTag type;//Tag //VacuumOption位标记 int options; /* OR of VacuumOption flags */ //VacuumRelation链表,如为NIL-->所有Relation. List *rels; /* list of VacuumRelation, or NIL for all */} VacuumStmt;VacuumParams
vacuum命令参数
/* * Parameters customizing behavior of VACUUM and ANALYZE. * 客户端调用VACUUM/ANALYZE时的定制化参数 */typedef struct VacuumParams{ //最小freeze age,-1表示使用默认 int freeze_min_age; /* min freeze age, -1 to use default */ //扫描整个table的freeze age int freeze_table_age; /* age at which to scan whole table */ //最小的multixact freeze age,-1表示默认 int multixact_freeze_min_age; /* min multixact freeze age, -1 to * use default */ //扫描全表的freeze age,-1表示默认 int multixact_freeze_table_age; /* multixact age at which to scan * whole table */ //是否强制wraparound? bool is_wraparound; /* force a for-wraparound vacuum */ //以毫秒为单位的最小执行阈值 int log_min_duration; /* minimum execution threshold in ms at * which verbose logs are activated, -1 * to use default */} VacuumParams;VacuumRelation
VACUUM/ANALYZE命令的目标表信息
/* * Info about a single target table of VACUUM/ANALYZE. * VACUUM/ANALYZE命令的目标表信息. * * If the OID field is set, it always identifies the table to process. * Then the relation field can be NULL; if it isn't, it's used only to report * failure to open/lock the relation. * 如设置了OID字段,该值通常是将要处理的数据表. * 那么关系字段可以为空;如果不是,则仅用于报告未能打开/锁定关系。 */typedef struct VacuumRelation{ NodeTag type; RangeVar *relation; /* table name to process, or NULL */ Oid oid; /* table's OID; InvalidOid if not looked up */ List *va_cols; /* list of column names, or NIL for all */} VacuumRelation;二、源码解读
ExecVacuum函数,手工执行VACUUM/ANALYZE命令时的主入口,vacuum()函数的包装器(wrapper).
/* * Primary entry point for manual VACUUM and ANALYZE commands * 手工执行VACUUM/ANALYZE命令时的主入口 * * This is mainly a preparation wrapper for the real operations that will * happen in vacuum(). * 这是vacuum()函数的包装器(wrapper) */voidExecVacuum(VacuumStmt *vacstmt, bool isTopLevel){ VacuumParams params; /* sanity checks on options */ //验证&检查 Assert(vacstmt->options & (VACOPT_VACUUM | VACOPT_ANALYZE)); Assert((vacstmt->options & VACOPT_VACUUM) || !(vacstmt->options & (VACOPT_FULL | VACOPT_FREEZE))); Assert(!(vacstmt->options & VACOPT_SKIPTOAST)); /* * Make sure VACOPT_ANALYZE is specified if any column lists are present. * 如出现字段列表,则确保指定了VACOPT_ANALYZE选项 */ if (!(vacstmt->options & VACOPT_ANALYZE)) { ListCell *lc; foreach(lc, vacstmt->rels) { VacuumRelation *vrel = lfirst_node(VacuumRelation, lc); if (vrel->va_cols != NIL) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("ANALYZE option must be specified when a column list is provided"))); } } /* * All freeze ages are zero if the FREEZE option is given; otherwise pass * them as -1 which means to use the default values. * 如指定了FREEZE选项则设置所有freeze ages为0. * 否则的话,传递-1(即使用默认值). */ if (vacstmt->options & VACOPT_FREEZE) { //指定VACOPT_FREEZE params.freeze_min_age = 0; params.freeze_table_age = 0; params.multixact_freeze_min_age = 0; params.multixact_freeze_table_age = 0; } else { params.freeze_min_age = -1; params.freeze_table_age = -1; params.multixact_freeze_min_age = -1; params.multixact_freeze_table_age = -1; } /* user-invoked vacuum is never "for wraparound" */ //用户调用的vacuum永远不会是wraparound params.is_wraparound = false; /* user-invoked vacuum never uses this parameter */ //用户调用vacuum永远不会使用该参数 params.log_min_duration = -1; /* Now go through the common routine */ //调用vacuum vacuum(vacstmt->options, vacstmt->rels, ¶ms, NULL, isTopLevel);}三、跟踪分析
测试脚本
17:19:28 (xdb@[local]:5432)testdb=# vacuum t1;
启动gdb,设置断点
(gdb) b ExecVacuumBreakpoint 1 at 0x6b99a1: file vacuum.c, line 92.(gdb) cContinuing.Breakpoint 1, ExecVacuum (vacstmt=0x210e9c0, isTopLevel=true) at vacuum.c:9292 Assert(vacstmt->options & (VACOPT_VACUUM | VACOPT_ANALYZE));(gdb)
输入参数
options = 1 -> VACOPT_VACUUM
(gdb) p *vacstmt$1 = {type = T_VacuumStmt, options = 1, rels = 0x210e988}(gdb)获取Relation相关信息
gdb) n93 Assert((vacstmt->options & VACOPT_VACUUM) ||(gdb) 95 Assert(!(vacstmt->options & VACOPT_SKIPTOAST));(gdb) 100 if (!(vacstmt->options & VACOPT_ANALYZE))(gdb) 104 foreach(lc, vacstmt->rels)(gdb) 106 VacuumRelation *vrel = lfirst_node(VacuumRelation, lc);(gdb) 108 if (vrel->va_cols != NIL)(gdb) p *vrel$3 = {type = T_VacuumRelation, relation = 0x210e8d0, oid = 0, va_cols = 0x0}(gdb) p *vrel->relation$4 = {type = T_RangeVar, catalogname = 0x0, schemaname = 0x0, relname = 0x210e8b0 "t1", inh = true, relpersistence = 112 'p', alias = 0x0, location = 7}(gdb)设置vacuum参数
(gdb) n104 foreach(lc, vacstmt->rels)(gdb) 119 if (vacstmt->options & VACOPT_FREEZE)(gdb) 128 params.freeze_min_age = -1;(gdb) 129 params.freeze_table_age = -1;(gdb) 130 params.multixact_freeze_min_age = -1;(gdb) 131 params.multixact_freeze_table_age = -1;(gdb) 135 params.is_wraparound = false;(gdb) (gdb) n138 params.log_min_duration = -1;(gdb)
调用vacuum
141 vacuum(vacstmt->options, vacstmt->rels, ¶ms, NULL, isTopLevel);(gdb) 142 }(gdb) standard_ProcessUtility (pstmt=0x210ea80, queryString=0x210dec8 "vacuum t1;", context=PROCESS_UTILITY_TOPLEVEL, params=0x0, queryEnv=0x0, dest=0x210ed70, completionTag=0x7fff1d69dea0 "") at utility.c:672672 break;
"PostgreSQL中vacuum主流程分析"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!
命令
参数
分析
最小
信息
函数
字段
主流
主流程
入口
内容
手工
数据
更多
用户
目标
知识
包装
不同
学有所成
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
有格互联网科技
上海卓越科技互联网
广州大一互联网络科技有限公司
网络科技有限互联网
互联网金融 金融科技
华宇互联网科技
互联网科技logo
碳银互联网科技有限公司
互联网科技公司介绍
互联网科技有限公司 翻译
中正互联网科技招聘
中盈科技互联网信息有限公司
天速互联网络科技有限公司
崇明区互联网教育科技诚信经营
晓花互联网科技有限公司网址
如何创新互联网科技
互联网科技包装股
马化腾互联网科技教学
科技互联网公司两年变化
互联网科技创业计划的风险分析
上海喔噻互联网科技有限公司
百单网互联网科技有限公司怎么样
互联网科技工作委员会
互联网科技深圳
鑫亿盛互联网科技
太原新华互联网科技学校怎么样
云创客互联网科技公司
浙南科技城互联网大厦建设工程
互联网安防科技感
唐山双旺合互联网科技产业园