第8章的摘要:“ postgresql的内部”书中的“缓冲经理”
#postgres #database #apacheage #agenssql

此博客旨在帮助您理解本书的章节:8 [Buffer Manager] The Internals of PostgreSQL

注意:确保您对Chapter 7 Part-1Chapter 7 Part-2和posttresql的基础知识有透彻的了解,因为它构成了我们探索的基础。

所以,让我们开始:

章节简介

  • 一个缓冲区管理器管理共享内存和持久存储之间的数据传输,并且可以对DBMS的性能产生重大影响。

  • PostgreSQL缓冲区管理器的工作非常有效。

在PostgreSQL中的缓冲管理器,存储和后端过程之间的关系如下:

Image description


本章概述

缓冲管理器结构

  • PostgreSQL缓冲区管理器包括一个缓冲台,缓冲区描述符和缓冲池

  • 缓冲池层存储数据文件页面,例如表和索引,以及自由空间地图和可见性映射

  • 缓冲池是数组(缓冲池阵列的索引称为buffer_ids),即每个插槽存储数据文件的一页。

缓冲区标签

  • 在PostgreSQL中,所有数据文件的每个页面都可以分配一个唯一标签,即A buffer tag

  • 当缓冲区管理器收到请求时,PostgreSQL使用所需页面的 buffer_tag

  • buffer_tag包括三个值: -

  1. relfilenode。
  2. 其页面所属关系的叉数数量。
  3. 其页面的块号。
  • 例如: buffer_tag {((16821,16384,37721)),0,7} 识别第七块中其关系的页面中的页面OID和叉数分别为 37721 0 ;该关系包含在oid 16384 的数据库中,其OID为 16821

后端过程如何读取页面

  1. 读取表或索引页面时,后端进程会向“ Buffer_TAG”发送一个请求,向缓冲区管理器。

  2. 缓冲区管理器返回存储请求页面的插槽的buffer_id。如果请求的页面未存储在缓冲池中,则缓冲区管理器将页面从持久存储到一个缓冲池插槽之一,然后返回Buffer_ID的插槽。

  3. 后端进程访问buffer_id的插槽。

如何从Buffer Manager中读取PostgreSQL中的Buffer Manager 的页面如下:

Image description

  • 当后端过程修改缓冲池中的页面(例如,通过插入元组)时,尚未将尚未刷新存储的修改页面称为 dirty页面

页面替换算法

  • 当占用所有缓冲池插槽但未存储所请求的页面时,缓冲区管理器必须在缓冲池中选择一个页面,该页面将由请求的页面替换。

  • 页面选择算法称为页面替换算法,所选页面称为受害者页面

  • PostgreSQL使用了时钟扫描,因为它比以前版本中使用的LRU算法更简单,更有效。

冲洗肮脏的页面

  • 肮脏的页面最终应冲洗到存储中;但是,缓冲区管理器需要帮助执行此任务。

  • 在Postgresql中,两个背景过程, checkpointer 背景作者是该任务的原因。

    < /li>

缓冲管理器结构

  • PostgreSQL缓冲液管理器包括三层层,即 buffer表 缓冲区描述符 buffer pool

Buffer Manager的三层结构 PostgreSQL中的三层结构如下:

Image description

  • 缓冲池 array 。每个插槽存储一个数据文件页面。数组插槽的索引称为 buffer_ids

  • 缓冲区描述符层是缓冲区描述符的数组。每个描述符具有与缓冲池插槽的一对一对应关系,并保存在相应插槽中存储的页面的元数据。

  • 缓冲表是一个哈希表,它存储了存储的页面的 buffer_tags 与描述符的 buffer_ids 之间的关系保持存储的页面各自的元数据。

缓冲台

  • 一个缓冲表可以在逻辑上分为三个零件: a hash函数哈希桶插槽数据条目< /strong>。

缓冲表 postgresql中的如下图:

Image description

  • 内置哈希函数映射 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 是用于控制对关联存储的页面的访问的轻量重量锁。

  • 标志可以保存关联存储的页面的多个状态。

  1. 肮脏的位指示存储的页面是否脏。
  2. 有效的位指示是否可以读取或编写存储的页面(有效)。
  3. io_in_progress 位指示缓冲区管理器是否正在/到存储中读取关联的页面。
  • freenext 是下一个生成自由主义者的描述符的指针。

  • 三个定义了描述符:

  1. 空:当相应的缓冲池插槽不存储页面时(即refcount和usage_count为0)时,该描述符的状态为空。

  2. 固定:当相应的缓冲池插槽存储一个页面和任何PostgreSQL进程正在访问页面(即refcount和USAGE_COUNT大于或等于1),缓冲区描述符固定

  3. undinned:当相应的缓冲池插槽存储一个页面时,但没有postgresql进程访问页面(即USAGE_COUNT大于或等于1,但重新卡是0),但是此缓冲区描述符的状态是 untined


我希望,这个博客帮助您理解了popstresql中的缓冲经理的最初概念。

查看Chapter : 8 Part-2的摘要

如果您想了解PostgreSQL In-Depth