此博客旨在帮助您理解本书 The Internals of PostgreSQL 的最终概念:8 [Buffer Manager]。
注意:确保您对
有透彻的了解 Chapter 8 Part-2和posttresql的基础知识在我们继续进行第8章第3章之前,因为它构成了我们的探索基础。
所以,让我们继续:
3。从存储到受害者缓冲池插槽
加载页面-
1)创建所需页面的buffer_tag并查找缓冲区表。在此示例中,我们假设buffer_tag是'tag_m'(找不到所需的页面)。
-
(2)使用时钟扫描算法选择一个受害者缓冲池插槽,从缓冲台上获取包含受害者池插槽的buffer_id的旧条目,然后将受害者池插槽固定在缓冲区中描述符层。在此示例中,受害人插槽的Buffer_ID为5,旧条目为tag_f,id = 5。下一个小节中描述了时钟扫描。
-
(3)齐平(写和fsync)受害者页面数据是否脏;否则继续步骤(4)。肮脏的页面必须写入存储之前,然后用新数据覆盖。冲洗肮脏的页面如下:
-
用Buffer_ID 5获得了共享的content_lock和独家io_in_progress锁定(在步骤6中发布)。
-
更改相应描述符的状态; io_in_progress位设置为'1',而just_dirtied位设置为'0'。
-
根据情况,Xlogflush()函数被调用以在WAL缓冲区上写入WAL数据到当前WAL段文件(详细信息; WAL和Xlogflush功能在第9章中描述)。<<<<<<<<<<<<<<<<<<<<<<<<<<< /p>
-
将受害者页面数据冲洗到存储。
-
更改相应描述符的状态; io_in_progress位设置为'0',有效位设置为'1'。
-
发布io_in_progress和content_lock锁。
-
(4)获取覆盖包含旧条目的旧插槽的旧bufmappinglock分区,以独家模式。
-
(5)获取新的bufmappinglock分区,然后将新条目插入缓冲表:
-
创建由新的buffer_tag'tag_m'和受害者的buffer_id组成的新条目。
-
获取新的bufmappinglock分区,该分区涵盖了以独家模式包含新条目的插槽。
-
将新条目插入缓冲表。
-
(6)从缓冲表中删除旧条目,然后释放旧的bufmappinglock分区。
-
(7)将所需的页面数据从存储中加载到受害者缓冲区插槽。然后,使用Buffer_ID 5更新描述符的标志;脏点设置为'0并初始化其他位。
-
(8)释放新的bufmappinglock分区。
-
(9)使用Buffer_ID访问缓冲池插槽5。
在PostgreSQL中从存储到受害者缓冲池插槽的加载页面如下图:
在PostgreSQL中将页面从存储中加载到受害者缓冲池插槽(续)如下图:
页面替换算法:时钟扫描
-
该算法是 nfu (不经常使用)的变体,开销低;它有效地选择了较少使用的页面。
-
nextVictimbuffer ,无签名 32位整数始终指向一个缓冲区描述符,并顺时针旋转。
-
算法的伪代码如下:
WHILE true
(1) Obtain the candidate buffer descriptor pointed by the nextVictimBuffer
(2) IF the candidate descriptor is unpinned THEN
(3) IF the candidate descriptor's usage_count == 0 THEN
BREAK WHILE LOOP /* the corresponding slot of this descriptor is victim slot. */
ELSE
Decrease the candidate descriptpor's usage_count by 1
END IF
END IF
(4) Advance nextVictimBuffer to the next one
END WHILE
(5) RETURN buffer_id of the victim
postgresql中的时钟清扫如下图所示:
-
1)NextVictImbuffer指向第一个描述符(Buffer_ID 1);但是,由于将其固定而跳过。
-
2)NextVictImbuffer指向第二个描述符(Buffer_ID 2)。该描述符是未键的,但其用法_count为2;因此,用法_count减少了1,而NextVictimbuffer则前进到第三个候选人。
-
3)NextVictImbuffer指向第三个描述符(Buffer_ID 3)。该描述符是未键的,其用法_count为0;因此,这是这一轮的受害者。
-
每当 next Victimbuffer 扫描一个未添加的描述符时,其使用情况_Count会减少1。 0,通过旋转NextVictimBuffer。
环缓冲区
-
PostgreSQL在阅读或编写巨大表时使用环缓冲区。
-
环缓冲区是分配给共享内存的小而临时的缓冲区。
分配环缓冲区的条件
-
批量阅读>的环缓冲区大小是 256 kb 当扫描大于shared_buffers/4的关系时。
-
批量处理的环缓冲区大小是 16 Mb 执行某些SQL命令(例如复制,创建table as at as as as as as as et et et,eft)等。
< < /li> -
真空加工的环缓冲区尺寸是 256 kb 当自动伏库姆执行真空处理时。
-
使用后。
-
环形缓冲区有助于防止缓存在大规模的桌子操作过程中保持较高的缓存命中率。
肮脏的页面冲洗
-
CheckPointer进程将检查点记录写入写入log(WAL)段文件,并在检查点期间冲洗脏页。。
< /li> -
Checkpointer的主要作用是执行检查点和确保数据一致性。
-
背景作者的过程旨在最大程度地减少密集检查点对数据库活动的影响。
-
背景作者冲洗肮脏的页面逐渐,连续地减少了系统上的整体工作量。
-
默认情况下,背景作者醒来了每个 200 毫秒(由 bgwriter_delay 控制),并最大程度地冲洗 bgwriter_lru_maxpages ( 默认值为100页)。
-
背景作者的主要目标是保持稳定的冲洗肮脏页面,保持系统运行顺利。
我希望,这个博客帮助您了解了poststresql中的缓冲经理的最终概念。
的摘要如果您想了解PostgreSQL In-Depth。