暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

从KCBBH数据结构看Oracle 缓冲区的基本算法

白鳝的洞穴 2020-06-08
948
Oracle数据库以KCB为开头的都是和缓冲区相关的。数据结构kcbbh定义了数据块块头CACHE部分的结构。在Oracle数据库中有x$bh或者v$bh视图来反映这个结构的数据。今天老白以Oracle 10.2的KCBBH数据结构为基础和大家一起讨论一下Oracle缓冲区中的一些常用的算法实现,以及从这些算法可以看到的优化和运维的要点。首先我们来看看struct kcbbh的定义:

  kgglk                kcbbhha; *  hash chain buffer is on  */

  ktsn                 kcbbhtsn; *  tablespace number  */

  krdba                kcbbhrdba; *  relative DBA  */

最前面的数据结构指向和数据块地址相关的数据结构,kcbbhha是HASH CHAIN的指针,指向该BUFFER的HASH BUCKET上的双向链表。ktsn+krdba是广义ROWID中的寻址部分,只要知道了表空间名和RDBA,那么就可以唯一定位某个数据块了。

这个字段是标识数据块的状态的,这是一个UB4结构的数据,占四个字节。很多和块操作相关的操作都要检查这个数据的状态。
kcbbhst是标识数据块的状态,其定义如下:

下面三个字段是和CKPT有关的:

  ub1           kcbbhcqid; *  which ckpt queue in working set buffer is  */

  kgglk         kcbbhckql; /*  link for checkpoint queue  */

  kgglk         kcbbhfql; /*  link for per-file checkpoint queue  */

  kgglk                kcbbhoq; /*  object queue the buffer is on  */

kcbbhcqid指向这个BUFFER位于哪个WORKING SET,关于WORKING SET的详细实现我们以后找其他话题细谈。WORKING SET是Oracle为了支持大内存,充分利用多SMP多CPU的优势而将DB CACHE划分为多个工作区,不同的工作区可以由不同的DBW进程来处理,从而提高DB CACHE的效率。
kcbbhckql和kcbbhfql分别是两个CKPT 链的指针,一个指向一个标准的CKPT链,这个链是按照SCN排序的。另外一个指向数据文件CKPT 链。数据文件CKPT链是每个文件一条的链表,是为了做文件级的CKPT专门设计的结构。这样如果我们要离线一个文件或者对一个文件做一些和CKPT有关的操作的时候,不需要等全量的CKPT把这个文件上的所有脏块都写盘了,只需要顺着某个文件的CKPT链去写入脏块就可以了。
kcbbhoq是10G才引入的新结构,9i或者之前的版本没有,是对象的CKPT链。当需要做对象级的CKPT的时候,比如执行ddl,TRUNCATE等操作,就需要对该对象进行CKPT。所以针对10g的这些对象级的操作性能提高了很多。
下面几个字段是和LRU链相关的:

  kgglk                kcbbhrpl; /*  link for maintaining position on replacement chain  */

  b1                   kcbbhfoq; /*  TRUE iff the buffer is on a write list  */

  b1                   kcbbhlpf; /*  LRU latch protected flags  */

  ub2                  kcbbhtch; /*  touch count  */

  ub4                  kcbbhtim; /*  time of last touch count increment  */

kcbbhrpl是LRU链的指针,kcbbhfoq标识用于区分该块是在LRU还是在LRU-W上,LRU-W是一个等待DBWR写入数据文件的链,该链上的数据块暂时不能被覆盖。实际上LRU链有多条,LRU,LRU-W,LRU-AUX等。LRU链上的数据块是可能能被覆盖的(也有脏块暂时链接在LRU上,还没放到LRU-W上),LRU-W是明显的脏块,需要被DBW写入的,LRU-AUX是已经完成写入的脏块,可以马上返回LRU重新使用的(ORACLE采用批量链入的方式,避免多多重组链带来的性能开销)。kcbbhtch是用来记录某个数据块被访问的次数的,这个值不一定是精确的,也不需要精确,用来反映出块的冷热就行了。TOUCH超过某个阈值的块被设置为热快(后面我们会介绍热快的标识),而如果某个块要被重用的时候,如果发现它是个热块,则会跳过,避免热块被过早的覆盖。

这个统计值计算了在扫描lru链的时候发现hot buffers的数量。如果这个值很高,说明在LRU链的尾部有比较多的热块。
kcbbhtim是该块的TOUCH上一次修改后的时间间隔,这也说明当前该块的热度。
kcbbhlpf 是该块的闩锁保护状态位,取值如下:

Oracle的KCBBH的数据结构设计的十分漂亮,从这个数据结构能够学到好多算法思想。这不仅对数据库是有用的,对于一些其他的内存缓冲设计,也有十分好的参考价值。
最后修改时间:2020-06-08 09:23:51
文章转载自白鳝的洞穴,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论