深入解析DBWR

dbwr进程,Database Writer Process ,理论上最大支持20个dbwr进程,默认是 1/8 cpu_count的设置。dbwr进程的作用的将buffer cache的脏块写出到disk上。

dbwr进程写机制

首先我们要明白,dbwr进程的本质作用的是:将cache buffer中的脏块写入到disk上,使cache buffer尽量保持干净。那么这里就存在一个问题:dbwr 进程如何来写脏块?有什么机制会触发dbwr进程来写脏块? dbwr进程是怎么进行写操作的?
在讲dbwr是如何来写脏块的之前,我们需要了解下checkpoint 机制:

checkpoint queue: 检查点队列是从oracle 8i引入的,实际上是从引入增量检查点时引入的。 那么什么是检查点队列呢 ?实际上,检查点队列就是一个列表,而这个列表上包含一系列的buffer cache中的脏块,当然,这些脏块的顺序是最早被修改的脏块在前面,稍后被修改的脏块在后,总之是根据time来排序的。 每个checkpoint queue的一个位置我们称为postion,当然,这个postion就是通过rba来表示的。所以你可以理解为:checkpoint queue 就是一些 脏块对应的buffer header列表,每个buffer header里面还包含了rba信息,只是这些rba是有一定顺序的。每个rba都对应buffer cache中 的一个脏块,而脏块这里也是分时间前后的。

大家可以想象,oracle 的dbwn进程去写buffer cache中的脏块,是如何判断一个block是否被写或者不写的呢? 这跟oracle引入的一个LRU算法有关系(Least Recently Used). 通过该算法去判断哪些脏块需要put 到checkpoint queue上。LRU 链表,它上面的信息其实是一系列的buffer header,并不是我们实际的脏块。 每个buffer header里面存在一个指针,通过这个指针,可以定位到一个脏块,是一对一的关系。每次checkpoint 触发后,会触发dbwr去写脏块,dbwr进程根据checkpoint queue以及LRU-W ,顺序性的把脏块写出到disk上。

checkpoint触发的情况下,是根据checkpoint queue来写脏块,其他的一些触发机制,是根据LRU-W来的。

这里dbwr涉及2种情况写:

  • DBWR checkpoint buffers written —》 checkpoint queue的dbwr写块数
  • physical writes non checkpoint —》dbwr通过LRU-W写的脏块数

Performs writes for several reasons:

  • Make free requests
  • Checkpoints
  • Cleanout of cold dirty buffers
  • Ping writes

1)Make free requests

如果server process在搜索的lru没有发现可用的free buffer,那么就会等待DBWR进程写脏块,在等待的过程中,server process将会等待free buffer wait等待, 同时,如果你检测统计数据,你会发现dirty buffers inspected 指标的值会增加。

这个参数的意思是:表示已经扫描的buffer header的总数占整个LRU链表上buffer header总数的百分比值。服务器进程在LRU中搜索可重用Buffer时,遇到脏块,会将脏块移至lruw,等待三秒DBWR超时,LRUW中的脏块被DBWR写磁盘。注意,如果进程在LRU中遇到TCH大于等于2的脏块,不会将其移到LRUW,而会移到热LRU。另外,被移到LRUW中的脏块,将从检查点队列中去除。

2)Checkpoints

3) Cleanout of cold dirty buffers

4)Ping writes

5) timeout write

注意:dbwr还存在一个固定唤醒机制,在10g中每300s会唤醒一次,如下参数进行控制:

dbwr的写操作:

1) batch写

每个Batch中IO是异步,Batch与Batch之间为串行。比如,某个Batch是100个块,发现相连的块有50个、40个、8个,还有两个块不相连,将50个块从Buffer Cache的不同位置复制到共享池中一块连续的大内存中(此时如果内存不足,会报4031),提交异步IO,将此连续的大块内存写磁盘。再将40个块从Buffer Cache的不同位置也复制到共享池中一块连续的大内存,提交异步IO,等等。对于不相连的块,不在复制,直接提交异步IO从Buffer Cache写磁盘。然后等这个Batch中所有IO完成,开始下一个Batch。所有,Batch与Batch之间,是同步、串行的。

2) 合并写

第一个参数可以控制dbwr进程在写的时候,batch的大小,换句话讲,batch越大,batch写的次数就少。可以适当提高dbwr进程的性能。

注意:根据我在生产环境中的观察,该参数可能会导致dbwr进行消耗过多的内存。需要慎重。

3) 异步写

dbwr进程写在赃块时是进行异步写,该机制默认是开启的。不仅如此,对于batch的写操作,一个batch内的IO也是异步的。batch和batch写之间是串行的。

此条目发表在Oracle分类目录,贴了标签。将固定链接加入收藏夹。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注