日期:2014-05-16  浏览次数:20464 次

oracle检查点队列与增量检查点【转载】

oracle检查点队列与增量检查点

   今天是2013-09-04,这几天一直心里安顿不下来,今天还好了,可以自己安静的学习一下oracle,在此记录一下学习笔记。这篇文章我不知道在那转载的,一直都留在我的qq空间,我觉得还是非常棒的,另外我查看分析了一下相关内容,并做 了部分实验。这块内容我想应该是ocp考试知识点之一吧。

  检查点的主要目的是以对数据库的日常操作影响最小的方式刷新脏块。脏块不断的产生,如何将脏块刷新到磁盘中去呢?在8i之前,Oracle定期的锁住所有的修改操作,刷新Buffer cache中的所有脏块,这种刷新脏块的方式被称为完全检查点,这极大的影响了效率,从9i之后只有当关闭数据库时才会发生完全检查点。


从8i开始,Oracle增加了增量检查点的概念,增量检查点的主要宗旨就是定期的刷新一部分脏块。将脏块一次刷新完是不合理的,因为脏块不断产生,没有穷尽。像完全检查点那样停止用户所有的修改操作,将脏块刷新完再继续,这绝对会极大的影响性能。所有增量检查点的一次刷新部分块是脏块问题的最好解决办法。那么,每次刷新时,都刷新那些块呢?根据统计研究,根据块变脏的顺序,每次刷新那些最早脏的块,这种方式最为合理。为了实现这一点,Oracle在Buffer cache中又建立了一个链表,就是检查点队列。每个块在它变脏时,会被链接到检查点队列的末尾。就好像排队一样,9:00来的人站在第一位,9:05来的人排第二位,以后每来一个人都站在队伍的末尾,这个队伍就是按来到的时间顺序排列的一个队列。检查点队列就是这样,块在变脏时会被链到末尾。因此检查点队列是按块变脏的时间顺序,将块排成了一个队列。

如上图,检查点队列中的每一节点,都指向一个脏块。检查点队列每个节点中的信息其实非常少,就是记录对应块在Buffer cache中的地址,脏块对应的重做记录在日志文件中的位置,另外还有前一个节点、后一个节点的地址。检查点队列还有LRU、脏LRU,这些都是双向链表。双向链表就是在节点中记录前、后两个节点的地址。

     检查点队列头部的块是最早变脏的,因此,Oracle会定期唤醒DBWn从检查点队列头开始,沿着检查点队列的顺序,刷新脏块。在刷新脏块的同时,仍可以不断的有新的脏块被链接到检查点队列的尾部。这个定期唤醒DBWn刷新脏块的操作,Oracle就称为增量检查点。

eg:

SQL> select kvittag,kvitval,kvitdsc from x$kvit where kvittag='kcbldq';

KVITTAG                                     KVITVAL KVITDSC
---------------------------------------- ---------- ----------------------------
kcbldq                                           25 large dirty queue if kcbclw reaches this

SQL> select kvittag,kvitval,kvitdsc from x$kvit where kvittag='kcbfsp';

KVITTAG                                     KVITVAL KVITDSC
---------------------------------------- ---------- ----------------------------
kcbfsp                                           40 Max percentage of LRU list foreground can scan for free

SQL> show user
USER is "SYS"

 

 

如上图,1、2、3号节点所指向的脏块已经被刷新为干净块。同时,又有两个块变脏,它们被链接到了检查点队列的末尾,它们是9号、10号节点。