PostgreSQL存储引擎源码分析二(原创,不断更新)
上次我分析了PostgreSQL存储系统页面管理的页面初始化函数PageInit,接下来的工作量相当大,由于源码有几十万行,如果像上次一样逐条语句分析的话,那么整体的篇幅是相当巨大的,语言也不容易组织。因此接下来的工作我准备对于每一个.c或者.h文件 的每个数据结构以及函数等整体代码块作出整体分析。下面我来对backend/storage/page/bufpage.c 中的剩余函数进行分析:
紧接着的函数声明是bool PageHeaderIsValid(PageHeader page),从其声明就可以看出这个函数的功能是验证页面首部page是否有效。具体的实现原理是:如果page的长度与定义的宏BLCKSZ相等并且page的版本号与宏PG_PAGE_LAYOUT_VERSION相等并且page的pd_lower,pd_upper,pd_special均合法的话。返回true,否则验证page的每一个比特位,如果全为0,说明这是一个刚初始化的页首部,返回true,否则,页首部无效,返回false。
下面的函数比较长,有150多行。函数声明是OffsetNumber PageAddItem(Page page,Item, item,OffsetNumber offsetNumber,bool overwirte,bool is_heap) 这个函数的功能将元组项item添加到页面page当中并返回item在page中的偏移量,OffsetNumber是一个16位无符号整型数据,offsetNumber参数是一个偏移量,可能是由调用者生成的元组添加位置索引。这个函数的实现原理是:首先会检查要操作的页面page是否是合法的页面,如果不合法,将报错并退出函数。接着定义一个变量limit存储page的剩余空间大小。接下来验证offsetNumber是否有效,有效的话便验证overwrite参数是否为真,如果为真便验证offsetNumber参数是否小于limit,成立的话便取得page当中offsetNumber位置的元组项的id,如果这个元组项已经被使用,那么报错,返回IvalidOffsetNumber宏,函数退出。如果overwirte参数为假且offsetNumber小于limit,置变量needshuffle为true。如果offsetNumber参数无效,那么就要自己寻找要添加位置的偏移量了,从page中遍历,找到一个没有使用到的item,那么offsetNumber的值便为这个item的偏移量,如果offsetNumber大于limit的话,那么返回IvalidOffsetNumber。接下来便设置lower,upper变量,从添加位置offsetNumber中取出page在这个位置上的元组项item。设定这个item的大小,偏移量参数。接着使用memcpy函数将这个item添加到page当中,返回offsetNumber,函数结束。
接下来是三个很相似的函数,Page PageGetTempPage(Page page),它的功能是返回本地内存中的一个临时的页面,但是返回的页面分配了与page大小相同的物理空间,但是确没有对临时页面初始化,第二个函数声明是Page PageGetTempPageCopy(Page page),它的功能同第一个函数,也是返回本地内存的一个临时页面。但是与第一个函数的区别在于,返回的这个临时页面是参数page页面的一个拷贝页面,第三个函数是Page PageGetTempPageCopySpecial(Page page),功能与函数一,二类似,不同点在于这个函数返回的页面的特殊空间部分是参数page的特殊空间的拷贝。
今天的分析就到这里,希望其他同学给予意见,修改。
姓名:鲁笛 主题:缓冲区页面描述二