缓冲区管理器位于用户和数据库存储之间,用户进程请求数据块时,由缓冲区管理器从数据库存储层将数据块读取到数据缓冲区提供服务。
数据缓冲区内存放的是数据块,包含表和索引的块、可用性地图的块、可见性地图的块以及缓冲区索引块。
缓冲区管理器分为三层,第一层为缓冲区表层,第二层为缓冲区描述层,第三层为缓冲区池层(负责将数据块从数据文件读到内存)。缓冲区描述层包含大量信息,也是对于管理最重要的一层。
缓冲区表层存在很多插槽,每个插槽里存放了数据块的标记,标记里包含了对于要访问的数据块的描述,比如哪个数据文件的第几个块。每个槽里记录了一个或多个标记。
比如缓冲区标记为{(16821、16384、37721)、0、7},其中16821、16384、37721分别代表对象oid、数据库oid以及表空间oid,0代表页面的fork number,7代表页面number。
将数据块读到数据缓冲区需要记录信息,此类信息存放在描述层。
描述层里包含了缓冲区的tag信息以及buffer_id。PolarDB将缓冲区分为多个大小相同的块,每个块都有自己的buffer_id。
refcount和usage_count用于描述缓冲区被访问的热度。缓冲区被某个进程访问过一次,refcount和usage_count均会+1。与此同时,如果缓冲区被时钟扫描过后refcount-1,refcount=0代表该缓冲区可用。
Flag有三个状态,其中dirty bit代表缓冲区已经被修改过;valid bit代表已经被写到数据文件,当前可用;io_in_progress bit代表正在被进程处理。
缓冲池层是连接描述层与表层非常重要的一层,它将内存分割为若干个内存块,每个内存块都有一个buffer_id。
将数据块读取到数据缓冲区的流程如下:首先,发送一个请求,请求到达描述层后分配一个插槽,管理器将数据块的标记记录在描述里,同时从数据缓冲区层申请内存块,将缓冲数据块的标记从数据库读到缓冲区,并发送 Buffer_id,使得块的标记与 Buffer_id的标记能够进行匹配。
假如数据块是8k,则缓冲池会被分割为若干个8k的池槽,正好等于数据块的大小。
接下篇:https://developer.aliyun.com/article/1223086?groupCode=polardbforpg