接着上期说,第二个问题 autovacuum 到底做了什么,可以总结为四点
1 删除或重用无效元组的磁盘空间
2 更新数据统计信息,提高执行计划的效率
3 更新visibility map
4 方式数据库回卷造成数据库进入单机模式
下面我们通过autovacuum launcher 进行切入, autovacuum launcher 是一个postgresql的外部进程,通过他来定期拉起 autovacuum worker 的线程来进行工作。
下面我们对autovacuum.c 源码部分进行简略的阅读, 在阅读之前我们将重点进行罗列方便后面理解
1 autovacuum 本身是通过两个进程来完成的, autovacuum launcher 和 autovacuum worker 组成
2 autovacuum launcher 是守护进程,autovacuum worker 是实际进行工作的进程。
3 autovacuum launcher 本身是寄存在 share buffer 内存结构中的,所以他必须通过postmaster 主进程进行拉起
4 autovacuum worker 本身是通过autovacuum launcher 守护进程拉起的,在worker 完成工作后,会发出sigusr2 信号,同时 launcher 本身也会根据参数来调配 worker的启动时机
5 autovacuum 整体会在工作的过程中将正在整理的表放入share memory中,所以启动多个 worker时不会引起系统的多 worker 整理同一个表的情况,在整理表之前也会查询表中的状态,不会对一个表重复多次的进行整理。
我们从源代码开始看, 一开始代码中会对autovacuum 中的参数进行初始化。
下面是autovacuum 的两个部分 1 launcher 2 worker
在autovacuum 中在整理表之前需要拿到表的状态,同时在表整理之后也需要在重新检查表的状态
主要autovacuum 工作的代码
其中也可以窥见autovacuum 在工作的过程中,的确是有进行表的 analyze的工作
这一段代码是postgresql autovacuum 中 launcher 定时拉起autovacuum worker的代码。
下面这些代码是针对表进行vacuum 的源代码
从代码中我们可以看到上一篇中提到的
1 autovacuum 本身是通过 launcher 运行并定时拉起 autovacuum worker 来进行工作的。
2 autovacuum 工作会获取数据库的列表以及表的列表,并且根据当前自己有的autvacuum worker的线程进行工作的分配
3 autovacuum 会进行初始化,在整理前获得表的状态,并保存在内存结构体(share buffer), 同时在执行结束后会在此检查表的状态并记录到内存的结构体中。
4 初始化的过程中会对autovacuum的参数进行初始化和读取
autovacuum_start_daemon = false;
autovacuum_max_workers;
autovacuum_naptime;
autovacuum_vac_thresh;
autovacuum_vac_scale;
autovacuum_anl_thresh;
autovacuum_anl_scale;
autovacuum_freeze_max_age;
autovacuum_vac_cost_delay;
autovacuum_vac_cost_limit;
Log_autovacuum_min_duration = -1;