对于日志缓冲区来说,设置过小,容易引起log buffer space等待事件。但也不是说设置得越大就越好的,设置过大,由于LGWR进程会不断启动刷新日志缓冲区从而释放内存,所以可能会根本用不上多余的内存,从而浪费内存。
 
设置合适的日志缓冲区大小,目的是为了能够让LGWR进程合理地触发。理想情况下是,一方面,在LGWR进程向联机日志文件中写重做记录时,日志缓冲区中还是有剩余的可用空间以供其他进程所使用;另一方面,当LGWR进程完成时,日志缓冲区中的剩余可用空间不要很多,因为这时由LGWR所写入日志文件的日志块就可以释放出来了,成为新的剩余可用空间。然后,LGWR可以再次启动刷新脏的日志块。如此良性循环,就能在满足性能的前提下,充分利用日志缓冲区。没必要盲目地把日志缓冲区设置得很大,完全可以把节省下来的内存交给比如数据块缓冲区(buffer cache)等这样更需要内存的组件。
 
我们已经知道,当重做记录达到日志缓冲区的1/3或1MB时,就会触发LGWR进程。也就是说,Oracle默认认为LGWR进程在写日志缓冲区大小的1/3或1MB的重做记录的过程中,剩下的日志缓冲区可以供新的重做记录的需要。当LGWR写完以后,那么这1/3或1MB的日志缓冲区就又可以成为可用的日志块以容纳新的重做记录了。由此,我们可以很容易推导出,当我们设置日志缓冲区达到3MB(3×1MB)以上时,这时多余出来的日志缓冲区实际上并不能用得上,换句话说,多余出来的内存就被我们浪费了。
 
在设置日志缓冲区时,可以参考下面这个建议的公式来计算:1.5×(平均每个事务所产生的重做记录大小×每秒提交的事务数量)。
 
首先先找到总事务量是多少:
select a.value as trancount from v$sysstat a,v$statname b
where a.statistic# = b.statistic# and b.name = 'user commits';
 
然后,找到系统总共的运行时间:
select trunc(sysdate - startup_time)*24*60*60 as
seconds from v$instance;
 
第三,找到产生的所有重做记录大小:
select value as redoblocks from v$sysstat where name =
'redo blocks written';
 
最后,我们可以分别计算公式中的值:平均每个事务所产生的重做记录大小= redoblocks/trancount;每秒提交的事务数量=trancount/seconds。这样,最后所建议的日志缓冲区的大小可以写为:1.5×(redoblocks/trancount)×(trancount/seconds)。