ITPub博客

首页 > 大数据 > 可视化 > 为什么Oracle要搞出两个脏链表

为什么Oracle要搞出两个脏链表

原创 可视化 作者:wei-xh 时间:2018-08-23 15:23:05 0 删除 编辑

为什么Oracle要搞出两个脏列表:一个Checkpoint Queue,一个LRUW。

两个链表设计的目的是不一样的。

Checkpoint Queue严格按照数据块第一次被修改的时间排序,DBWR会沿着Checkpoint Queue写脏数据,并将写的位置记录在控制文件中,Oracle这么做的目的是,将越早被修改的块,越早被写出,达到减少实例恢复时间的目的。在实例异常down后,只需要从控制文件中读取检查点的位置,把这个点之后的重做日志前滚就可以恢复实例。

而LRUW链表不是这个目的。这个问题,稍显复杂,慢慢来说。

我们知道,一般情况下,buffer cache的内存是要比数据文件小的多的,在实例运行一段时间后,buffer cache就会呈现出“满”的状态,在出现新的内存空间请求时候,就需要在buffer cache中牺牲掉一些内存块来存储新的数据。

那么在空间不够的情况下,哪些块会被牺牲,刷出buffer cache呢?

一般是TCH小于2,CR块,全表扫描的块优先被牺牲重用。这些需要被重用的块里是可能包含脏块的。 那么这些脏块不同于CR块,不能直接被重用,需要被刷到磁盘

那么,LRUW链表来了,把需要刷出的脏块放到LRUW链表上,单独设计这个链表的目的是,可以最大化写出脏块的效率。例如可以合并物理空间上连续的脏块,减少IO数量。例如服务器进程,扫描到脏块后,把脏块链到LRUW,就不用管其他事,可以继续自己的工作。

此外,这里补充一些细节信息。

在系统急需大量空闲块的时候,服务器进程会搜索LRU链表,如果发现了脏快且TCH小于2(因为是从LRU冷端扫起,所以脏快的TCH大概率会很小)那么就挪到LRUW链表上,然后这些块后续会从LRUW写出到磁盘,最终这个内存就成了free的内存块,就可以被挪到LRU-Aux上被重用了,另外这个块被写入磁盘后,需要从Checkpoint Queue摘除。

一个块被修改变脏后,一定会进入到Checkpoint Queue队列,但是不会立即进入到LRUW队列,只有发生进程搜索LRU链表的时候,发现该块TCH数比较小,且没有被pin住,才会被放入LRUW链表然后被写出到磁盘。

很多人会认为,LRU链表里的块都应是干净的块。其实LRU链表里的脏快应该是比较多的,特别是如果这些脏块访问比较频繁,那么TCH数就会比较高,按照算法就不会被放到LRUW链表里,它会一直呆在LRU连表里,当然这个脏块最终会从Checkpoint Queue写出变为干净的块。

这里还有一个有趣的知识点,很多人都存在误解,这些块从Checkpoint Queue写出到磁盘后,其实 
1. 不会改变这个块在LRU链表里的位置 
2. 依然存在在内存里,很多人有误解,认为写出脏快后,这个块就不在内存里了,其实并不是这样的。是从LRUW链表里写出的脏块才会被刷出内存。


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/22034023/viewspace-2212672/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
Oracle ACE组成员,DBGeeK用户组发起人。曾在DTCC、ORACLE技术嘉年华、Gdevops等公开场合做过数据库技术专题分享,2017年应Oracle邀请在世界最大的数据库会议OOW上做技术分享。组织翻译了《拨云见日,解密Oracle ASM内核》一书。

注册时间:2009-07-04

  • 博文量
    422
  • 访问量
    2304716