此博客旨在帮助您理解本书的章节:8 [Buffer Manager] The Internals of PostgreSQL 。
注意:确保您对Chapter 7 Part-1,Chapter 7 Part-2和posttresql的基础知识有透彻的了解,因为它构成了我们探索的基础。
所以,让我们开始:
章节简介
-
一个缓冲区管理器管理共享内存和持久存储之间的数据传输,并且可以对DBMS的性能产生重大影响。
-
PostgreSQL缓冲区管理器的工作非常有效。
在PostgreSQL中的缓冲管理器,存储和后端过程之间的关系如下:
:
本章概述
缓冲管理器结构
-
PostgreSQL缓冲区管理器包括一个缓冲台,缓冲区描述符和缓冲池。
-
缓冲池层存储数据文件页面,例如表和索引,以及自由空间地图和可见性映射。
-
缓冲池是数组(缓冲池阵列的索引称为buffer_ids),即每个插槽存储数据文件的一页。
缓冲区标签
-
在PostgreSQL中,所有数据文件的每个页面都可以分配一个唯一标签,即A buffer tag 。
-
当缓冲区管理器收到请求时,PostgreSQL使用所需页面的 buffer_tag 。
-
buffer_tag包括三个值: -
- relfilenode。
- 其页面所属关系的叉数数量。
- 其页面的块号。
- 例如: buffer_tag {((16821,16384,37721)),0,7} 识别第七块中其关系的页面中的页面OID和叉数分别为 37721 和 0 ;该关系包含在oid 16384 的数据库中,其OID为 16821 。 。
后端过程如何读取页面
-
读取表或索引页面时,后端进程会向“ Buffer_TAG”发送一个请求,向缓冲区管理器。
-
缓冲区管理器返回存储请求页面的插槽的buffer_id。如果请求的页面未存储在缓冲池中,则缓冲区管理器将页面从持久存储到一个缓冲池插槽之一,然后返回Buffer_ID的插槽。
-
后端进程访问buffer_id的插槽。
如何从Buffer Manager中读取PostgreSQL中的Buffer Manager 的页面如下:
- 当后端过程修改缓冲池中的页面(例如,通过插入元组)时,尚未将尚未刷新存储的修改页面称为 dirty页面。
页面替换算法
-
当占用所有缓冲池插槽但未存储所请求的页面时,缓冲区管理器必须在缓冲池中选择一个页面,该页面将由请求的页面替换。
-
页面选择算法称为页面替换算法,所选页面称为受害者页面 。
-
PostgreSQL使用了时钟扫描,因为它比以前版本中使用的LRU算法更简单,更有效。
冲洗肮脏的页面
-
肮脏的页面最终应冲洗到存储中;但是,缓冲区管理器需要帮助执行此任务。
-
在Postgresql中,两个背景过程, checkpointer 和背景作者是该任务的原因。
< /li>
缓冲管理器结构
- PostgreSQL缓冲液管理器包括三层层,即 buffer表 ,缓冲区描述符和 buffer pool 。
Buffer Manager的三层结构 PostgreSQL中的三层结构如下:
-
缓冲池是 array 。每个插槽存储一个数据文件页面。数组插槽的索引称为 buffer_ids 。
-
缓冲区描述符层是缓冲区描述符的数组。每个描述符具有与缓冲池插槽的一对一对应关系,并保存在相应插槽中存储的页面的元数据。
-
缓冲表是一个哈希表,它存储了存储的页面的 buffer_tags 与描述符的 buffer_ids 之间的关系保持存储的页面各自的元数据。
缓冲台
- 一个缓冲表可以在逻辑上分为三个零件: a hash函数,哈希桶插槽和数据条目< /strong>。
缓冲表 postgresql中的如下图:
-
内置哈希函数映射 buffer_tags to hash bucket插槽。
-
如果哈希桶插槽的数量大于缓冲池插槽的数量,则可能发生碰撞。
-
缓冲表使用与链接列表方法分开链接来解决碰撞。
-
一个数据条目包括两个值:页面的 buffer_tag 和 buffer_id 保存页面的描述符元数据。
-
例如:数据输入 tag_a,id =1â表示带有 buffer_id 1 存储用 tag_a 标记的页面的元数据。
-
伪函数是: -
uint32 bucket_slot = calc_bucket(unsigned hash(buffertag buffer_tag),uint32 bucket_size)
缓冲区描述符
-
缓冲区描述符结构由结构 BufferDesc 。
定义
-
标签在相应的缓冲池插槽中保存存储页面的buffer_tag。
-
buffer_id 识别描述符(相当于相应的缓冲池插槽的buffer_id)。
-
重新计算(PIN COUNT)**保留当前访问关联存储页面的PostgreSQL进程的数量。当postgresql进程**访问存储的页面时,其重新数必须由1( refcount ++ )增加。访问该页面后,其重新数必须减少1(重新汇编 - )。当重新计为 Zero ,即当前未访问相关的存储页面时,页面是未锁定;否则它是固定。
-
USAGE_COUNT 保留自加载到相应的缓冲池插槽中以来,已访问了关联存储的页面的次数。
-
content_lock 和 io_in_progress_lock 是用于控制对关联存储的页面的访问的轻量重量锁。
-
标志可以保存关联存储的页面的多个状态。
- 肮脏的位指示存储的页面是否脏。
- 有效的位指示是否可以读取或编写存储的页面(有效)。
- io_in_progress 位指示缓冲区管理器是否正在/到存储中读取关联的页面。
-
freenext 是下一个生成自由主义者的描述符的指针。
-
三个定义了描述符:
-
空:当相应的缓冲池插槽不存储页面时(即refcount和usage_count为0)时,该描述符的状态为空。
-
固定:当相应的缓冲池插槽存储一个页面和任何PostgreSQL进程正在访问页面(即refcount和USAGE_COUNT大于或等于1),缓冲区描述符固定。
-
undinned:当相应的缓冲池插槽存储一个页面时,但没有postgresql进程访问页面(即USAGE_COUNT大于或等于1,但重新卡是0),但是此缓冲区描述符的状态是 untined 。
我希望,这个博客帮助您理解了popstresql中的缓冲经理的最初概念。
查看Chapter : 8 Part-2的摘要
如果您想了解PostgreSQL In-Depth。