PostgreSQL ring buffer的设计

对于扫表的查询,buffer区该如何应对?

1.如果没有额外的处理会如何

例如扫描表tableA

select * from tableA;

当tableA有许多页面,查询会将tableA的页面加载到buffer区中,那么就会将buffer区大量甚至全部的页面淘汰了。这个就不是我们希望看到的,前面我们按照 clock sweep的NFU算法,将频繁访问的页面留在内存中,然后一次扫表查询,就把buffer高频访问的页面淘汰,相当不划算。

2.解决方式

对于扫表的查询,限定查询使用的buffer数量。例如一次扫表查询,限定使用20个buffer,后续加载第21个页面时,也在这20个buffer进行淘汰。

在PG代码中,提出了ring buffer,

除了扫表查询(Bulk-READ),还有批量写(Bulk-writing)、vacumm机制需要ring buffer

3.具体实现

在PG中,获取buffer,分成两种有策略情况和普通情况

有策略情况,对应这对于扫表查询、批量写这样的情况,需要分配一个ring buffer,buffer的分配需要在ring buffer内进行分配。(可能这叫策略吧)

普通情况就是正常的随机访问,buffer的分配就是在buffer池进行分配

typedef enum BufferAccessStrategyType
{
    BAS_NORMAL,                 /* Normal random access */
    BAS_BULKREAD,               /* Large read-only scan (hint bit updates are
                                 * ok) */
    BAS_BULKWRITE,              /* Large multi-block write (e.g. COPY IN) */
    BAS_VACUUM                  /* VACUUM */
} BufferAccessStrategyType;

BufferAlloc:分配一个buffer,其中新分配时会调用到 StrategyGetBuffer

StrategyGetBuffer:入参strategy,传入对应的策略,普通情况时就是null;

typedef struct BufferAccessStrategyData *BufferAccessStrategy;
typedef struct BufferAccessStrategyData
{
    BufferAccessStrategyType btype;
    int         nbuffers;
    int         current;
    Buffer      buffers[FLEXIBLE_ARRAY_MEMBER];
}           BufferAccessStrategyData;

这里提出一个思考,ring buffer是单独划分的吗,独立于 buffer pool吗?

buffer pool指的公共的buffer池,在PG中就是BufferBlocks

答案:ring buffer还是在buffer pool内,可以看AddBufferToRing

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值