暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PostgreSQL特性矩阵解析系列14之Multiple autovacuum workers

1237

概述

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.c
    AutoVacuum时间等信息的结构体信息.
    /* 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数据库内核分析》

    文章转载自CP的PostgreSQL厨房,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

    评论