log buffer及日志管理深入分析及性能调整(七)

3.2.2 其他相关的等待事件
        当进程需要向日志缓冲区里拷贝重做记录时,发现没有足够的可用空间时,则必须等待log buffer space事件。如果一个进程花费了太多的时间在log buffer space等待事件上,这通常是由于下面两个原因:
1)      日志缓冲区尺寸太小。对于一个繁忙的批处理数据库系统里,一个太小的日志缓冲区(小于512K)会导致进程等待log buffer space
2)      LGWR进程太慢了,这也就是物理I/O速度过慢。可以通过检查log file parallel write等待事件的平均等待时间来判断,如果大于10毫秒,则说明LGWR过慢。
可以通过增加日志缓冲区的尺寸或加快LGWR的进程来减少log buffer space等待事件。
 
        而较小尺寸的联机日志文件会引起log file switch completionlog file switch (checkpoint incomplete)
这两个等待事件。log file switch completion表示进程正在等待日志切换完成。而当应用程序产生很多重做,然后由LGWR进程非常快得写日志文件并进行日志切换时,这时DBWR进程还没有把脏数据块写入磁盘以通知checkpoint结束时,这个时候产生log file switch (checkpoint incomplete)等待事件。可以通过增加联机日志文件的尺寸来减少log file switch completionlog file switch (checkpoint incomplete)
 
        使用如下SQL来显示有关日志缓冲区的latch freemisrate是否很大。

select name,gets,misses,to_char((misses/(gets+misses)) * 100,'990.99') misrate

from v$latch where name in ( 'redo allocation' , 'redo copy', 'redo writing')

如果是redo copy的丢失率很严重,则可以考虑增加隐藏参数:_log_simultaneous_copies的值。该参数定义了redo copy latch的数量,该参数缺省为CPU数量的两倍。从8i起,该参数成为隐藏参数,因为不适合为系统增加过多的redo copy latch,特别是在OLTP环境中。增加该参数可以减少前台对redo copy latch的等待,但是要注意,过多的redo copy latch可能会使得LGWR等待更长的时间。因为前面我们已经知道,LGWR在确定了要写哪些日志块以后,会等待前台进程完成对这些日志块的操作以后,才开始正式写入。所以,如果很多的前台进程都可以获得redo copy latch以后,就可能引起LGWR要等很长时间才能开始正式写入。

如果是redo allocation的丢失率很严重,需要考虑是否有可能减少重做记录的生成。具体可以看下面有关如何减少重做记录的部分。8i以前,存在一个参数:log_small_entry_max_size,该参数说明了当重做记录的尺寸小于该参数指定值时,使用redo allocation latch来保护重做记录拷贝到日志缓冲区的过程,否则,如果重做记录大于该参数值时,使用redo copy latch来保护这个过程。但是从8i以后,取消了该参数,只要拷贝重做记录到日志缓冲区,就获得redo copy latch

如果是redo writing的丢失率很严重,则说明LGWR写的时间过长,导致其他进程无法获得该latch。这时可以通过减小_log_io_size来增加LGWR写的频率。具体_log_io_size的用法可以参考下面log buffer的设置部分。

3.3 log buffer的设置

对于日志缓冲区来说,设置过小,容易引起log buffer space等待事件。但也不是说设置的越大就越好的,设置过大,由于LGWR进程会不断启动刷新日志缓冲区从而释放内存,所以可能会根本用不上多余的内存,从而浪费内存。

设置合适的日志缓冲区大小,目的是为了能够让LGWR进程合理的触发。理想情况下是,一方面,在LGWR进程向联机日志文件中写重做记录时,日志缓冲区中还是有剩余的可用空间以供其他进程所使用;另一方面,当LGWR进程完成时,日志缓冲区中的剩余可用空间不要很多,因为这时LGWR所写入日志文件的日志块就可以释放出来了,成为新的剩余可用空间。然后,LGWR可以再次启动刷新脏的日志块。如此良性循环,就能在满足性能的前提下,充分利用日志缓冲区。没必要盲目的把日志缓冲区设置的很大,完全可以把节省下来的内存交给比如数据块缓冲区(buffer cache)等这样更需要内存的组件。

我们已经知道,当重做记录达到日志缓冲区的1/31M时,就会触发LGWR进程。也就是说,oracle缺省认为LGWR进程在写日志缓冲区大小的1/31M的重做记录的过程中,剩下的日志缓冲区可以供新的重做记录的需要。当LGWR写完以后,那么这1/31M的日志缓冲区就又可以成为可用的日志块以容纳新的重做记录了。由此,我们可以很容易推导出,当我们设置日志缓冲区达到3M3×1M)以上时,这时多余出来的日志缓冲区实际上并不能用得上,换句话说,多余出来的内存就被我们浪费了。

不过,本质上,这个启动LGWR的限度值是由一个隐藏参数:_log_io_size决定的,如下所示。该参数表示日志缓冲区中存在多少个脏日志块时触发LGWR进程写脏日志块。缺省情况下,该参数为0,表示当脏日志块占日志缓冲区的1/3时触发LGWR进程。如果设置了该参数为一个非0值,则如果该参数值不大于日志缓冲区大小的1/2时,该参数值作为启动LGWR的限度值。否则,如果该参数值大于日志缓冲区的1/2时,忽略该参数值,以日志缓冲区大小的1/2为启动LGWR的限度值。不管怎么样,脏日志块的容量只要超过1M,就必然触发LGWR进程。

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

在设置日志缓冲区时,可以参考下面这个建议的公式来计算: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)

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9842/viewspace-414951/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/9842/viewspace-414951/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值