在Oracle中如何调整 I/O 相关的等待
这个等待事件是指等待Oracle的前台的COMMIT和ROLLBACK操作进程完成,有时候这个等待事件也会包括等待LGWR进程把一个会话事务的日志记录信息从日志缓冲区中写入到磁盘上的重做日志文件中。因此,当前台进程在等待这个事件的时候,LGWR进程同时也在等待事件log file parallel write。理解什么造成这个等待事件的关键在于对比这个等待事件和log file parallel write等待事件的平均等待时间:如果它们的等待时间差不多,那么就是重做日志文件的I/O引起了这个等待事件,则需要调整重做日志文件的I/O,这个在之后会有详细的讲述。如果log file parallel write等待事件的平均等待时间明显小于log file sync等待事件的等待时间,那么就是一些其他的写日志的机制在COMMIT和ROLLBACK操作的时候引起了等待,而不是I/O引起的等待,例如重做日志文件的latch的竞争,会伴随着出现latch free或者LGWR wait for redo copy等待事件。
在V$SESSION_WAIT这个视图里面,这个等待事件有三个参数P1、P2、P3,其中P1代表在日志缓冲区中需要被写入到重做日志文件中的缓存的数量,写入的同时会确认事务是否已经被提交,并且保留提交信息到实例意外中断之前,因此必须等待LGWR将P1数量的缓存写入重做日志文件为止。P2、P3属于无用的参数。
如果这个等待事件在整个等待时间中占了比较大的比重,可以从以下三个方面来调整这个等待事件:
调整LGWR进程使其具有更好的磁盘I/O吞吐量,例如不要将日志文件放置在RAID5的磁盘上。
如果存在很多执行时间很短的事务,可以考虑将这些事务集合成一个批处理事务以减少提交的次数,因为每次提交都需要确认相关的日志写入重做日志文件,因此使用批处理事务来减少提交的次数是一种非常行之有效的减少I/O的方法。
查看是否一些操作可以安全的使用NOLOGGING或者UNRECOVERABLE选项,这样可以减少日志的产生。
Ø log file sequential read等待事件
这个等待事件是指等待读取重做日志文件中的日志记录,等待的时间就是耗费在完成整个读取日志记录的物理I/O操作的时间。
在V$SESSION_WAIT这个视图里面,这个等待事件有三个参数P1、P2、P3,其中P1代表一个日志组里面所有日志文件的相对sequence号,P2代表日志文件在指定物理块大小的偏移量,P3代表读取BLOCK的数量,如果P3的值为1,一般来说都是在读取日志文件头。
Ø log file single write等待事件
这个等待事件是指等待写重做日志文件操作完成,常常是在等待写重做日志文件头,例如在增加一个新的重做日志组成员的时候,Oracle数据库就会往这个重做日志文件头写入相应的sequence号。
在V$SESSION_WAIT这个视图里面,这个等待事件有三个参数P1、P2、P3,其中P1代表正在被写入的重做日志文件组的组号,P2代表日志文件在指定物理块大小的偏移量,P3代表写入BLOCK的数量。
因为single write通常都是在写或者重写日志文件头的时候出现,因此开始的block号总是为1。一般如果出现这个等待事件,应该对重做日志文件尽量使用裸设备,避免将多个日志文件放在同一个磁盘上,减少产生I/O竞争的可能。
Ø switch logfile command等待事件
这个等待事件是指执行日志文件切换命令的时候等待日志文件切换完成,Oracle数据库会每隔五秒钟就检测一次是否超时。
如果出现这个等待事件,表明花费了很长的时间去切换重做日志文件,此时我们需要去检查数据库的告警日志文件查看Oracle后台进程LGWR是否正常在工作。
Ø log file switch completion等待事件
这个等待事件是指由于当前重做日志文件已经被写满了而Oracle后台进程LGWR需要完成写完当前重做日志文件并且要打开一个新的重做日志文件而导致的重做日志文件切换的等待,或者是其他请求需要切换重做日志文件导致等待。
如果当前的重做日志写满了,这个时候Oracle数据库就需要切换重做日志文件来提供足够的磁盘空间给重做日志写日志缓存。但是由于一些其他的进程也同样可以引起重做日志的切换,Oracle数据库不会同时去切换重做日志两次,因此,就出现了这个等待事件,在Oracle数据库早期的版本中还有log_file_switch_checkpoint_incomplete、log_file_switch_archiving_needed、log_file_switch_clearing_log_file的等待事件。
Ø log file switch (checkpoint incomplete) 等待事件
这个等待事件是指由于当前重做日志的检查点没有及时的完成而导致重做日志文件无法切换到下一个日志文件引起的日志文件切换的等待。
调整这个等待事件的方法一般是加速检查点的完成,可以通过减小buffer cache缓冲区或者增加更多的DBWR进程、调整相关检查点的初始化参数等方法来达到相应的效果。
Ø log file switch (archiving needed)等待事件
这个等待事件是指当前的重做日志文件准备切换到下一重做日志文件,但是当前重做日志文件因为没有被归档而导致等待,这个等待事件只出现于采用了归档方式的Oracle数据库中。
如果出现这个等待事件,首先应该查看Oracle数据库的告警日志文件,看是否因为写归档日志文件错误导致归档进程停止,其次,可以增加归档进程的数量或者将归档日志文件存放到I/O速度比较快的磁盘上,还可以通过增大和增加重做日志文件的大小和数量来给予归档更多的时间。
高速缓存区相关的I/O等待事件:
Ø db file parallel write等待事件
这个等待事件是指Oracle后台进程DBWR等待一个并行写入文件或者是BLOCK的完成,等待会一直持续到这个并行写入操作完成。
在V$SESSION_WAIT这个视图里面,这个等待事件有三个参数P1、P2、P3,其中P1代表Oracle正在写入的数据文件的数量,P2代表操作将会写入多少的BLOCK数量,P3在Oracle9i release2版本之前代表总共有多少BLOCK的I/O请求,等于P2的值;在Oracle9i release2版本之后则代表等待I/O完成的超时的时间,单位是百分之一秒。
这个等待事件即使在总的等待时间中占的比例比较大也不会对用户的会话有很大的影响,只有当用户的会话显示存在大量的等待时间消耗在"write complete waits" 或者是"free buffer waits"上的时候才会影响到用户的会话,较明显的影响是这个写操作的等待会影响到读取同一个磁盘上数据的用户会话的I/O。
Ø db file single write等待事件
这个等待事件通常是表明在等待写入数据到数据文件头。
在V$SESSION_WAIT这个视图里面,这个等待事件有三个参数P1、P2、P3,其中P1代表Oracle正在写入的数据文件的文件号:
SELECT * FROM v$datafile WHERE file# = <file#>;
P2代表Oracle正在写入的BLOCK号,如果BLOCK号不是1,则可以通过如下查询查出Oracle正在写入的对象是什么:
SELECT segment_name , segment_type ,
owner , tablespace_name
FROM sys.dba_extents
WHERE file_id = <file#>
AND <block#>
BETWEEN block_id AND block_id + blocks -1;
P3代表Oracle写入file#的数据文件中从BLOCK#开始写入的BLOCK的数量。
Oracle数据文件的文件头一般来说都是BLOCK1,操作系统指定的文件头是BLOCK0,如果BLOCK号大于1,则表明Oracle正在写入的是一个对象而不是文件头。
Ø write complete waits等待事件
这个等待事件表明Oracle的会话在等待写入缓存,一般都是缓存的正常老化或者是实例之间的互相调用引起的。
在V$SESSION_WAIT这个视图里面,这个等待事件有三个参数P1、P2、P3,其中P1代表Oracle正在写入的数据文件的文件号,P2代表Oracle正在写入的BLOCK号,可以通过如下查询查出Oracle正在写入的对象是什么:
SELECT segment_name , segment_type ,owner , tablespace_name
FROM sys.dba_extents
WHERE file_id = <file#>
AND <block#> BETWEEN block_id AND block_id + blocks -1;
P3代表产生这个等待事件原因的id号,具体的id号所代表的原因如下:
1022 无
1027 在写入过程中的buffer,最多等待1秒后会重新扫描cache
1029 试图应用改变到正在写入中的BLOCK,会一直等到BLOCK可用,每次等待的时间都是1秒
1030 无
1031 无
1033 无
1034 实例间的交叉写:一个实例企图去修改一个BLOCK,而另外一个实例想去获得此BLOCK的状态,这个实例产生最多一秒钟的等待
1035 与1034一样,但是产生的原因是由于数据库出于热备的状态下
当Oracle的后台进程DBWR获取可以写入的缓存并标记这些缓存为正在写入的状态,接着这些被收集的缓存中的数据将会被写入磁盘上的数据文件中,当所有的I/O完成后将清除在原来那些被标记的缓存上的标记,这个等待事件出现意味着Oracle想获取的buffer已经被标记为正在写入的状态,只有等标记被清除才能获取到相应的buffer。在Oracle7.2以前的版本中,只有当批处理中所有的buffer都被写入磁盘后标记才被清除,在这之后的版本,每个buffer写入磁盘后就将清除在这个buffer上的标记了。
增加更多的Oracle后台DBWR进程或者是采用异步I/O都将能减少这个等待事件的产生。
Ø free buffer waits等待事件
这个等待事件出现的原因比较多,大致可以分为以下几种:
当一个数据文件从只读状态变成为可读写状态的时候,所有的buffer gets全部都被挂起了,就可能出现这个等待事件。已经存在的所有buffer都必须要失效,因为它们没有链接到lock elements(OPS/RAC环境下时需要)。因此,只有当这些buffers失效完成后才能够被分配给数据库块地址。
当Oracle数据库需要从系统全局区(SGA)中读取一个buffer给一致性读(CR)操作,只读操作或者是用于任何恢复模式中的操作的时候,也可能出现这个等待事件,此时可以加速Oracle后台的DBWR进程来获得较多的空闲buffer。
在检查了'free buffers inspected'之后也会出现这个等待事件,如果没有找到空闲的buffer,Oracle会等待1秒钟后继续试图去获取空闲的buffer。
在V$SESSION_WAIT这个视图里面,这个等待事件有三个参数P1、P2、P3,其中P1代表Oracle读取buffer而引起等待的数据文件的文件号,P2代表数据文件中读取buffer的BLOCK的号,P3代表要读取buffer的缓存中的BLOCK(7.3.X以上的版本)。
一般来说,这个等待事件都是由于Oracle的后台进程DBWR不能及时的将buffer写完到磁盘上的数据文件中而引起的,尽量将I/O平均分配到各个磁盘上,减少出现某个磁盘上I/O负载很高而引起DBWR进程写入慢的情况,可以通过操作系统上的I/O监控工具或者查询V$FILESTAT视图来获取相应的数据:
SELECT name, phyrds, phywrts
FROM v$filestat a, v$datafile b
WHERE a.file# = b.file#;
还可以通过查看数据文件上是否存在全表扫描来判断:
SELECT name, phyrds, phyblkrd, phywrts
FROM v$filestat a, v$datafile b
WHERE a.file# = b.file#
and phyrds!= phyblkrd;
需要注意在应用中要避免漏建立了索引,这样会引起I/O大幅度的增加,导致不必要的磁盘扫描,如果有多块硬盘来存储Oracle的数据文件,尽量使用操作系统的条带化软件来分布Oracle的数据文件使得I/O分配均匀。此外,大量的磁盘排序会导致存在很多的脏缓存需要写完,因此,临时表空间中的数据文件最好能分配到不同的磁盘上,避免同一个磁盘上的I/O竞争。还有如果排序的BLOCK的检查点没有完成,将会存在于正常的缓存写批处理中,如果缓存写批处理中全部都被排序块给占满了,那其他的脏数据块就没法被写入导致前台的应用不得不等待分配空闲的buffer。对于Oracle9i之后的版本,因为排序使用的块通常都是来自临时表空间文件,不会进入到缓存中,因此,由于大量排序引起的这种等待在9i中基本上就不会存在了。
了解了在Oracle数据库I/O性能或者是响应时间低下的时候该如何去调整和优化数据库,还有一点很重要的需要提及的是,无论是何种情况,都应该先去检查操作系统上的日志文件,因为如果是本身在操作系统级别上出现了I/O问题,那不管如何调整Oracle数据库都是徒劳的,所以必须首先要保证在操作系统级别上I/O不存在问题,然后再去Oracle数据库中具体的检查问题产生的原因。
四、 结论
不管用何种方法去解决Oracle数据库的I/O性能问题,关键都是先找出产生I/O性能问题的根本最终原因,然后想各种各样的办法去解决产生的原因就可以达到优化数据库的目的了。以上所谈到的都是关于Oracle数据库I/O调整优化的一些基本概念和方法,希望能起到一个抛砖引玉的作用,以便能够更好的深入理解Oracle数据库I/O性能方面的知识。
本文作者:叶梁
建议继续学习:
- 关于IO的同步,异步,阻塞,非阻塞 (阅读:14482)
- Linux服务器性能评估 (阅读:8192)
- 提升磁盘IO性能的几个技巧 (阅读:7606)
- I/O模型-读书笔记 (阅读:6920)
- Innodb IO优化-配置优化 (阅读:6662)
- 查看 CPU, Memory, I/O and NetFlow (阅读:6446)
- blktrace 深度了解linux系统的IO运作 (阅读:6012)
- Linux操作系统内核3.3版本I/O Stack的流图 (阅读:5781)
- Linux IO协议栈框图 (阅读:5340)
- MySQL Tuning之浅析I/O优化 (阅读:5147)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:eygle@eygle.com(eygle) 来源: Oracle Life
- 标签: IO
- 发布时间:2011-12-18 23:20:49
- [52] IOS安全–浅谈关于IOS加固的几种方法
- [51] android 开发入门
- [50] 如何拿下简短的域名
- [49] Oracle MTS模式下 进程地址与会话信
- [48] 图书馆的世界纪录
- [47] 【社会化设计】自我(self)部分――欢迎区
- [46] Go Reflect 性能
- [43] 读书笔记-壹百度:百度十年千倍的29条法则
- [37] 视觉调整-设计师 vs. 逻辑
- [34] 程序员技术练级攻略