postgres中重要的数据结构(五)

PostmasterMain()中的process table的初始化后内存结构

已有 620 次阅读 2010-4-8 05:51 |个人分类:postgresql|系统分类:科研笔记|关键词:postmaster,process table,InitProcGloble

上次写完了“Postmaster的Memory Context 初始化内存结构” http://www.sciencenet.cn/m/user_content.aspx?id=308964,接下来我们看看初始化process table 部分。
Postmaster在PostmasterMain()->reset_shared()->CreateSharedMemoryAndSemaphores()中初始化process table的主要函数为:
    /*
     * Set up process table
     */
  1. InitProcGlobal();
  2. CreateSharedProcArray();
  3. CreateSharedBackendStatus();
我们可以猜想一下,对于接下来PostmasterMain马上要fork的postgres的进程中肯定是用到这些函数初始化的数据结构的。我们来一一分析一下。

1.InitProcGlobal()
void InitProcGlobal(void)
{
    PGPROC       *procs;
    int            i;
    bool        found;

    /* Create the ProcGlobal shared structure */
    ProcGlobal = (PROC_HDR *)
        ShmemInitStruct("Proc Header", sizeof(PROC_HDR), &found);
    Assert(!found);

    /*
     * Create the PGPROC structures for auxiliary (bgwriter) processes, too.
     * These do not get linked into the freeProcs list.
     */
    AuxiliaryProcs = (PGPROC *)
        ShmemInitStruct("AuxiliaryProcs", NUM_AUXILIARY_PROCS * sizeof(PGPROC),
                        &found);
    Assert(!found);

    /*
     * Initialize the data structures.
     */
    ProcGlobal->freeProcs = NULL;
    ProcGlobal->autovacFreeProcs = NULL;

    ProcGlobal->spins_per_delay = DEFAULT_SPINS_PER_DELAY;

    /*
     * Pre-create the PGPROC structures and create a semaphore for each.
     */
    procs = (PGPROC *) ShmemAlloc((MaxConnections) * sizeof(PGPROC));
    if (!procs)
        ereport(FATAL,
                (errcode(ERRCODE_OUT_OF_MEMORY),
                 errmsg("out of shared memory")));
    MemSet(procs, 0, MaxConnections * sizeof(PGPROC));
    for (i = 0; i < MaxConnections; i++)
    {
        PGSemaphoreCreate(&(procs[i].sem));
        procs[i].links.next = (SHM_QUEUE *) ProcGlobal->freeProcs;
        ProcGlobal->freeProcs = &procs[i];
    }

    procs = (PGPROC *) ShmemAlloc((autovacuum_max_workers) * sizeof(PGPROC));
    if (!procs)
        ereport(FATAL,
                (errcode(ERRCODE_OUT_OF_MEMORY),
                 errmsg("out of shared memory")));
    MemSet(procs, 0, autovacuum_max_workers * sizeof(PGPROC));
    for (i = 0; i < autovacuum_max_workers; i++)
    {
        PGSemaphoreCreate(&(procs[i].sem));
        procs[i].links.next = (SHM_QUEUE *) ProcGlobal->autovacFreeProcs;
        ProcGlobal->autovacFreeProcs = &procs[i];
    }

    MemSet(AuxiliaryProcs, 0, NUM_AUXILIARY_PROCS * sizeof(PGPROC));
    for (i = 0; i < NUM_AUXILIARY_PROCS; i++)
    {
        AuxiliaryProcs[i].pid = 0;        /* marks auxiliary proc as not in use */
        PGSemaphoreCreate(&(AuxiliaryProcs[i].sem));
    }

    /* Create ProcStructLock spinlock, too */
    ProcStructLock = (slock_t *) ShmemAlloc(sizeof(slock_t));
    SpinLockInit(ProcStructLock);
}
纵观其中的代码, ProcGlobal->freeProcs = &procs[i]; 是我们比较感兴趣的。因为其他的初始化例如autovacuum类似的辅助进程我们暂时还不怎么关注。初始化的结果就是把这些结构用next指针给链接起来,本身不复杂。

2.CreateSharedProcArray()
void CreateSharedProcArray(void){
    bool        found;

    /* Create or attach to the ProcArray shared structure */
    procArray = (ProcArrayStruct *)
        ShmemInitStruct("Proc Array", ProcArrayShmemSize(), &found);

    if (!found)
    {
        /*
         * We're the first - initialize.
         */
        procArray->numProcs = 0;
        procArray->maxProcs = MaxBackends + max_prepared_xacts;
    }
}
比较关键的代码已用红色标出,注意procArray的定义:
typedef struct ProcArrayStruct
{
    int            numProcs;        /* number of valid procs entries */
    int            maxProcs;        /* allocated size of procs array */

    /*
     * We declare procs[] as 1 entry because C wants a fixed-size array, but
     * actually it is maxProcs entries long.
     */
    PGPROC       *procs[1];        /* VARIABLE LENGTH ARRAY */
} ProcArrayStruct;

static ProcArrayStruct *procArray;
很简单,无需解释。

3.CreateSharedBackendStatus()
void CreateSharedBackendStatus(void){
    Size        size;
    bool        found;
    int            i;
    char       *buffer;

    /* Create or attach to the shared array */
    size = mul_size(sizeof(PgBackendStatus), MaxBackends);
     BackendStatusArray = (PgBackendStatus *)
        ShmemInitStruct("Backend Status Array", size, &found);

    if (!found)
    {
        /*
         * We're the first - initialize.
         */
        MemSet(BackendStatusArray, 0, size);
    }

    /* Create or attach to the shared activity buffer */
    size = mul_size(pgstat_track_activity_query_size, MaxBackends);
     BackendActivityBuffer = (char *)
        ShmemInitStruct("Backend Activity Buffer", size, &found);

    if (!found)
    {
        MemSet(BackendActivityBuffer, 0, size);

        /* Initialize st_activity pointers. */
        buffer = BackendActivityBuffer;
        for (i = 0; i < MaxBackends; i++)
        {
            BackendStatusArray[i].st_activity = buffer;
            buffer += pgstat_track_activity_query_size;
        }
    }
}
主要初始化了 BackendStatusArray和 BackendActivityBuffer,并让 BackendStatusArray各项指向 BackendActivityBuffer中的各项。

这样,我们分析结束了,结论就是其实这一部分的初始化,基本上没有设定具体数据结构的值,只是把大体框架给列在那里了。
最后,我给出初始化之后在内存中的表示,图有点大的吓人,不过你可以略去shared buffer和shared memory的部分。

至此,结束。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值