晶晶实验十八之buffer cache中的LRU链
一、LRU链介绍
HASH是快速查找时,常用的算法。Oracle中几乎在所有需要快速查找的地方,都使用了HASH算法。LRU则是在“资源重用”时,常用的算法。
在Buffer cache中,LRU链被分为两半,分别是热端、冷端,在默认方式下,热、冷端各占50%的块,这点可以由隐藏参数_db_percent_hot_default控制。当块第一次被读进Buffer时,会被插入到冷端头位置处。每次需要自由块时,Oracle服务器进程从冷端尾开始搜索可以被重用的块,因此,冷端的块是最有可能被重用的。在每个块的Buffer header中,准备有一个量,记录块被访问的次数,称作:Touch Count(TCH)。它代表块的访问频率。Oracle通过它决定块的冷热位置。在DSI中,专门有一段伪码,介绍TCH和块的重用:
关于Touch Count值具体算法如下:
IF ( 当前块的touch count 数> _db_aging_hot_criteria ) THEN
此块暂不重用
IF (_db_aging_stay_count >= _db_aging_hot_criteria) THEN
将此块的Touch Count数减半
ELSE
将此块的Touch Count值传给_db_aging_stay_count
END IF
ELSE
此块将被重用
END IF
(上述伪码来自DSI)
其中,_db_aging_hot_criteria与_ db_aging_stay_count都是Oracle的隐含参数,_db_aging_hot_criteria值默认为2,_ db_aging_stay_count有可能会随时变化。
根据这段代码,假如说,又有新的物理读发生了,Buffer cache中已经没有了空块,服务器进程开始从LRU的冷端开始扫描,寻找可以被重用的自由块。
例如,LRU冷端第一个块的TCH值为4,而当前_db_aging_hot_criteria参数仍为默认值2。因为块的TCH为4,大于2,此块暂不重用。假如_db_aging_stay_count当前值为0,_db_aging_stay_count并不大于等于_db_aging_hot_criteria,因此,将此块的Touch Count值传给_db_aging_stay_count,当前_db_aging_stay_count的值变为了4。
第一个块不可重用,继续向后查找。假如第二个块的TCH也为4,跟据上面的算法,它也不会被重用,但此时由于_db_aging_stay_count的值已经变为了4,已经大于_db_aging_hot_criteria的值2,因此,此块的TCH值将被减半,变为2。
等等,服务器进程照此算法扫描LRU上的块,直到找到足够的自由块为止。
但是这段伪码和我试验的结果一直不符。我试验的结果,每当块的TCH值发生变化时,并不会立即改变它所处的位置。块一旦从冷端移到了热端,TCH值马上变为0。
具体是,服务器进程需要读块进Buffer,它会从LRU链的尾端开始搜索自由块,如果发现搜索到的块的TCH值小于2,就重用这个块,并把它移动到冷端头。如果发现TCH大于2的块,并不会重用它,而是把它移到热端头部,并把它的TCH设为0。下面,我们试验一下这个过程:
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/21266384/viewspace-1311995/
,如需转载,请注明出处,否则将追究法律责任。