每个数据块缓冲单元的可以有三种类型
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. pinned 正在被使用的
2. free 可以被分配
3. dirty 已经被修改,还未写入磁盘
下面是他们的转化关系
1. 申请一个free的db_block_buff
2. 因为有程序使用,他的状态就变成pinned
3. 如果程序修改了他,等到程序释放了他,他的状态就变成dirty
4. 如果程序没有修改他,等到程序释放了他,他的状态就变成free
5. DBWR将dirty状态的数据块写入磁盘后,数据块缓冲状态变成free free缓冲在LRU的最后面 问题:
如果数据库做的修改操作很少,在部分是查询操作,服务进程将数据从文件中读入缓存,将free块全部占满,那服务进程在查找空闲块的时候就找不到空闲块,即使把所有的脏数据都写入文件所得到的空闲块也不足以容纳新的数据,这种情况下怎么得到空闲块呢?
我的疑问就是什么样的块才算是free呢,如果空闲块上已经填上数据(但不是脏数据),也不是当前正在使用的数据,那这个块算不算是空闲块呢?
这个问题问得好 确实从来没考虑过这一点
我说说我的看法吧
ORACLE在扫描LRU LIST的时候超过一定的阀值(比如说40%)了以后就会停止搜索FREE BUFFER,转而去通知DBWR进行写操作。
不过好像这样依然不能解决你这里说的问题 因为大部分都是PINNED 而并不是DIRTY2
根据你前面描述中的第4点
算空闲块
如果应用偏向于大量的读取和查询操作时,把buffer填满不是很容易的事吗?到时再有新的查询又该如果取得free或clean块呢?这就是我想不明白的地方
比如现在说有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
以此类推……
明白了吧 呵呵
是在没有任何dirty块的时候才会按LRU算法来复用呢?还是dirty块存在时,也会复用原来的有数据的块呢?
这样的话,如果有很多可复用的块,还有没有必要唤醒DBWn将脏块写入文件呢?