文章目录
- 前言
- 命令介绍
- 命令参数说明
- 命令处理
- 结尾
前言
本文是基于postgresql 14的代码进行分析解读,演示是在centos8系统上进行。
- 命令介绍
Vacuum 命令主要是进行垃圾回收和analyze;
- 命令参数说明
VACUUM [ ( option [, ...] ) ] [ table_and_columns [, ...] ]
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ]where option can be one of:
FULL [ boolean ]
FREEZE [ boolean ]
VERBOSE [ boolean ]
ANALYZE [ boolean ]
DISABLE_PAGE_SKIPPING [ boolean ]
SKIP_LOCKED [ boolean ]
INDEX_CLEANUP { AUTO | ON | OFF }
PROCESS_TOAST [ boolean ]
TRUNCATE [ boolean ]
PARALLEL integerand table_and_columns is:
table_name [ ( column_name [, ...] ) ]
对于boolean类型,默认是true;
- 命令说明
VACUUM (VERBOSE, ANALYZE) onek; 执行表onek上的 analyze; 如果不指定表,就会对当前数据库的所有表和物化视图都进行vacuum;
VACUUM full onek; 对onek执行vacuum,full选项会释放空闲空间,但是它的执行需要有足够的磁盘空间,在执行过程中会对原表不修改,再新建一个表文件,将有效数据迁移过来,最后再替换表文件,所以需要有更大的磁盘空闲空间;
其它选项:
TRUNCATE 可以指定在清理完垃圾版本后,是否要把文件尾的空闲空间truncate掉;默认是打开的;主要在truncate时,会获取表锁 ACCESS EXCLUSIVE lock,对session正常使用会产生冲突。
DISABLE_PAGE_SKIPPING 是否跳过一些page,默认是跳过。在vm文件中,当整个page都为frozen或对所有事务全可见时,默认就会跳过,避免与session进行竞争使用;
SKIP_LOCKED 如果设置了,就会跳过一些表锁冲突的表,对于分区表,如果指定表有锁冲突,其子表也会跳过。但是对于索引的清理,还是会等待表锁,另外对于analyze,也会等待表锁,因为它要扫描抽样得到的行或分区或类型或外键等;
INDEX_CLEANUP 是否跳过对index的清理,默认auto。当少量dead tuple时,对索引进行清理,代价比得到的好处要大的多,所以此处会进行判断优化。 为了兼容旧版的postgresql 版本,需要设置为ON,因为旧版本中默认是都需要清理。对于需要快速进行事务号回收的情况下,可以设置为OFF,这样可以快速处理,虽然事务号在冻结周期时会自动触发,对于延迟回收也是安全的。
PROCESS_TOAST 是否跳过toast表的处理。主要用于只清理主表时,可以设置为false,默认是打开;
PARALLEL 设置并行vacuum的worker个数,与max_parallel_maintenance_workers 取最小值。主要是提升vacuum中对索引扫描和索引清理的效率,当表中存在多个索引时,就可以并行处理。另外,对于是否要加到并行扫描中,还要看是否大于min_parallel_index_scan_size。
- 命令处理流程
- 执行命令 调用
ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
在这个函数中对命令参数开关进行判断赋值
- Vacuum 参数开关结构体
有对应入参的赋值,也有从统计信息来的临界值
/*
* Parameters customizing behavior of VACUUM and ANALYZE.
*
* Note that at least one of VACOPT_VACUUM and VACOPT_ANALYZE must be set
* in options.
*/
typedef struct VacuumParams
{
bits32 options; /* bitmask of VACOPT_* */
/* freeze 相关的四个参数 */
int freeze_min_age; /* min freeze age, -1 to use default */
int freeze_table_age; /* age at which to scan whole table */
int multixact_freeze_min_age; /* min multixact freeze age, -1 to
* use default */
int multixact_freeze_table_age; /* multixact age at which to scan
* whole table */
bool is_wraparound; /* force a for-wraparound vacuum */
int log_min_duration; /* minimum execution threshold in ms at
* which autovacuum is logged, -1 to use
* default */
VacOptValue index_cleanup; /* Do index vacuum and cleanup */
VacOptValue truncate; /* Truncate empty pages at the end */
/*
* The number of parallel vacuum workers. 0 by default which means choose
* based on the number of indexes. -1 indicates parallel vacuum is
* disabled.
*/
int nworkers;
} VacuumParams;
对于opions的赋值,按位进行,以下定义了各位域代表的含义:
/* flag bits for VacuumParams->options */
#define VACOPT_VACUUM 0x01 /* do VACUUM */
#define VACOPT_ANALYZE 0x02 /* do ANALYZE */
#define VACOPT_VERBOSE 0x04 /* output INFO instrumentation messages */
#define VACOPT_FREEZE 0x08 /* FREEZE option */
#define VACOPT_FULL 0x10 /* FULL (non-concurrent) vacuum */
#define VACOPT_SKIP_LOCKED 0x20 /* skip if cannot get lock */
#define VACOPT_PROCESS_TOAST 0x40 /* process the TOAST table, if any */
#define VACOPT_DISABLE_PAGE_SKIPPING 0x80 /* don't skip any pages */
需要注意的是:
- 基中 VACOPT_VACUUM 和 VACOPT_ANALYZE 不同时存在的,其它标记是存在或为0;
- vacuum是不能并行执行,也就是parrallel worker只能为0;
- 命令具体执行统一调用
void
vacuum(List *relations, VacuumParams *params,
BufferAccessStrategy bstrategy, bool isTopLevel)
这是一个vacuum执行的公共调用,将在lazy/full vacuum中详细介绍
结尾
作者邮箱:[email protected]
如有错误或者疏漏欢迎指出,互相学习。
注:未经同意,不得转载!