| 网管联盟 | 网管论坛 | 网管u家 | 网管博客 | 网管软件 | 网管求职 | 小游戏 | 网管搜索 | 网管原创 | 网管聚合 | 网管读摘 | 网管焦点 | 世界素材 | 会员投稿 | 会员中心 |
![]() |
| Windows Linux Cisco 网络技术 数据库 黑客攻防 DotNet Java PHP 认证 新闻资讯 服务器 存储资讯 网络设备 网管学堂 技术专题 焦点 网吧频道 |
在hash chain上搜索的逻辑如下:
1) 比较buffer header上所记录的数据块的地址,如果不符合,则跳过该buffer header。
2) 跳过状态为CR的buffer header。
3) 如果遇到状态为READING的buffer header,则等待,一直等到该buffer header的状态改变以后再比较所记录的数据块的地址是否符合。
3.2 LRU和LRUW链表结构及其管理机制
3.2.1 LRU和LRUW链表结构概述
在前面,我们已经知道了oracle是如何在hash chain中搜索要找的数据块所对应的buffer header的过程,我们也知道如果在hash chain上没有找到所要的buffer header时,oracle会发出I/O调用,到磁盘上的数据文件中获取数据块,并将该数据块的内容拷贝一份到buffer cache中的内存数据块里(顺带提一句,内存数据块通常叫做buffer,而数据文件里的数据块通常叫做block,二者是一个意思)。这个时候,假如buffer cache是空的,比较好办,直接拿一个空的内存数据块来用即可。但是如果buffer cache中的内存数据块全都被用掉了,没有空的内存数据块了,怎么办?应该重新使用哪一个内存数据块?当然我们可以一个一个的比较内存数据块与其对应在数据文件中的数据块的内容是否一致,如果一致则可以将该数据块拿来,将其内容清空,然后拷贝上当前数据块的内容;如果不一致,则跳过,再找下一个。毫无疑问,这种方式效率低下。为了高效的管理buffer cache中的内存数据块,oracle引入了LRU和LRUW等链表等结构。 网管u家www.bitscn.net
在buffer cache中,最耳熟能详的链表可能就是LRU链表了。在前面描述buffer cache结构的图上,也可以看到有两个链表:LRU和LRUW。在介绍LRU和LRUW前,先说明几个概念。
1) 脏数据块(dirty buffer):buffer cache中的内存数据块的内容与数据文件中的数据块的内容不一致。
2) 可用数据块(free buffer):buffer cache中的内存数据块为空或者其内容与数据文件中的一致。注意,可用数据块不一定是空的。
3) 钉住的数据块(ping buffer):当前正在更新的内存数据块。
4) 数据库写进程(DBWR):这是一个很底层的数据库后台进程。既然是后台进程,就表示该进程是不能被用户调用的。由oracle内置的一些事件根据需要启动该进程,该进程用来将脏数据块写入磁盘上的数据文件。
LRU表示Least Recently Used,也就是指最近最少使用的buffer header链表。LRU链表串连起来的buffer header都指向可用数据块。而LRUW则表示Least Recently Used Write,也叫做dirty list,也就是脏数据块链表,LRUW串起来的都是修改过但是还没有写入数据文件的内存数据块所对应的buffer header。某个buffer header要么挂在LRU上,要么挂在LRUW上,不能同时挂在这两个链表上。
我们已经知道一个lru latch就是一个working set,那么working set的数量也就是lru latch的数量。而lru latch的数量是由一个隐藏参数:_db_block_lru_latches决定的。该参数缺省值为DBWR进程的数量×8。
该参数最小必须为8,如果强行设置比8小的数值,oracle将忽略你设置的值,而使用8作为该参数值。 网管有家www.bitscn.net
1SQL> alter system set "_db_block_lru_latches"=1 scope=spfile; 2
SQL> startup force 3
SQL> show parameter _db_block 4
NAME TYPE VALUE 5
------------------------------------ ----------- ------------------------------ 6
_db_block_lru_latches integer 8
网管联盟bitsCN@com
3.2.2 深入LRU链表
我们已经知道LRU链表是用来查找可以重用的内存数据块的,那么oracle是怎么使用LRU链表的呢?这里需要分为8i之前和8i以后两种情况。
在8i之前,我们举一个例子。假设buffer cache只能容纳4个数据块,同时只有一个hash chain和一个LRU。当数据库刚刚启动,buffer cache是空的。这时前台进程发出SELECT语句获取数据块时,oracle找一个空的内存数据块,并将其对应的buffer header挂到hash chain上。同时,oracle还会把该buffer header挂到LRU的最尾端。随后前台进程又发出SELECT语句,这时所找到的buffer header在LRU上会挂到前一个buffer header的后面,也就是说第二次SELECT语句所找到的buffer header现在变成了LRU的最尾端了。假设发出4句SELECT以后找到了4个buffer header,从而用完了所有的buffer cache空间。这个时候的LRU可以用下图二来表示。
网管有家www.bitscn.net
中国网管论坛bbs.bitsCN.com
网管u家www.bitscn.net
这个时候,发来了第五句SELECT语句。这时的buffer cache里已经没有空的内存数据块了。但是既然需要容纳下第五个数据块,就必然需要找一个可以被替换(后面会看到类似牺牲、重用的字样,它们和替换都是一个意思)的内存数据块。这个内存数据块会到LRU上去找。按照oracle设定的最近最少使用的原则,位于LRU最尾端的BH1将成为牺牲者,oracle会把该BH1对应的内存数据块的内容清空,并将当前第五句SQL所获得的数据块的内容拷贝进去。这个时候,BH1就成了LRU的首端,而BH2则成为了LRU的尾端。如下图三所示。在这种方式下,经常被访问的数据块可以一直靠近LRU的首端,也就保证了这些数据块可以尽可能的不被替换掉,从而保证了访问的效率。
网管下载dl.bitscn.com
网管联盟bitsCN@com
图三
网管u家www.bitscn.net
中国网管论坛bbs.bitsCN.com
|
0
|
评论加载中…