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

postgres中重要的数据结构(五),第1张

概述PostmasterMain()中的process table的初始化后内存结构 已有 620 次阅读 2010-4-8 05:51 |个人分类:postgresql|系统分类:科研笔记|关键词:postmaster,process table,InitProcGloble 上次写完了“Postmaster的Memory Context 初始化内存结构” http://www.sciencenet 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
*/
InitProcglobal(); CreateSharedProcArray(); 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,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,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,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,size);
}

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

if (!found)
{
MemSet(BackendActivityBuffer,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的部分。

至此,结束。 总结

以上是内存溢出为你收集整理的postgres中重要的数据结构(五)全部内容,希望文章能够帮你解决postgres中重要的数据结构(五)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1179689.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存