概述
allows the autovacuum daemon to operate on multiple tables concurrently.
允许autovacuum守护进程同时对多个表进行操作。
PostgreSQL8.3版本增强功能。

在“自动清理守护进程”实际上是由多个进程。有一个持久的守护进程,称为autovacuum启动程序,负责启动所有数据库的autovacuum工作进程。以上文字翻译自官方文档O(∩_∩)O
守护进程who?autovacuum launcher 
autovacuum launcher
autovacuum launcher 进程可以理解为AutoVacuum机制的守护进程,周期性地调度autovacuum worker进程。
autovacuum launcher 进程在postgresql.conf文件中的相关配置参数(支持对每个表单独配置参数)如下:
track_counts:是否开启统计信息收集功能。
autovacuum:是否启动系统自动清理功能,默认值为on。
autovacuum_max_workers:设置系统自动清理工作进程的最大数量。
autovacuum_naptime:设置两次系统自动清理操作之间的间隔时间。
autovacuum_vacuum_cost_limit:声明将在自动VACUUM操作里使用的开销限制数值。
autovacuum_vacuum_cost_delay :声明如果超过了上面的开销限制,则需要延迟清理的时间。
autovacuum_freeze_max_age:设置需要强制对数据库进行清理的XID上限值。
autovacuum_multixact_freeze_max_age:设置需要强制对数据库进行清理的multi XID上限值。
因为AutoVacuum依赖于统计信息,所以只有track_counts=on 且 autovacuum=on 时,PostgreSQL才启动autovacuum launcher 进程。
autovacuum launcher 进程会周期性地创建autovacuum worker 进程,最多能够创建autovacuum_max_workers个autovacuum worker 进程。
源码导读

下面对其中几个重要的步骤进行说明:
1)构建数据库列表:调用函数rebuild_database_list完成,其步骤如下:
①建立一个Hash表,其中每一个元素代表一个数据库,记录了该数据库的OID(adl_datid)、启动worker的时间戳(adl_next_worker)以及一个评分值(adl_score)。初始时该Hash表中没有元素。
②将pg_database平面文件(在PGDATA/global目录下)中的数据库构成一个链表,链表中的每一个节点代表一个数据库,其中包括数据库的OID、名称、该数据库的统计信息等。
③调用pgstat_fetch_stat_dbentry来填充每个节点的统计信息。
④对每一个统计信息不为空的数据库,在Hash表中搜索该数据库,如果没有找到则将该数据库加入到Hash表中,并且将该数据库的adl_score设置为该数据库被加入到Hash表中时的顺序号。
⑤将Hash表中的数据库按照adl_score值升序的顺序依次加入到全局变量DatabaseList所指向的链表中,并设置每一个数据库的adl_next_worker值。其中第一个数据库的adl_next_worker值设为当前时间,之后的每一个数据库的adl_next_worker的值都比前一个增加millis_increment。millis_increment的值由autovacuum_naptime参数值除以Hash表中数据库的个数来设定。
src/backend/postmaster/autovacuum.cAutoVacuum时间等信息的结构体信息./* struct to keep track of databases in launcher */typedef struct avl_dbase{Oid adl_datid; /* hash key -- must be first */TimestampTz adl_next_worker;int adl_score;dlist_node adl_node;} avl_dbase;adl_node 表示该avl_dbase对应的在列表中的位置信息struct dlist_node{dlist_node *prev;dlist_node *next;};autovacuum launcher可以启动最多autovacuum_max_workers个autovacuum worker 进程。为了管理autovacuum worker 进程,PostgreSQL维护了共享内存AutoVacuumShmemStruct来存储当前所有autovacuum worker的情况typedef struct{sig_atomic_t av_signal[AutoVacNumSignals];pid_t av_launcherpid;dlist_head av_freeWorkers;dlist_head av_runningWorkers;WorkerInfo av_startingWorker;AutoVacuumWorkItem av_workItems[NUM_WORKITEMS];} AutoVacuumShmemStruct;WorkerInfoData 列表/*-------------* This struct holds information about a single worker's whereabouts. We keep* an array of these in shared memory, sized according to* autovacuum_max_workers.** wi_links entry into free list or running list* wi_dboid OID of the database this worker is supposed to work on* wi_tableoid OID of the table currently being vacuumed, if any* wi_sharedrel flag indicating whether table is marked relisshared* wi_proc pointer to PGPROC of the running worker, NULL if not started* wi_launchtime Time at which this worker was launched* wi_cost_* Vacuum cost-based delay parameters current in this worker** All fields are protected by AutovacuumLock, except for wi_tableoid which is* protected by AutovacuumScheduleLock (which is read-only for everyone except* that worker itself).*-------------*/typedef struct WorkerInfoData{dlist_node wi_links;Oid wi_dboid;Oid wi_tableoid;PGPROC *wi_proc;TimestampTz wi_launchtime;bool wi_dobalance;bool wi_sharedrel;int wi_cost_delay;int wi_cost_limit;int wi_cost_limit_base;} WorkerInfoData;
参考
https://www.postgresql.org/about/featurematrix/#backend
《PostgreSQL数据库内核分析》




