PostgreSQL中vacuum主流程分析
发表于:2024-11-26 作者:千家信息网编辑
千家信息网最后更新 2024年11月26日,本篇内容介绍了"PostgreSQL中vacuum主流程分析"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有
千家信息网最后更新 2024年11月26日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安全错误
数据库的锁怎样保障安全
底层软件开发要点
上海神兵信息安全签名服务器
x86服务器国产芯片
为什么服务器只能连接一台电脑
魔兽世界部落去哪里买服务器
平板电脑服务器连接失败如何恢复
显示数据库信息
网络安全活动主题
软件开发公司管理模式
互联网络安全大会
网络软件开发模式特点
神武怎么查看服务器等级
广州前端软件开发有用吗
榆林软件开发培训哪家好
idcx86服务器出货量
用友互联网科技有限公司
苏州c语言软件开发大概要多少钱
大数据分析服务器linux分区
网络安全领域军民融合
y str数据库
linux云服务器管理系统
网络安全和信息化部招聘
除tcmsp数据库外
数据库应用技术面试题
陕西mes软件开发
软件开发学习哪些算法
京东网络安全论文
英雄联盟服务器停止响应怎么办
方舟生存进化末日生存服务器
河北java软件开发性价比高