每个数据块缓冲单元的可以有三种类型 
    1. pinned 正在被使用的 
    2. free    可以被分配 
    3. dirty  已经被修改,还未写入磁盘 
下面是他们的转化关系 
    1. 申请一个free的db_block_buff 
    2. 因为有程序使用,他的状态就变成pinned 
    3. 如果程序修改了他,等到程序释放了他,他的状态就变成dirty 
    4. 如果程序没有修改他,等到程序释放了他,他的状态就变成free 
    5. DBWR将dirty状态的数据块写入磁盘后,数据块缓冲状态变成free free缓冲在LRU的最后面 问题: 
    如果数据库做的修改操作很少,在部分是查询操作,服务进程将数据从文件中读入缓存,将free块全部占满,那服务进程在查找空闲块的时候就找不到空闲块,即使把所有的脏数据都写入文件所得到的空闲块也不足以容纳新的数据,这种情况下怎么得到空闲块呢? 
    我的疑问就是什么样的块才算是free呢,如果空闲块上已经填上数据(但不是脏数据),也不是当前正在使用的数据,那这个块算不算是空闲块呢? 

解决方案 »

  1.   

    1
    这个问题问得好 确实从来没考虑过这一点
    我说说我的看法吧
    ORACLE在扫描LRU LIST的时候超过一定的阀值(比如说40%)了以后就会停止搜索FREE BUFFER,转而去通知DBWR进行写操作。
    不过好像这样依然不能解决你这里说的问题 因为大部分都是PINNED 而并不是DIRTY2
    根据你前面描述中的第4点  
    算空闲块
      

  2.   

    首先,还有一种数据块(clean buffer)你这里没有提到,也就是和脏buffer相对的,这类块也是其中进行分配的buffer。数据库可用的buffer都是通过LRU list来进行分配的,上面WH提到了,当扫描一定的值发现没有可用的话,会启动DBWR把脏块写入,这样脏块就变成clean叻,也就是可以分配的了, 至于你这里提到的如果没有发现任何可用的块的话,会有latch等待,直到有可用的内存块找到,不过我想,你说的这样的case可能性不大,毕竟不会有这样的应用,会hold这么大块的数据什么都不动的。什么是free,free就是自由buffer,也就是什么都没有的空闲buffer。 这是窄义上的认识,广义上,我们可以把free和clean的数据库看做是可用数据buffer。
      

  3.   

    请问inthirties
       如果应用偏向于大量的读取和查询操作时,把buffer填满不是很容易的事吗?到时再有新的查询又该如果取得free或clean块呢?这就是我想不明白的地方
      

  4.   

    大量的读取,如果buffer不够了,就会清除它们,再load新的到buffer里来呀。
      

  5.   

    哦……突然理解楼主的困惑所在了呵呵 首先谢谢inthirties老大的回答哦举个例子来说形象一些吧
    比如现在说有5个BUFFER 3个FREE 2个DIRTY
    现在执行了大量SELECT 已经占用了满了3个FREE BUFFER
    那么这个时候如果继续进行查询操作 那么就会触发DBWR去把2个DIRTY BUFFER写入数据文件
    然后查询操作就可以从数据文件中读取相应的数据到这两个BUFFER中
    注意哦 现在5个BUFFER可都没有DIRTY的了
    你的疑问就是 如果现在再不断的进行查询 那么系统该把从数据文件中读取进来的输入放到什么地方呢?
    这个时候ORACLE就会重用这5个BUFFER呀 
    比如说1、2、3、4、5
    虽然里面已经存了一些数据了 可并不是必须保存在BUFFER中的
    至于算法嘛 我猜也是LRU吧
    这时的一个SELECT可能会把数据读入5、4两个BUFFER中
    如果再来一个SELECT 需要两个BUFFER
    那么就用3、2两块BUFFER
    以此类推……
    明白了吧 呵呵
      

  6.   

    这样解说我明白,只是不了解的是,oracle也没有提到什么样的有数据的块会被重用,是按什么机制来复用的?
    是在没有任何dirty块的时候才会按LRU算法来复用呢?还是dirty块存在时,也会复用原来的有数据的块呢?
    这样的话,如果有很多可复用的块,还有没有必要唤醒DBWn将脏块写入文件呢?
      

  7.   

    DIRTY块存在的时候会去通知DBWR把DIRTY块写入数据文件 重用这些DIRTY块而如果像你说的那种情况 没有DIRTY块的时候 就是采用LRU算法重用这些所谓PINNED的BUFFER了