8.缓冲区管理器

目录

1. 结构

1.1 缓冲区标签

1.2 缓冲表

1.3 缓冲区描述符

1.4 缓冲池

2. 锁

2.1 缓冲表锁bufMappingLock

2.2 缓冲区描述符相关锁

3. 页面访问

3.1 访问缓冲池中的页面

​编辑

3.2 将页面从存储加载到空槽

4. 其他

4.1 时钟扫描的页面置换算法

4.2 环形缓冲区

4.3 脏页刷盘


1. 结构

1.1 缓冲区标签

tag{(16821,16384,37721),1,3}表示16821号表空间的16384号数据库的37721号表的空闲空间映射(0为关系本体main分支,2位VM分支)的第3页。

1.2 缓冲表

缓冲表为散列表,通过散列函数,可根据缓冲区标签tag找到对应的buffer_id,即数据在缓冲池中的槽位号。散列表通过分离链接方法解决冲突。

1.3 缓冲区描述符

缓冲区描述符层包括与之相关的缓冲池槽位的元数据信息,包括buffer_id,缓冲区标签tag,当前访问页面的进程数refcount,访问次数usage_count,标志脏位的flags,指向下一个描述符的freeNext(所以缓冲区描述符层也是一个链表),以及context_lock与io_in_progress_lock两个锁,后面会介绍。

缓冲区描述符有三种状态:

空:缓冲池槽中无页面,refcount与usage_count均为0。

钉住:当前页面正在被访问,refcount与usage_count均大于等于1。

未钉住:存在该页面,但目前没有进程访问,refcount为0,usage大于等于1(因为至少将其载入缓冲池槽的进程使其加了1)。

其中空缓冲区描述符组成了一个freelist链表。

1.4 缓冲池

缓冲池有多个槽位组成,是一个数组,每个槽位为8k,正好可加载一个磁盘页面。

2. 锁

该锁为缓冲区管理器同步化的一部分,与SQL语句与操作中的锁无关。

2.1 缓冲表锁bufMappingLock

维护缓冲表的锁,分为读取的共享锁与增删的独占锁。

为了不影响其他事务对缓冲表的读写,提高并发量,pg将散列表划分为16组,每组一个锁,一次锁多个桶。

2.2 缓冲区描述符相关锁

内容锁:读取页面时的共享锁以及独占锁,独占锁在以下几种情况下分配:

  1. 增删改元组t_xmin/t_xmax事务
  2. 物理删除元组
  3. 冻结页面中的元组

IO进行锁

进程加载、写入页面时分配。

自旋锁

检查或更新元数据信息字段时获取,如更新refcount等。9.6版后,使用原子操作替代自旋锁。

3. 页面访问

3.1 访问缓冲池中的页面

通过Tag1与散列函数,找到散列表上的桶,

获取桶所在区的缓冲表共享锁,在该桶中找到tag1对应的buffer_id1(一个桶中可能有多个buffer_id)。

钉住buffer_id1的缓冲区描述符,将ref_count与usage_count分别加1.

释放共享锁,访问buffer_id1的缓冲池槽。

3.2 将页面从存储加载到空槽

1.通过Tag1与散列函数,找到散列表上的桶,获取桶所在区的缓冲表共享锁,在该桶中没找到tag1。释放共享锁。

2.从freelist(空缓冲区描述符链表)中获取空缓冲区描述符,并将其钉住,假设获得的是buffer_id2,以独占模式获取桶所在分区的锁。

3.创建一条tag=1,buffer_id=2的数据项,插入桶中。

4.获得排他的IO锁,将数据页面加载到buffer_id=2的缓冲池插槽中,标记vaild为1,释放IO锁。

5.释放桶所在分区的锁。

6.访问buffer_id=2的插槽。

将页面从存储加载到受害者缓冲池槽

  1. 使用时钟扫描算法选择脏页,将脏页刷到磁盘中
  2. 在散列表中加新的tag,删旧的tag,并且将脏页腾出的buffer_id设为新tag对应的id。
  3. 将新数据页面替换缓冲池插槽中的旧数据页面

4. 其他

4.1 时钟扫描的页面置换算法

以时钟的方式扫描缓冲区描述符,跳过被钉住的描述符,对于未被钉住的描述符,如果其usage_count为0,则将其置换出去,若不为0,则将其减1,然后扫描下一个:

(深色的表示被钉住的) 

4.2 环形缓冲区

当需要读写大表时,需要大量置换缓冲池,这会导致之后的缓存命中率降低。所以pg使用额外的环形缓冲区来替代缓冲池加载大表。当有以下情况时,会启用环形缓冲区:

  • 批量读取。当扫描关系读取数据的大小超过缓冲池的四分之一时,环形缓冲区的大小为 256 KB。(256k正好可以加载进二级缓存)
  • 批量写入,当执行下列 SQL 命令时,环形缓冲区大小为 16 MB。

COPY FROM 命令。

CREATE TABLE AS 命令。

CREATE MATERIALIZED VIEW 或 REFRESH MATERIALIZED VIEW 命令。

ALTER TABLE 命令。

  • 清理过程,当自动清理守护进程执行清理过程时,环形缓冲区大小为 256 KB。分配的环形缓冲区将在使用后被立即释放。

4.3 脏页刷盘

除了置换脏页时需要脏页刷盘外,检查点进程会在检查点开始时进行脏页刷盘;

后台写入进程通过少量多次的脏页刷盘来减少检查点的密集写入,默认为200ms一次,默认最多刷100个页。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值