log buffer及日志管理深入分析及性能调整(三)
3.3 log buffer的设置
对于日志缓冲区来说,设置过小,容易引起log buffer space等待事件。但也不是说设置的越大就越好的,设置过大,由于LGWR进程会不断启动刷新日志缓冲区从而释放内存,所以可能会根本用不上多余的内存,从而浪费内存。
设置合适的日志缓冲区大小,目的是为了能够让LGWR进程合理的触发。理想情况下是,一方面,在LGWR进程向联机日志文件中写重做记录时,日志缓冲区中还是有剩余的可用空间以供其他进程所使用;另一方面,当LGWR进程完成时,日志缓冲区中的剩余可用空间不要很多,因为这时LGWR所写入日志文件的日志块就可以释放出来了,成为新的剩余可用空间。然后,LGWR可以再次启动刷新脏的日志块。如此良性循环,就能在满足性能的前提下,充分利用日志缓冲区。没必要盲目的把日志缓冲区设置的很大,完全可以把节省下来的内存交给比如数据块缓冲区(buffer cache)等这样更需要内存的组件。
我们已经知道,当重做记录达到日志缓冲区的1/3或1M时,就会触发LGWR进程。也就是说,oracle缺省认为LGWR进程在写日志缓冲区大小的1/3或1M的重做记录的过程中,剩下的日志缓冲区可以供新的重做记录的需要。当LGWR写完以后,那么这1/3或1M的日志缓冲区就又可以成为可用的日志块以容纳新的重做记录了。由此,我们可以很容易推导出,当我们设置日志缓冲区达到3M(3×1M)以上时,这时多余出来的日志缓冲区实际上并不能用得上,换句话说,多余出来的内存就被我们浪费了。
不过,本质上,这个启动LGWR的限度值是由一个隐藏参数:_log_io_size决定的,如下所示。该参数表示日志缓冲区中存在多少个脏日志块时触发LGWR进程写脏日志块。缺省情况下,该参数为0,表示当脏日志块占日志缓冲区的1/3时触发LGWR进程。如果设置了该参数为一个非0值,则如果该参数值不大于日志缓冲区大小的1/2时,该参数值作为启动LGWR的限度值。否则,如果该参数值大于日志缓冲区的1/2时,忽略该参数值,以日志缓冲区大小的1/2为启动LGWR的限度值。不管怎么样,脏日志块的容量只要超过1M,就必然触发LGWR进程。
在设置日志缓冲区时,可以参考下面这个建议的公式来计算:1.5×(平均每个事务所产生的重做记录大小×每秒提交的事务数量)。SQL> select x.ksppinm, y.ksppstvl, x.ksppdesc from x$ksppi x , x$ksppcv y
2 where x.indx = y.indx and ksppinm like '%_log_io_size%';
KSPPINM KSPPSTVL KSPPDESC
------------- ---------- -------------------------------------------------------
_log_io_size 0 automatically initiate log write if this many redo blocks in buffer
首先先找到总事务量是多少:
然后,找到系统总共的运行时间: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;
第三,找到所产生的所有重做记录大小:
最后,我们可以分别计算公式中的值:平均每个事务所产生的重做记录大小= redoblocks/trancount;每秒提交的事务数量=trancount/seconds。 这样,最后所建议的日志缓冲区的大小可以写为:select value as redoblocks from v$sysstat where name = 'redo blocks written';
1.5* (redoblocks/trancount)* (trancount/seconds)
0
相关文章
