http://blog.sina.com.cn/s/blog_48c95a190100grf9.html
Postgresql中缓冲区管理主要分为共享缓冲区和管理和本地缓冲区管理两大部分,其中共享缓冲区结构以及管理方法主要定义在文件pgsql/src/backend/storage/buffer/buf_init.c,文件pgsql/src/backend/storage/buffer/buf_table.c,文件pgsql/src/backend/storage/buffer/bufmgr.c和文件pgsql/src/backend/storage/buffer/freelist.c中。
我们首先来看文件pgsql/src/backend/storage/buffer/buf_init.c,这个文件主要就是定义了共享缓冲区管理器的初始化方法。在本地缓冲区管理器部分我们知道缓冲区的组织至少包括三个部分:缓冲区块、缓冲区描述器以及引用计数,共享缓冲区也是一样。在文件的开始就定义了这三个全局变量,唯一跟本地缓冲区不同的地方就是,这里定义的变量名前面都没有Local这个字符串,此外这里引用计数的名称前加了一个Private。
BufferDesc *BufferDescriptors;
char
int32
然后就是一些其他的用于统计信息的计数器变量:
long int
long int
long int
long int
long int
long int
long int
long int
其中包括读缓冲区的次数、缓冲区命中的次数、缓冲区文件的读写次数等等,通过这些统计数据我们就可以计算缓冲区命中率一类的更有意义的数据信息。
void
InitBufferPool(void)
{
是这里没有连同私有引用计数一起分配,函数ShmemInitStruct定义在文件pgsql/src/backend/storage/ipc/shmem.c中,它会根据第一个参数,也就是共享内存数据结构的名称来判断这个结构在共享内存中是否已经存在,如果不存在的话就在共享内存段中分配一个这样的结构,我们稍后会对这个重要的函数进行分析。
话我们就要验证这两个结构都是已经分配的,因为这两个结构肯定是一起分配的,如果一个还存在另一个已经不存在的话就说明共享内存段出了问题。
在这里,和本地缓冲区一样我们通过循环遍历来对缓冲区描述器进行初始化。
冲区块。
指向它的下一个缓冲区块,而最后一个缓冲区块的freeNext域则为FREENEXT_END_OF_LIST。
享缓冲区有一个专门的数据结构类型BufferStrategyControl对缓冲区的替换进行控制,函数StrategyInitialize就是对这个结构类型进行一些初始化的工作。
}
通过上面的分析我们知道InitBufferPool这个函数主要就是实现了对共享缓冲区部分两个重要数据结构的地址分配缓冲区块和缓冲区描述器,其次就是初始化一个专门用于缓冲区替换策略控制的数据结构。在代码的分析中我们已经提到就是InitBufferPool这个函数并没有给缓冲区块一起分配针对缓冲区块的引用计数,所以下面的函数InitBufferPoolAccess就是实现对引用计数的分配的,至于为什么将这两部分分开放在两个函数中还有待进一步探究。
InitBufferPoolAccess(void)
}
文件pgsql/src/backend/storage/buffer/buf_init.c中还有另外一个函数BufferShmemSize,这个函数用来计算缓冲区所需的共享内存的空间大小。
Size
BufferShmemSize(void)
然后将三者相加之后返回,这里也没有将引用计数的空间大小计算在内,这不得不使我们隐约地感到引用计数是不算在共享缓冲区里面的,事实真相有待进一步揭示。
}