oracle buffer cache的脏数据块如何被dbwr写入到数据文件中;
脏数据块如何管理,即用lruw进行管理
何为lruw
1,从8i以后,LRUW链表同样包含两个子链表:辅助LRUW链表和主LRUW链表。那么LRUW链表是如何产生buffer header的呢
2,把lru buffer cache移动到lruw中
/*****摘录lruw机制如下****/
我们还是接着上面图五所示的例子来说明。假设这个时候,前台用户发出DML语句,要求修改BH2所指向的内存数据块。这时,按顺序发生下面的动作:
1) oracle会将BH2从辅助LRU链表上摘下,同时插入主LRU链表的中间,也就是插入BH1和BH4中间,同时增加BH2的touch的数量。
2) 将该BH2的标记设置为钉住(ping)。/********更改前先ping住***/
3) 更新BH2对应的内存数据块的内容。
4) 更新完以后,取消钉住的标记。/***更改完取消ping**/
5) 将BH2从主LRU链表转移到主LRUW链表上。/***从lru移动到主lruw链表***是更新完***/
6) 如果这个时候又有进程发出更新BH2所对应的内存数据块的内容,则BH2再次被钉住,更新,取消钉住。
7) DBWR启动以后,在扫描主LRUW链表时会将BH2转移到辅助LRUW链表上。/***dbwr进程先扫描,不是一上来就写lruw中的脏数据到data file***,先把主lruw移动到辅助lruw链表***/
8) DBWR将辅助LRUW链表上的BH2对应的数据块写入数据文件。/**dbwr然后才把lruw辅助链表的脏数据写入到datafile&*****/
9) 确认成功写入数据文件以后,将BH2从辅助LRUW链表上转移到辅助LRU链表上。/*****确认把脏数据从辅助lruw写完了,然后把辅助链表又移动回原来的辅助lru链表上***这样数据还是在内存中***/
从上面的描述中,我们可以看到,
主LRUW链表上包含的buffer header要么是
1,已经更新完了的数据块,
2,要么是被钉住正在更新的数据块。
而当DBWR进程启动以后,
它会扫描主LRUW链表,并跳过正在被钉住更新的buffer header,而将已经更新完了的buffer header从主LRUW链表上摘除,并转移到辅助LRUW链表上去。
扫描完主LRUW链表,或扫描的buffer header的个数达到一定限度时,DBWR会转到辅助LRUW上,将上面的buffer header所对应的数据块写入数据文件。
所以说,对于辅助链表上的buffer header来说,要么是正在等待被写入的;要么就是已经发出写入请求,正在写入而还没写完的。这里要注意的是,
buffer header进入LRUW链表,是从尾端进入;而DBWR扫描LRUW链表时,则是从首端开始。
顺带提一句,这里将主LRUW链表和辅助LRUW链表分开,主要就是为了提高DBWR在主LRUW链表上扫描的效率。如果只有主LRUW链表而没有辅助LRUW链表的话,
势必造成三种类型buffer header交织在LRUW链表上:
1)正在被钉住更新的buffer header;
2)已经更新完,而正在等待被写入数据文件的buffer header;
3)已经发出写请求,正在写而尚未写完的buffer header。在这种情况下,必然造成DBWR为了找到第二种类型的buffer header而需要扫描不该扫描的第三种类型的buffer header。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9240380/viewspace-757542/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/9240380/viewspace-757542/