openGauss autovacuum autoanalyze代码走读

部分数据结构变量

struct WorkerInfoData:

表示一个avcworker的结构体,存放了avcworker的一些信息、工作状态等。内部有一个SHM_QUEUE,可以将一批worker连城一个双链表。


t_thrd.autovacuum_cxt.DatabaseList :
AVClauncher的一个双链表,存放了数据库列表,且顺序能表示某种时间的old?来源与pgstats相关。


t_thrd.autovacuum_cxt.AutoVacuumShmem :
一块共享内存,存放一些avc的全局信息,包括一些槽位、状态等。受AutovacuumLock保护。luncher与avcworker通过这几个槽位进行信息传递,其中主要的几个槽位有:

  • av_freeWorkers:空闲的worker,是个队列。

  • av_startingWorker:正在启动的worker。在这里只当成一个元素用,所以worker的启动只能是串行的,可能这样子比较安全或者实现比较简单吧。

  • av_runningWorkers:正在运行的worker,是个队列。

t_thrd.autovacuum_cxt.MyWorkerInfo:
当前worker自己的信息,存放例如正在vacuum的表。受AutovacuumScheduleLock保护。

AVClauncher 线程:AutoVacLauncherMain()

      AutoVacuumingActive(),如果没有开启autovcacuum或track_count的话,则退出。
       
      rebuild_database_list(): 维护 t_thrd.autovacuum_cxt.DatabaseList,也是数据库的vacuum顺序。
       
       
           
          launcher_determine_sleep()   计算sleep时间。要考虑是不是有空闲的worker,有可能所有worker都干不完活。如果没有就得多睡会。
           WaitLatch 间隔sleep
           ResetLatch
           
          t_thrd.autovacuum_cxt.got_SIGHUP: 配置重加载
           
           
          t_thrd.autovacuum_cxt.got_SIGUSR2:两种作用,1、avcworker完成工作通知,2、pm启动线程avcworker失败通知。然后进行相关的处理。
           
           
           LWLockAcquire(AutovacuumLock, LW_SHARED);
           if (t_thrd.autovacuum_cxt.AutoVacuumShmem->av_startingWorker != NULL) {
               判断是不是有正在启动的avcworker。如果有且是启动时间过长的话,就LW_EXCLUSIVE,取消掉。直接重置相关槽位。
           LWLockRelaese(AutovacuumLock);
           
           如果没有 av_freeWorkers ,(同时还不能有正在启动的avcworker),全都在忙,就continue。
           
           
          launch_worker(current_time) :启动一个worker {
              dbid = do_start_worker() :启动一个worker {
                   刷新avc的统计计数信息。
                   dblist = get_database_list();
                   获取xidForceLimit,multiForceLimit。受参数autovacuum_freeze_max_age控制,表示一个事务号最多只能活多久,超过这个年龄,就得被冻结或清理。
                   
                   
                  avdb:根据dblist、DatabaseList、xidForceLimit等,选出来一个最近最少avc的或需要循环clog的、还得有统计信息的、扒拉扒拉的。
                   
                   
                  LOCK,在av_freeWorkers取出一个worker变成av_startingWorker,并将avdb、时间等信息传给特。RELEASE
                  SendPostmasterSignal(PMSIGNAL_START_AUTOVAC_WORKER): 发送信号给pm进行启动。
                   
                   返回选中的avdb的oid。
               }
               
               
               遍历DatabaseList,把对应dbid的元素信息更新,并移到链表最头上。
               
           }
           
    <br>