深入理解缓冲区(十八)

4.3.3 从buf淘汰方式看改进---freelist

在“4.1.4.5 Buf置换管理算法”中,我们描述了buf调度算法。PG首先是从freelist中取出空余的优先供缓存请求使用。如果freelist空,才去真正淘汰缓存块。

所以,一个思路是:尽可能增加freelist中的成员,使得淘汰减少,是否物理IO也可以减少呢?

先看PG对于freelist的操作方式:

1. 从结构上看,首先定义出一个指针,用来指向空余的buf,见如下蓝色字体

typedef struct BufferAccessStrategyData

{

BufferAccessStrategyType btype;

int ring_size;

int current;

bool current_was_in_ring;

/*

* Array of buffer numbers. InvalidBuffer (that is, zero) indicates we

* have not yet selected a buffer for this ring slot. For allocation

* simplicity this is palloc'd together with the fixed fields of the

* struct.

*/

Buffer buffers[1]; /* VARIABLE SIZE ARRAY */

} BufferAccessStrategyData;

2. 从这个指针的调用关系看,共被:增加空余buf到链表操作(AddBufferToRing)和从链表取出空余buf 操作构成(GetBufferFromRing)

BufferAccessStrategyData.buffers

BufferAccessStrategyData(就是如上的数据结构)

GetBufferFromRing

AddBufferToRing

StrategyRejectBuffer

3. 从函数的调用关系看,GetBufferFromRing和AddBufferToRing函数,都是被StrategyGetBuffer函数调用。而当有缓存块被申请使用时,才会调用到StrategyGetBuffer函数(从StrategyGetBuffer函数的代码中可以看出,只有使用指定“淘汰策略”,才会从一个“Ring”上拿出空余的buf供上层使用)。这样,freelist上的空余buf增加的机会并不多。这样,可能会影响着buf的有效利用。


深入理解缓冲区(十八) - 那海蓝蓝 - 那海蓝蓝的博客

/*

* If given a strategy object, see whether it can select a buffer. We

* assume strategy objects don't need the BufFreelistLock.

*/

if (strategy != NULL)

{

buf = GetBufferFromRing(strategy);

if (buf != NULL)

{

*lock_held = false;

return buf;

}

}

所以,我们可以知道,此处也有改进余地。

改法:增加一个线程,在适当的时机,遍历缓冲区,当发现空余的缓冲区存在时,即补充到freelist上,这样当需要申请缓冲区时,freelist尽可能地多存在空闲缓存块。

什么时候让这个线程启动去干活呢?上一节,增加了异步IO操作(提出了预取功能)。当发出异步IO读写请求时,数据还没有到位,也许是启动这样线程的最佳时机。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值