微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

postgresql存储引擎源码分析一

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

typedefPageHeaderData *PageHeader;

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

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

{

PageHeaderp = (PageHeader) page;

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

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

MemSet(p,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.

}

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

姓名:鲁笛 主题:存储系统之缓冲区页面描述

原文地址:https://www.jb51.cc/postgresql/194941.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐