您的位置:首页 > 数据库

PostgreSQL存储引擎源码分析一(不断更新)

2010-01-16 16:27 567 查看
PostgreSQL的存储系统作为PostgreSQL的最低层,向下通过操作系统系统接口访问物理数据,向上为存取系统提供由缓冲区页面及页面上的接口函数。

存储系统的总体架构如下图所示(转自贵州大学硕士黄崇争毕业论文“开放源代码DBMS的分析,比较”)


注释:Lock Manager是锁管理器,IPC是进程间通信,他们实现了存取层对存储层的互斥访问,操作。

存储系统各子系统功能如下:

Page Manager:对缓冲区页面的结构进行定义并提供页面的相关操作。

Buffer Manager:对共享缓冲区和本地缓冲区进行管理。

Storage Manager:屏蔽不同物理设备接口函数的差异,向Buffer Manager提供统一的接口。

File Manager:一般的操作系统只允许一个进程打开256个文件,而PostgreSQL服务器在工作时需要打开的文件会很多,因此,其使用File Manager来封装操作系统文件读写的函数。

下面对Page Manager的一段代码进行分析:Page Manager模块的功能上面已经讲到过,这里便不再赘述,这个模块主要由三个文件组成:源码根目录下的backend\storage\page路径下的bufpage.c,itemptr.c,以及根目录下include\storage路径的头文件bufpage.h组成。

页面Page的结构大致如下:页面由页首部,页面存储记录的ID,存储的记录以及特殊空间所组成。其中,页面首部定义在bufpage.h文件中。如下所示:

typedef struct PageHeaderData
{
XLogRecPtr pd_lsn; /* XLogRecPtr是定义在/include/access/xlogdefs.h中的一个结构体,定义了存取层所用的日志文件 ,期待其他模块同学的完善。*/
uint16 pd_tli; /* 善未搞明白。。。*/
uint16 pd_flags; /* 页首部标志*/
LocationIndex pd_lower; /* 页面空闲区域起始偏移量 ,LocationIndex 是无符号16位整型数据,下同*/
LocationIndex pd_upper; /* 页面空闲区域结束偏移量 */
LocationIndex pd_special; /* 页面特殊区域起始偏移量 */
uint16 pd_pagesize_version;/* 页面大小*/
TransactionId pd_prune_xid; /* 不重要的XID, 如果为空则为0 */
ItemIdData pd_linp[1]; /* ItemidData是定义在/include/storage/itemid.h中的结构体,主要定义了元组项的底层特征:元组在页面上的偏移量,元组项指针的状态,元组的比特位长度,这里是定义了一个元组项的一个指针,指向页面不同的元组项(也就是记录) */
} PageHeaderData;

typedef PageHeaderData *PageHeader;

下面来分析/backend/storage/page/bufpage.c中的PageInit函数(页面初始化)

void PageInit(Page page,Size pageSize,Size specialSize)

{

PageHeader p = (PageHeader) page;

specialSize = MAXALIGN(specialSize);//MAXALIGN是常量表达式

Assert(pageSize == BLCKSZ);//如果页面大小和磁盘块大小相等的话,函数终止,页面初始化失败
Assert(pageSize > specialSize + SizeOfPageHeaderData);//SizeofPageHeaderData是定义在bufpage.h中的宏,即offsetof(PageHeaderData, pd_linp),功能是获得页面首部中pd_linp数组的偏移量,如果页面大小大于特殊空间大小与偏移量之和的话,函数终止。

MemSet(p, 0, pageSize);//讲页首部初始化,清零。

p->pd_lower = SizeOfPageHeaderData;//初始化页面空闲区域起始偏移量
p->pd_upper = pageSize - specialSize;//初始化页面空闲区域结束偏移量
p->pd_special = pageSize - specialSize;//初始化特殊区域起始偏移量
PageSetPageSizeAndVersion(page, pageSize, PG_PAGE_LAYOUT_VERSION);//设置页面大小以及页面布局的版本号,这是定义在bufpage.h下的一个宏原型为:#define PageSetPageSizeAndVersion(page, size, version) \
( \
AssertMacro(((size) & 0xFF00) == (size)), \
AssertMacro(((version) & 0x00FF) == (version)), \
((PageHeader) (page))->pd_pagesize_version = (size) | (version) \
)里面基本上是一些位操作:将页面大小的后16位置0,版本号的前16为置0.

}

今天就分析到这里,希望大家给出意见,给予改正,谢谢!

姓名:鲁笛 主题:存储系统之缓冲区页面描述
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: