如过再有新的块进入Buffer cache,比如块X被读入Buffer cache,它将覆盖T,并且会被移至块V的前面,如下图: 
大家可以想像一下,如果按照这面的方式继续下去,最右边冷端头处的块,一定是最后一次访问时间距现在最远的块。那么,访问次数多的块是不会被选做牺牲者的,这一点Oracle是如何实现的?这很简单,Oracle一般以2次为准,块被访问2次以上了,它就有机会进入热端。 Oracle为内存中的每个块都添加了一个记录访问次数的标志位,假设图中每个块的访问次数如下: 
如果现在又有新块要被读入Buffer cache,Oracle开始从冷端头寻找牺牲者,冷端头第一个块S,它的访问次数是2,那么,它不能被覆盖,只要访问次数大于等于2的块,Oracle会认为它可能会被经常访问到,Oracle要把它移到热端,它会选择R做为本次的牺牲者: 

块S会被从冷端移到热端,并且它的访问次数会被清零。此时,块R就是牺牲者了,因为它的访问次数不到两次。 
新块Y覆盖了块R,并被移到了冷端块开始处,它的访问次数是1。如果块Y再被访问了一次,它的访问次数变为了2: 
虽然Y的访问次数达到了两次,但它不会马上被移到热端,它仍然留在原来的位置,随着不断有新块加入,被插入到它的前面,它会不断的被向后推移。 
如上图,又加入了很多的新块,Y又被推到了冷端头,当再有新块进入Buffer cache时,Y不会是牺牲者,它会被移到热端头S的前面,Y后面的Z,它的访问次数没有达到2,它将会是牺牲者。 好了,这就是Oracle中Buffer cache管理LRU的原理。按照这种方式运作,Oracle可以把常用的块尽量长的保持在Buffer cache中。而且,每有新块进入Buffer cache,Oracle都会从冷端头处,从右向左搜索牺牲块。因为越靠近冷端,块的访问次数有可能越少、最后的访问时间离现在最远。好了,LRU链还没有讲完,下面,我们再讨论一下脏块与脏LRU链的问题。
|