PostgreSQL在VFD管理上是一套还是多套

VFD是为了解决文件句柄的限制,防止把OS级别的文件句柄用光。

原来我认为VFD是各个进程间共有的。但是根据观察,发现每一个进程都拥有自己的VFD数组指针。

看看下面两段加了调试信息后的代码:

InitFileAccess:

从 VfdCache = (Vfd *) malloc(sizeof(Vfd)) 基本可以断定,没有使用共享内存方式

/*

 * InitFileAccess --- initialize this module during backend startup

 *

 * This is called during either normal or standalone backend start.

 * It is *not* called in the postmaster.

 */

void

InitFileAccess(void)

{



    fprintf(stderr,"In %s ...by Process %d\n", __FUNCTION__,getpid());

    fprintf(stderr,"----------------------------------------------------\n\n");



    Assert(SizeVfdCache == 0);    /* call me only once */



    /* initialize cache header entry */ VfdCache = (Vfd *) malloc(sizeof(Vfd)); if (VfdCache == NULL)

        ereport(FATAL,

                (errcode(ERRCODE_OUT_OF_MEMORY),

                 errmsg("out of memory")));



    MemSet((char *) &(VfdCache[0]), 0, sizeof(Vfd));

    VfdCache->fd = VFD_CLOSED;



    SizeVfdCache = 1;



    /* register proc-exit hook to ensure temp files are dropped at exit */

    on_proc_exit(AtProcExit_Files, 0);

}

AllocateVfd:

会因为扩充内存结构数组的需要,进行 realloc,这导致 VfdCache指针的值会在进程的范畴里发生变化。

static File

AllocateVfd(void)

{

    Index        i;

    File        file;



    DO_DB(elog(LOG, "AllocateVfd. Size %lu", SizeVfdCache));

    Assert(SizeVfdCache > 0);    /* InitFileAccess not called? */



    if (VfdCache[0].nextFree == 0)

    {

        /*

         * The free list is empty so it is time to increase the size of the

         * array.  We choose to double it each time this happens. However,

         * there's not much point in starting *real* small.

         */

        Size        newCacheSize = SizeVfdCache * 2;

        Vfd           *newVfdCache;



        if (newCacheSize < 32)

            newCacheSize = 32;



        /*

         * Be careful not to clobber VfdCache ptr if realloc fails.

         */ newVfdCache = (Vfd *) realloc(VfdCache, sizeof(Vfd) * newCacheSize); if (newVfdCache == NULL) ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"))); VfdCache = newVfdCache;     ...



    file = VfdCache[0].nextFree;

    VfdCache[0].nextFree = VfdCache[file].nextFree;

    return file;

}

PathNameOpenFile:

/*

 * open a file in an arbitrary directory

 *

 * NB: if the passed pathname is relative (which it usually is),

 * it will be interpreted relative to the process' working directory

 * (which should always be $PGDATA when this code is running).

 */

File

PathNameOpenFile(FileName fileName, int fileFlags, int fileMode)

{

    char       *fnamecopy;

    File        file;

    Vfd           *vfdP;



    DO_DB(elog(LOG, "PathNameOpenFile: %s %x %o",

               fileName, fileFlags, fileMode));



    /*

     * We need a malloc'd copy of the file name; fail cleanly if no room.

     */

    fnamecopy = strdup(fileName);

    if (fnamecopy == NULL)

        ereport(ERROR,

                (errcode(ERRCODE_OUT_OF_MEMORY),

                 errmsg("out of memory")));



    //VfdCache

    fprintf(stderr,"In %s ...by Process %d...", __FUNCTION__,getpid());

    fprintf(stderr,"VfdCache Address is: %p \n\n +++++++++++++++++++++++++++++++++++\n",VfdCache);



    file = AllocateVfd();

    vfdP = &VfdCache[file];

    ...

    return file;

}

实际运行的结果如下(开两个psql客户端,一个pid为 6518,另一个为6584):

+

In BaseInit ...by Process 6518

In InitFileAccess ...by Process 6518

----------------------------------------------------



In PathNameOpenFile ...by Process 6518...VfdCache Address is: 0x10dfff50 



 +++++++++++++++++++++++++++++++++++

In PathNameOpenFile ...by Process 6518...VfdCache Address is: 0x10e9c450 



 +++++++++++++++++++++++++++++++++++

In PathNameOpenFile ...by Process 6518...VfdCache Address is: 0x10e9c450 



 +++++++++++++++++++++++++++++++++++

In PathNameOpenFile ...by Process 6518...VfdCache Address is: 0x10e9c450 



 +++++++++++++++++++++++++++++++++++

In PathNameOpenFile ...by Process 6518...VfdCache Address is: 0x10e9c450 



 +++++++++++++++++++++++++++++++++++

In PathNameOpenFile ...by Process 6518...VfdCache Address is: 0x10e9c450 



 +++++++++++++++++++++++++++++++++++

In PathNameOpenFile ...by Process 6518...VfdCache Address is: 0x10e9c450 



 +++++++++++++++++++++++++++++++++++

In PathNameOpenFile ...by Process 6518...VfdCache Address is: 0x10e9c450 



 +++++++++++++++++++++++++++++++++++

In PathNameOpenFile ...by Process 6518...VfdCache Address is: 0x10e9c450 



 +++++++++++++++++++++++++++++++++++

In PathNameOpenFile ...by Process 6518...VfdCache Address is: 0x10e9c450 



 +++++++++++++++++++++++++++++++++++

In PathNameOpenFile ...by Process 6518...VfdCache Address is: 0x10e9c450 



 +++++++++++++++++++++++++++++++++++

In PathNameOpenFile ...by Process 6518...VfdCache Address is: 0x10e9c450 



 +++++++++++++++++++++++++++++++++++

In PathNameOpenFile ...by Process 6518...VfdCache Address is: 0x10e9c450 



 +++++++++++++++++++++++++++++++++++

In PathNameOpenFile ...by Process 6518...VfdCache Address is: 0x10e9c450 



 +++++++++++++++++++++++++++++++++++

In PathNameOpenFile ...by Process 6518...VfdCache Address is: 0x10e9c450 





In BaseInit ...by Process 6584

In InitFileAccess ...by Process 6584

----------------------------------------------------



In PathNameOpenFile ...by Process 6584...VfdCache Address is: 0x10e04e00 



 +++++++++++++++++++++++++++++++++++

In PathNameOpenFile ...by Process 6584...VfdCache Address is: 0x10ecaad0 

两个进程里面的 VfdCache 地址是不同的。

我想,可能是出于效率的原因,各进程各自保持VFD指针。

你可能感兴趣的:(PostgreSQL)