浅谈CKPK-Q写和LRUW写的区别
两 个链表设计的目的是不一样的,Checkpoint Queue 按照数据块第一次被修改的先后时间排序(数据块只要变脏,肯定在这个链表上), Dbwr 沿 着 Checkpoint Queue 写脏数据, Oracle希望越早修改的块,会越早被写出。有利于减少恢复时间。但是有一点非常重要,这些块被写到磁盘后,1)是不会改变这个块在 Lru链表里的位置的 2)这个块依然存在在内存里(很多人有误解,认为写出脏快后,这个块就不在内存里了)。而 Lruw 链表不是这个目的,它的设计只是为了腾出点空间来,让后面发生物理读的块戒者需要构造 CR 的块可以在 BufferCache 里有地方,既然是为了腾出空间,那 么就要有块被牺牲掉挪出空间来,一般是 Tch 小于 2,CR 块,全表扫描的块会被牺牲重用。在系统急需大量空闲块的时候,迚程搜索 LRU 链表(包含 Lru-Aux)过程中,如果发现了脏快(因为是从 Lru 冷端扫起,所以脏快的 Tch 也很小)那么就挪到 Lruw 链表上,然后再从 Lruw写入到磁盘,最终这个 Free 的内存块就可以被挪到 Lru-Aux上被重用了,当然这个块被写入磁盘后,需要把这个块从CheckpointQueue 摘除。一个块被修改变 脏后,一定会迚入到 Checkpoint Queue 队列,但是不会立即进入到 Lruw 队列,只有发生进程搜索 LRU 链表的时候,如果 Tch 数比较小,才会被放入 Lruw 链表然后被写入磁盘。并丌象很多人认为的,Lru链表里就应是干净的块。其实 Lru 链表里的脏快应该是很多的,特别是如果你的脏块访问的 比较频繁,Tch 数比较高,是很难被刷到Lruw 链表里的,它会一直呆在Lru 连表里,当然这个脏块最终会从Checkpoint Queue 写出变为干 净的块,但是它在Lru 链表里的位置不变,不会被刷出 Buffer Cache。 上面的描述都做了简化, 你可能说我描述有误。 例如: Oracle 从Lruw 写脏快,比较详细的过程应该是,先扫描 Lruw 链表,然后把没有 pin 的数据块挪到 Lruw-Aux 上,然后以排他模式 pin这个块,写入磁 盘。我们只要能说明 Checkpoint Queue 和Lruw 链表在设计目的上的差异就OK 了,至于其他细节,可以以后再讨论。
个人观点,可能写得有错误的地方,希望大家多多指导。其实分享这个,只是为了下载资料~{:soso_e110:}