7.将块读入buffer cache中时,如何找到一个可以使用的buffer呢?下面步骤进行一步步解析。
8.首先在辅助LRU的最尾端向前查找可用buffer,TCH<2的块可以被重用。
9.如果辅助LRU最尾端的块是TCH<2的块,则将直接使用此块,并将其移动到主LRU的冷端头。
同时也会根据此块的DBA进行HASH,查找相应的HASH BUCKET,将此块加入到对应的HASH CHAIN上,并对BH中的相应信息进行修改(如对应X$BH中的LRU_FLAG,NXT_HASH、BA等字段的具体值)--此过程也需要相应的CBC LATCH /buffer pin锁的获取释放等。
再把数据块的值返回前台进程,此时物理读就完成了。
10.如果辅助LRU最尾端的块是TCH>=2的块,则首先将此块移动到主LRU的热端头,同时TCH清零;然后在在辅助LRU上继续向前查找,直到找到可用的块---TCH<2。之后的过程和步骤9中的就一样了。(SMON每三秒时,服务器进程扫描空闲BUFFER时;都会把辅助LRU中TCH大于等于2的移到主的热端头)
11.如果在辅助LRU上搜索完毕扔未找到可以使用的块,则将从主LRU的冷端尾开始搜索。
12.如果主LRU最尾端的块是TCH<2的块,则将直接使用此块,并将其移动到主LRU的冷端头,TCH为1。如是TCH>=2的块,则将其移动到热端头,TCH清零。如果是脏块,则将其移动到主LRUW上。依此规则向前搜索查找可用块。(SMON每3秒,从主LRU冷端查找TCH小于2的非脏块到辅助LRU确保辅助LRU中有可用BUFFER)
13.如果从主LRU最尾端向前搜索了40%(隐含参数_db_block_max_scan_pct)还未找到可用块,则将触发DBWR写LRUW上的脏块--(CKPTQ队列的写不涉及LRUW,只有DBWR会写LRUW上脏块,并且写的是辅助LRUW上的全部脏块-每三秒醒来也要全部写出LRUM上所有块才会休眠--增量检查点只写一部分。。DBWR进程写时或者SMON进程每三秒本来时(LRUW进程不像辅助LRUW那样,非DBWR进程也允许访问),会将主LRUW上的一部分脏块移动到辅助LRUW。并且在DBWR写出过程中,会产生free buffer waits),写出后的buffer将重新挂载到辅助LRU上并变为可用。