图解PostgreSQL-buffer管理(三)

本文介绍本地缓冲的管理。

1、本地buffer的分配由函数LocalBufferAlloc来完成,用于临时表的读写。

2、同样需要先初始化tagnewTag,唯一标记一个物理页

3、第一次使用临时表时,需要通过calloc创建一系列缓冲区(InitLocalBuffers完成):几个数组,大小为num_temp_buffers,即该变量控制大小。

LocalBufferDescriptors[]:存储本地缓冲块的描述符

LocalBufferBlockPointers[]:本地缓冲块

LocalRefcount[]:每个描述符引用次数

LocalBufHash:用户管理本地缓冲块的hash表,keytagvaluebuffer的数组下标。

4、通过tagLocalBufHash表中查找,看有没有,是否已经加载到内存。

5LocalBufHash表中已存在:

   1)获取其ID,然后获取local buffer的描述符bufHdr

   2)原子操作读出bufHdrstatebuf_state

   3buf_stateusagecount保持为1refcount+1

   4bufBM_VALID,则foundPtrTRUE,表示命中缓冲,否则为false

   5)返回该描述符bufHdr

6LocalBufHash不存在:

   1)通过该值nextFreeLocalBuf遍历本地缓冲区,若超过NlocBuffer值则从头开始遍历

   2LocalRefcount对应的引用值不为0,则返回到1);否则取出其bufHdrstate

   3usagecount=0,表示没有人在用,则LocalRefcount=1后退出循环,进入步骤7

   4usagecount>0,则将usagecount-1后返回1)重新选择下一个

7buf_satateBM_DIRTY,则需要刷脏:

   1)获取具体页localpagesmgropen一个oreln,如打开checksum则计算checksum并写入localpagesmgrwrite将其写入到磁盘;最后将状态置为非BM_DIRTY

8、如果第一次使用本地buffer,则需要调用GetLocalBufferStorage将其挂到TopMemoryContext

9、如果该buffer缓冲区的数据有效,则需要更新hash表:将该tagLocalBufHash中删除,并将状态置为 ~(BM_VALID | BM_TAG_VALID),其bufHdr->tag需要清空

10、将新的tag newTag插入hashLocalBufHash

11、将bufHdr->tag替换成newTag,此时是我们的tag了。

12buf_state清空,并且置为BM_TAG_VALID,usagecount1foundPTRfalse

13、返回buf描述符bufHdr

发布了289 篇原创文章 · 获赞 85 · 访问量 26万+

猜你喜欢

转载自blog.csdn.net/yanzongshuai/article/details/103828829