当前位置:数据库 > SQLServer >>

PostgreSQL启动过程中的那些事一:初始化TopMemoryContext和ErrorContext

1先上个示意图,看一下函数调用过程梗概,中间略过部分细节

 

\

 

前面标1的是初始化TopMemoryContext

前面标2的是初始化ErrorContext

初始化TopMemoryContext和ErrorContext的方法调用过程图

 

2初始化TopMemoryContext的过程

话说main()->…->PostmasterMain()->…->MemoryContextInit()->AllocSetContextCreate()(以后用“->”表示调用),AllocSetContextCreate()函数主要是初始化AllocSet类型的变量,AllocSet的类型是“AllocSetContext*”,AllocSetContext是结构,定义见下面,也就是说,AllocSetContextCreate()函数主要是初始化AllocSetContext类型的变量。

在MemoryContextInit()函数中,一上来就是下面这句,调用AllocSetContextCreate初始化TopMemoryContext。

 

     TopMemoryContext =AllocSetContextCreate((MemoryContext) NULL,

                                      "TopMemoryContext",0,8 * 1024, 8 * 1024);

TopMemoryContext是个全局变量,定义如下

MemoryContext TopMemoryContext = NULL;

从MemoryContextInit()函数调用过来初始化Memorycontext类型的全局变量TopMemoryContext,不是AllocSetContextCreate()函数主要是初始化AllocSetContext类型的变量吗,怎么又初始化上Memorycontext类型的全局变量TopMemoryContext了呢,先卖个关子,容后再说。这是PostgresSQL(以后简称pg)一个比较秒的地方,也涉及了后面用到的面向过程编程的一个技巧。

TopMemoryContext这个全局变量在pg有至关重要,统领全局的地位,以后自然明白。

 

AllocSetContext定义如下:

typedef struct AllocSetContext

{

         MemoryContextData header;  /* Standardmemory-context fields */

         /* Info aboutstorage allocated in this context: */

         AllocBlock blocks;                         /* head of list of blocks in this set */

         AllocChunk        freelist[ALLOCSET_NUM_FREELISTS];             /* free chunk lists */

         bool           isReset;               /* T = no space allocedsince last reset */

         /* Allocationparameters for this context: */

         Size            initBlockSize;      /* initial blocksize */

         Size            maxBlockSize;   /* maximum blocksize */

         Size            nextBlockSize;   /* next block sizeto allocate */

         AllocBlock keeper;                        /* if not NULL, keep this block over resets */

}AllocSetContext;

 

AllocSetContext中有三个变量的类型分别是MemoryContextData、AllocBlock、AllocChunk,这些类型是pg管理AllocSet和MemoryContext涉及内存机制的主要元素,搭起pg管理AllocSet和MemoryContext涉及的内存的架构,后面会逐个提到。

 

在AllocSetContextCreate()函数中,刚声明一个AllocSet类型的变量conext,马上就调用MemoryContextCreate()函数,代码见下。MemoryContextCreate()函数从名字就能看出来是创建MemoryContext的,创建一个MemoryContext类型的值后返回,返回后做了类型强制转换为AllocSet赋给context。调用MemoryContextCreate()函数创建MemoryContext时传的第二个参数是要创建类型的大小,这里取的就是AllocSetContext的大小,而不是MemoryContext的大小。

     AllocSet context;

     context = (AllocSet) MemoryContextCreate(T_AllocSetContext,

                        sizeof(AllocSetContext), &AllocSetMethods,parent, name);

 

MemoryContextCreate()函数主要是初始化MemoryContext,MemoryContext的类型是“MemoryContextData *”,MemoryContextData是个结构,定义见下面。

typedef struct MemoryContextData

{

         NodeTag           type;                            /* identifies exact kind of context */

         MemoryContextMethods *methods;                   /*virtual function table */

         MemoryContext parent;            /* NULL ifno parent (toplevel context) */

         MemoryContext firstchild; /* head of linkedlist of children */

         MemoryContext nextchild;        /* next childof same parent */

         char    *name;                            /* context name (just for debugging) */

}MemoryContextData;

MemoryContextCreate()函数的简化代码如下,主要是声明一个MemoryContext类型的局部变量node,分配内存并初始化。注意,这时还没有初始化TopMemoryContext,所以node的内存空间是malloc出来的。MemoryContext类型的局部变量node初始化完后返回。

 

MemoryContext

MemoryContextCreate(NodeTag tag, Size size,

                       MemoryContextMethods*methods,

                       MemoryContextparent,

                       const char *name)

{

     MemoryContext node;

     Size     needed = size + strlen(name) + 1;

     if(TopMemoryContext == NULL)

     {

         /*Special case for startup: use good ol' malloc */

       &nbs

CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,