对于绝大多数系统,只要IO能力足够并且DB CACHE足够大,那么一般情况下,单个DBWR进程基本上是能够胜任的。不过对于IO十分敏感的系统,使用多个DBWR进程有助于提高脏数据块写的性能。从Oracle 8.0开始(严格的说是8.0.4),DBWR的算法发生了革命性的变化。Oracle 7虽然也支持多个DB WRITER进程,但是这些DB WRITER 进程之间是有区别的,其中一个是MASTER,其他几个是SLAVER。SLAVER进程是不能使用异步IO的,只能使用模拟的异步IO。从Oracle 8.0.4开始,DBA可以使用2种策略来配置DBWR,一种是单个DBWR进程加上多个IO SLAVER进程;另外一种方法是配置多个DBWR进程。不论是使用DBWR还是IO SLAVER,都可使用异步IO。这种改进大大提高了数据库写IO的性能。
如果使用Oracle 8以上的版本,如何配置DBWR,是使用多个DB WRITER进程还是一个DB WRITE进程加上多个IO SLAVER进程呢?实际上这两种配置方法,很难分出一个优劣来,在不同的系统上,可能两种配置的效果差不多,也许有所区别。具体使用哪种方式,只有做过实验才能有个清楚的结论。十年前,关于这两种方法的优劣,在网上有过一场论战,最终论战双方也都无法说服对方。实际上,在当时的系统配置情况下,这两种方式的主要区别在于,如果使用单一的DBWR进程加上多个IO SLAVER进程,那么这种配置和Oracle7的多DBWR进程的机制是类似的,和Oracle 7不同的只是SLAVER进程支持异步IO。由MASTER 的DBWR进程来管理LRU链,而实际的IO操作是由SLAVER进程完成的。
如果使用多个DBWR进程,那么每个DBWR管理LRU链的一个子区域。每个DBWR都有自己的LRU LATCH,对于ORACLE 8和Oracle 8i,LRU LATCH通过参数DB_BLOCK_LRU_LATCHES来设置(Oracle 9i以后的版本中取消了这个参数,自动设置为每个DB CACHE的LRU LATCH 数量是CPU数量的一半)。
DB_BLOCK_LRU_LATCHES定义了所有的DB CACHE的LRU LATCH的总数。一般来说建议,该参数设置为不超过CPU的数量(Oracle 8i,DB_BLOCK_LRU_LATCHES的最大值为CPU数量的6倍)。而一般情况下,DBWR的数量也不应该超过DB_BLOCK_LRU_LATCHES的数量,否则会形成LRU闩锁的竞争。Oracle 8/8i对于使用多缓冲的情况,除了DEFAULT POOL以外,每个POOL的LATCH的数量缺省为1个,也可以在DB_BUFFER参数设置的时候指定LATCH的数量,DEFULT POOL的LATCH的数量是总数减去其他BUFFER的LATCH的数量。
随着硬件技术的发展,目前的系统拥有更多的CPU,更大的内存和更快的IO子系统。在现在的系统中,配置DBWR不仅仅要根据IO的能力,更重要的是现在的DB CACHE已经不是10多年前那样,几个G的DB CACHE就算是超大型的系统了。现在的系统中,几十G甚至几百G的DB CACHE比比皆是。因此LRU的管理性能成为一个十分重要的考虑因素。因此由单个DBWR来管理LRU显然是不合适的。使用多个DBWR进程成为主要的选择。
基于上面的关于DBWR的基础知识,在设置DBWR数量的时候,我们可以如此考虑:
l 一般情况下,如果没有发现明显的DBWR问题,那么不需要使用多个DBWR
l 如果确实需要使用多个DBWR,那么对于多CPU系统,一般可以直接使用多个DBWR,对于单CPU的系统,可以采用一个DBWR加上多个IO SLAVER的方式。这条经验不是绝对的,为了确保获得最好的性能,最好是两种方式都尝试一下
l 如果你使用的是9i或者更新的版本,对于IO不存在严重瓶颈的系统,就毫不犹豫的使用多个DBWR吧
l 使用多个DBWR,建议DBWR的数量不超过CPU的数量(对于ORACLE 8/8I,DBWR的数量不超过DB_BLOCK_LRU_LATCHES)
那么我们如何来判断目前的DBWR是否足够呢?STATSPACK报告或者AWR报告是十分好的工具。
Free Writ Buffer
Number of Pool Buffer Physical Physical Buff Comp Busy
P Buffers Hit% Gets Reads Writes Wait Wait Waits
--- ---------- ---- -------------- ------------ ----------- ---- ---- ----------
D 4,405,998 98 945,225,805 21,899,493 2,291,122 0 0 5,692,101
如果经常会有write complete waits存在,那么就说明DBWR的写性能不足,可以考虑通过增加DBWR来改善脏块写的性能。另外,经常出现free buffer waits的问题,如果我们无法通过扩大DB CACHE来改善DB CACHE的性能,那么增加DBWR的数量,也可以从另外一个侧面改善这方面的问题。
最后要强调的一点是,不要误解了本文的观点,由于本文介绍的内容是从Oracle 7到现在的11.2各个版本的情况,因此有些观点可能更适合于早期的Oracle 版本。在10g或者11g中,大家不需要花费太多的精力纠结于DBWR的配置,大多数情况下,缺省的配置就是没问题的。只有少数情况,我们需要增加DBWR的数量。增加DBWR的操作是个很专业的操作,一定要在深思熟虑后再去调整。