Oracle 的检查点队列 (checkpoint queue)

时间:2022-07-01 07:43:58
这篇文章是参考甲骨论老相老师的视频:
http://v.youku.com/v_show/id_XNDAwOTY3MTU2.html
所做的学习笔记



1. LRU chain 和 LRUW chain CBC chain
     先复习一下:
     Oracle 的检查点队列 (checkpoint queue)
 
 
         如上图, 在database buffer cache中, 里面的buffer被若干条链串联在一齐(通过头尾部指针实现)

         LRU(Least recent used) chain
      
这是一条用于查找最近最少使用的buffer的链, 当buffer不够用时会从这条链冷端找出buffer来重用.

         LRUW(Least recent used writed) chain
      
与上面那条LRC chain对应, 有一条专门for  脏buffer的链, 而且是按最近修改次数排序的.
         DBWR后台进程会将这条链的冷端buffers写入dbf文件

         CBC(cache buffers chain)
      
根据buffer对应的block在dbf文件位置组织起来的链
       这种链有很多条,  如上图,server process会根据block头部信息算出对应的buffer在dababase buffer cache中的哪一条CBC中,然后遍历出来.

       

2.  Check Point Queue (检查点队列) chain
      
      
这是按照第一次被修改的时间排列的buffer链.


          注意2点:
          1, 里面都是脏buffer
          2. 按照第一次被修改(变脏)时间排序
                 也就说有3个buffer   假如它们第一次修改时间分别是  12:00 13:00 14:00, 那么它们就按照这个顺序排序了, 假如15:00 时第1个buffer又被修改了,  但是这时它们的顺序不会变, 因为顺序依据是第一次的被修改时间啊~
 



3. Check Point Queue的内容和工作方式
      
这就是本文主要讲的东西,  不过要首先介绍几个概念知识:
       
                3.1 RBA (Redo byte address)
            
看名字就知道这是1个地址.
                当database buffer cache里的1个buffer 被修改时, 也就是被变脏时就会产生日志, 而这些日志为被写入到Log buffer cache(日志缓存里),  那么这些日志在日志缓存里的位置就是RBA了.

                而脏buffer会把对把对应的RBA记录在自己的头部信息中, 当这个脏buffer要被回滚时, server process就可以根据RBA找到对应的日志了.

               而1个buffer的RBA并不是唯一的. 由于1个buffer可以在不同的时间段被多次修改, 就会产生多次日志, 而这些日志会被写入到log buffer cache中的不同的位置. 所以往往1个buffer里面记录着多个RBA.

             

              3.2 LRBA (Low Redo byte address) 和 HRBA
             
LRBA是RBA的一种.   是对应脏buffer 第一次被修改的日志地址.  而对应地 HRBA就是最近1次被修改的日志地址.

               
                

              3.3 Check Point Queue实际上是以脏buffer的LRBA顺序链接起来的.
             
刚才不是说是以第一次被修改的时间为序的吗?
                  没错.  而LRBA就是对应每个buffer第一次被修改的日志地址.
                  而且.  Oracle是严格按照日志的产生时间顺序来写日志的.   也就是地址靠后的日志产生时间肯定比地址靠前的日志产生时间要早.
                
               如下图:
                Oracle 的检查点队列 (checkpoint queue)



                   可以理解到, 当dirty buffer2在check point queue的位置比 dirty buffer1的位置靠后, 则代表 dirty buffer2的LRBA 肯定比 dirty buffer1 的LRBA 靠后.  也即是 dirty buffer1 的第一次被修改时间比 dirty buffer2的第一次被修改时间早.



                 3.4 CKPT 进程.
             
checkpoint 进程也叫检查点进程的, 以前都提过了, 是负责更新Oracle 控制文件的.
                

  Oracle 的检查点队列 (checkpoint queue)
               
                 而CKPT有其中两种事件:
                 a. 完全检查点 (completed checkpoint):
               这时CKPT进程 会 触发 DBWR进程把 check point queue 上所有的脏buffer(也就是所有的脏buffer)写入dbf文件.
                      
                          那么什么时候会出发这个完全检查点的事件呢?  很明显,  这个事件就是要将所有脏buffer写入dbf files的事件.
                          通常来讲, 只有关闭数据库这个1个动作(还有dba手动执行 alter system checkpoint动作),  oracle会将data buffer cache中所有脏buffer写入到dbf文件, 这样数据库的改动就被完整的保存下来了.
                         
                           所以, 在数据库正常运行期间来, 是不会发生完全检查点事件, 对应地, 会每3秒发生一次 增量检查点
                     


                 
b. 增量检查点(incremental checkpoint):
             
这时CKPT 会将  check point queue第一个脏buffer 的 LRBA地址 记录到控制文件中.

                  而这个事件每3秒发生一次.

                  上面那个动作,是CKPT进程在增量检查点主要的动作.
                  而实际上, CKPT在增量检查点发生的时候还会做一件事情.
                  就是会检查check point queue, 当它认为check point queue上的脏buffer过多的时候(其实数据库所有脏buffer都在check point queue上啦),    就会把 触发DBWR 把 checkpoint queue 上前几个脏buffer 写入到dbf 文件.     这样就缩短了checkpoint queue 的长度.

                  也就是会所其实DBWR进程有若干种工作方式, 其中1种是把 LRUW chain中的冷端的脏buffer 写入到 dbf文件. 另一种是在增量检查点事件中被CPKT进程触发, 将checkpoint queue中的前一部分脏buffer 写入dbf文件.


              
3.5 on disk RBA 介绍

             
我们可以用下面语句查看check point queue的一些信息:
                  select CPDRT,
                  CPLRBA_SEQ||'.'||CPLRBA_BNO||'.'||CPLRBA_BOF "Low RBA",
                  CPODR_SEQ||'.'||CPODR_BNO||'.'||CPODR_BOF  "On disk RBA",
                  CPODS,CPODT,CPHBT from x$kcccp;
Oracle 的检查点队列 (checkpoint queue)


                如上图
                 其中 CPDRT 列指的是当前checkpoint queue 上脏buffer的数量.
                       Low RBA 是指checkpoint queue上 第1个脏buffer的 LRBA
                      
                        那么on disk RBA似是啥.
 
                 而我们知道其实Logbuffer 里面空间其实很小,而LGWR 进程不断地将Logbuffer里面的日志写入到 redo log文件中.
                 而redo log文件其实分组的. 当前被写入的那一组就是current状态(当前被写入状态)
                 那么current 状态的redo log 文件记录的最后一条日志的地址,  也就是Current redo log文件最新的那一条日志地址就是On disk RBA了.
                其实就是被记录到硬盘的最新那条日志地址啦.

              
我们可以见到On disk RBA 的值 比 LRBA的值要靠后一些,   证明上图中checkpoint queen上的第一个脏buffer 已经被写入到硬盘上了.

                  如下图:


Oracle 的检查点队列 (checkpoint queue)

         
     中间那条红线是分割线.  上面的日志已经被写入redo log file,  下面的日志还在Log buffer. 那么redo log file中最新的那个日志地址就是on disk RBA了,  而整体checkpoint queen 的第1个buffer 的LRBA(就是整条checkpoint queue的LRBA) 地址比on disk RBA还早, 当然就已经写入硬盘了.

      
4. Check Point Queue的作用和意义          
          见我的另外一篇文章   checkpoint queue的作用与意义:
 http://blog.csdn.net/nvd11/article/details/8749393