概述
缓冲区管理器管理着共享内存和持久存储之间的数据传输。
PostgreSQL缓冲区管理器由缓冲表、缓冲区描述符和缓冲池组成。缓冲池层存储着数据文件页面,诸如表页与索引页,以及其相应的自由空间映射和可见性映射的页面。缓冲池是一个数组,数据的每个槽中存储数据文件的一页。缓冲池数组的序号索引称为buffer_id。
PostgreSQL中的每个数据文件页面都可以分配到唯一的标签,即缓冲区标签。当缓冲区管理器收到请求时,PostgreSQL会用到目标页面的缓冲区标签。
缓冲区标签由三个值组成,分别是关系文件节点、关系分支编号和页面块号。第一个值分别代表了表空间、数据库和表的oid;第二个值代表关系表的分支号;最后一个值代表页面号。
后端进程如何读取数据页
当后端进程修改缓冲池中的页面时(例如向页面插入元组),这种尚未刷新到持久存储,但已被修改的页面被称为脏页。
页面置换算法
当所有缓冲池槽位都被占用,且其中未包含所请求的页面时,缓冲区管理器必须在缓冲池中选择一个页面逐出,用于放置被请求的页面。
脏页刷盘
脏页最终应该被刷入存储,但缓冲区管理器执行这个任务需要额外帮助。在PostgreSQL中,检查点进程
和后台写入器
这两个后台进程负责此任务。
缓冲区管理器的结构
- 缓冲表层是一个散列表,它存储着页面的buffer_tag 与描述符的buffer_id 之间的映射关系。
- 冲区描述符层是一个由缓冲区描述符组成的数组。每个描述符与缓冲池槽一一对应,并保存着相应槽的元数据。
- 缓冲池层是一个数组。每个槽都存储一个数据文件页,数组槽的索引称为buffer_id。
缓冲表
缓冲表可以在逻辑上分为三个部分,分别是散列函数、散列桶槽及数据项。
缓冲区描述符
缓冲区描述符保存着页面的元数据,这些与缓冲区描述符相对应的页面保存在缓冲池槽中。缓冲区描述符的结构由BufferDesc结构定义。
缓冲区描述符层
冲区描述符的集合构成了一个数组,称该数组为缓冲区描述符层。
PostgreSQL中的freelist完全不同于Oracle中freelist的概念。PostgreSQL的freelist只是空缓冲区描述符的链表。PostgreSQL中与Oracle中的freelist相对应的对象是空闲空间映射(FSM)
缓冲池
缓冲池只是一个用于存储关系数据文件(例如表或索引)页面的简单数组。缓冲池数组的序号索引也就是buffer_id。
缓冲池槽的大小为8KB,等于页面大小,因而每个槽都能存储整个页面。