- 专栏内容: postgresql内核源码分析
- 个人主页:senllang的主页
- 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.
文章目录
- 前言
- 概要介绍
- 入口函数
- 清理数据流程
- analyze流程
- 事务号冻结流程
- 结尾
前言
本文是基于postgresql 15的代码进行分析解读,演示是在centos8系统上进行。
-
一.概要介绍
postgresql的MVCC机制,在update时会产生新旧版本,而且存储在表文件中,导致表数据膨胀,影响查询扫描的效率。vacuum的引入就是定期对deadtuple的清理,所谓deadtuple,对所有事务来说都是过期版本。
下面详细介绍vacuum具体做那些事情,以及如何来展,在清理过程中又是怎么避免与业务的冲突。
-
二.入口函数
- 以多种形式执行vacuum,如sql命令,vacuumdb命令,还有后台自动执行的autovacuum服务,它们经过各自己的包装处理后,都由vacuum()来统一处理
void
vacuum(List *relations, VacuumParams *params,
BufferAccessStrategy bstrategy, bool isTopLevel)
-
参数说明
- relations ,待处理的relation列表,如果为空,就处理当前数据库的所有表;
- params,记录执行vacuum的参数,主要是行为的可选,如是否为full, 是否跳过冲突的page等等,详细说明参见 vacuum命令的分析;
- bstrategy, 在autovacuum时会传入,其它情况下都为NULL
- isTopLevel,由 ProcessUtility 调用时传入 ,istopleve取值如下:
typedef enum
{
PROCESS_UTILITY_TOPLEVEL, /* toplevel interactive command */
PROCESS_UTILITY_QUERY, /* a complete query, but not toplevel */
PROCESS_UTILITY_QUERY_NONATOMIC, /* a complete query, nonatomic
* execution context */
PROCESS_UTILITY_SUBCOMMAND /* a portion of a query */
} ProcessUtilityContext;
-
函数流程
- 检查事务,对于analyze是需在处在事务中,对于vacuum,不能已经处于事务中,因为它自己会启动事务;
- 检查表列表,如果没有指定,获取所有表的列表
- 分配全局内存上下文,可能会多次使用;
static MemoryContext vac_context = NULL;
static BufferAccessStrategy vac_strategy;
- 如果使用自己的事务,就需要结束backend启动时的事务;
- vacuum的 表的vacuum和analyze整个处理放在 try…catch 当中,具有原子操作
- 在上面处理结束后,进行事务号冻结处理
- 最后释放内存上下文,结束处理
-
三.清理数据流程
- 处理函数为 vacuum_rel
- 参数说明
- OID, 待处理的relation OID
- relation RangeVar类型,对应OID的表信息
typedef struct RangeVar
{
NodeTag type;
/* the catalog (database) name, or NULL */
char *catalogname;
/* the schema name, or NULL */
char *schemaname;
/* the relation/sequence name */
char *relname;
/* expand rel by inheritance? recursively act on children? */
bool inh;
/* see RELPERSISTENCE_* in pg_class.h */
char relpersistence;
/* table alias & optional column aliases */
Alias *alias;
/* token location, or -1 if unknown */
int location;
} RangeVar;
前两个参数都是从VacuumRelation结构体中得来,也就是relation的List;
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;
- 启动事务
- 处理vacuum ,分两种类型
- Layze vacuum 由 table_relation_vacuum执行,由SQL命令和autovacuum触发
static inline void
table_relation_vacuum(Relation rel, struct VacuumParams *params,
BufferAccessStrategy bstrategy)
在执行时,持有表锁为 ShareUpdateExclusive lock
- Full vacuum 由 cluster_rel 执行
/* VACUUM FULL is now a variant of CLUSTER; see cluster.c */
void cluster_rel(Oid tableOid, Oid indexOid, ClusterParams *params);
在执行时,执有最高级别表锁
-
四.analyze流程
- 处理函数为 analyze_rel
-
五.事务号冻结流程
- 处理函数为 vac_update_datfrozenxid
结尾
作者邮箱:[email protected]
如有错误或者疏漏欢迎指出,互相学习。
注:未经同意,不得转载!