Oracle Study之--Oracle等待事件(4)

Db file scattered read
这个等待事件在实际生产库中经常可以看到,这是一个用户操作引起的等待事件,当用户发出每次I/O需要读取多个数据块这样的SQL 操作时,会产生这个等待事件,最常见的两种情况是全表扫描(FTS: Full Table Scan)和索引快速扫描(IFFS: index fast full scan)。
这个名称中的scattered( 分散),可能会导致很多人认为它是以scattered 的方式来读取数据块的,其实恰恰相反,当发生这种等待事件时,SQL的操作都是顺序地读取数据块的,比如FTS或者IFFS方式(如果忽略需要读取的数据块已经存在内存中的情况)。
这里的scattered指的是读取的数据块在内存中的存放方式,他们被读取到内存中后,是以分散的方式存在在内存中,而不是连续的。
这个等待事件有三个参数:
File#: 要读取的数据块所在数据文件的文件号。
Block#: 要读取的起始数据块号。
Blocks: 需要读取的数据块数目。


案例分析:

12:04:54SYS@prod>selectevent,TOTAL_WAITS,AVERAGE_WAITfromv$system_event12:04:592whereupper(event)like'DBFILE%';EVENTTOTAL_WAITSAVERAGE_WAIT---------------------------------------------------------------------------------------dbfilesequentialread5069.02dbfilescatteredread930.03dbfilesinglewrite27.36dbfileparallelwrite1514.24dbfileparallelread34.64Elapsed:00:00:00.1212:06:53SCOTT@prod>select*fromt1;12:05:04SYS@prod>selectevent,TOTAL_WAITS,AVERAGE_WAITfromv$system_event2*whereupper(event)like'DBFILE%'EVENTTOTAL_WAITSAVERAGE_WAIT---------------------------------------------------------------------------------------dbfilesequentialread5166.02dbfilescatteredread966.03dbfilesinglewrite27.36dbfileparallelwrite1613.69dbfileparallelread34.64Elapsed:00:00:00.02

oracle在执行FTS时也进行Single Block I/O。这时即便是FTS也会发生db file sequential read等待。FTS上使用Single Block I/O或读取比MBRC值小的块数的情况如下:
(1)达到区的界线时:如一个区有9个块,一次Multi Block I/O读取8个块,则一次以Multi Block I/O读取之后的剩余一个块通过Single Block I/O读取,如果剩下的块有两个,就会执行Multi Block I/O,而且只读取两个块。
(2)扫描过程中读取被缓存的块时:如读取8个块时,其中第三个块被缓存,oracle将前两个块通过Multi Block I/O读取,对于第三个块执行一次Logical I/O,剩下的5个块通过Multi Block I/O读取。这种情况经常发生时,因引发多次的I/O,可能成为FTS速度下降的原因。

(3)存在行链接时:在执行FTS的过程中,如果发现了行链接,oracle为了读取剩下的行引起的附加I/O,此时执行Single Block I/O。

14:16:34SYS@prod>showparametermultNAMETYPEVALUE-----------------------------------------------------------------------------db_file_multiblock_read_countinteger19parallel_adaptive_multi_userbooleanTRUE14:17:28SYS@prod>colsegment_namefora2014:18:08SYS@prod>selectOWNER,SEGMENT_NAME,SEGMENT_TYPE,EXTENT_ID,BLOCK_ID,BLOCKSfromdba_extents14:18:472wheresegment_name='T1'ANDowner='SCOTT';OWNERSEGMENT_NAMESEGMENT_TYPEEXTENT_IDBLOCK_IDBLOCKS--------------------------------------------------------------------------------------------------SCOTTT1TABLE01688SCOTTT1TABLE11848SCOTTT1TABLE21928SCOTTT1TABLE32008SCOTTT1TABLE42088SCOTTT1TABLE52168SCOTTT1TABLE62248SCOTTT1TABLE72328SCOTTT1TABLE82408SCOTTT1TABLE92488SCOTTT1TABLE102568SCOTTT1TABLE112648SCOTTT1TABLE122728SCOTTT1TABLE132808SCOTTT1TABLE142888SCOTTT1TABLE152968SCOTTT1TABLE16384128OWNERSEGMENT_NAMESEGMENT_TYPEEXTENT_IDBLOCK_IDBLOCKS--------------------------------------------------------------------------------------------------SCOTTT1TABLE17512128SCOTTT1TABLE18640128SCOTTT1TABLE19768128SCOTTT1TABLE20896128SCOTTT1TABLE21102412822rowsselected.Elapsed:00:00:00.78


Db file sequential read
这个等待事件在实际生产库也很常见,当Oracle 需要每次I/O只读取单个数据块这样的操作时,会产生这个等待事件。最常见的情况有索引的访问(除IFFS外的方式),回滚操作,以ROWID的方式访问表中的数据,重建控制文件,对文件头做DUMP等。
这里的sequential也并非指的是Oracle 按顺序的方式来访问数据,和db file scattered read一样,它指的是读取的数据块在内存中是以连续的方式存放的。
这个等待事件有三个参数:
File#: 要读取的数据块锁在数据文件的文件号。
Block#: 要读取的起始数据块号。
Blocks: 要读取的数据块数目(这里应该等于1)。

案例分析:

14:28:55SYS@prod>altersystemflushbuffer_cache;Systemaltered.Elapsed:00:00:00.2814:29:08SYS@prod>selectevent,TOTAL_WAITS,AVERAGE_WAITfromv$system_event14:29:412whereupper(event)like'DBFILE%';EVENTTOTAL_WAITSAVERAGE_WAIT---------------------------------------------------------------------------------------dbfilesequentialread13991.04dbfilescatteredread1637.03dbfilesinglewrite36.35dbfileparallelwrite9462.98dbfileparallelread46.48Elapsed:00:00:00.0314:26:46SCOTT@prod>createindext1_indont1(id);Indexcreated.14:28:30SCOTT@prod>select*fromt1whereid=100014:28:482;ID----------100010001000Elapsed:00:00:00.0514:29:46SYS@prod>selectevent,TOTAL_WAITS,AVERAGE_WAITfromv$system_event2*whereupper(event)like'DBFILE%'EVENTTOTAL_WAITSAVERAGE_WAIT---------------------------------------------------------------------------------------dbfilesequentialread13994.04dbfilescatteredread1637.03dbfilesinglewrite36.35dbfileparallelwrite9462.98dbfileparallelread46.48Elapsed:00:00:00.03

14:29:58 SYS@ prod>

数据文件关于Multi Block I/O和Single Block I/O的活动信息:

14:38:22SYS@prod>selectf.file#,2f.name,3s.phyrds,4s.phyblkrd,5s.readtim,6s.singleblkrds,7s.singleblkrdtim,8(s.phyblkrd-s.singleblkrds)asmultiblkrd,9(s.readtim-s.singleblkrdtim)asmultiblkrdtim,10round(s.singleblkrdtim/11decode(s.singleblkrds,0,1,s.singleblkrds),123)assingleblk_avgtim,13round((s.readtim-s.singleblkrdtim)/14nullif((s.phyblkrd-s.singleblkrds),0),153)asmultiblk_avgtim16fromv$filestats,v$datafilef17*wheres.file#=f.file#FILE#NAMEPHYRDSPHYBLKRDREADTIMSINGLEBLKRDSSINGLEBLKRDTIMMULTIBLKRDMULTIBLKRDTIMSINGLEBLK_AVGTIMMULTIBLK_AVGTIM--------------------------------------------------------------------------------------------------------------------------------------------------------------------------1/u01/app/oracle/oradata/prod/system01.dbf1697768027419128963735513146.029.0012/u01/app/oracle/oradata/prod/sysaux01.dbf20413089142189413411958.071.0073/u01/app/oracle/oradata/prod/undotbs1.dbf1111411400.3644/u01/app/oracle/oradata/prod/users01.dbf59133558359729961.01905/u01/app/oracle/oradata/prod/example01.dbf101409050006/u01/app/oracle/oradata/prod/tbs1.dbf440400007/u01/app/oracle/oradata/prod/undotbs2.dbf181518185018124862.026.3338/u01/app/oracle/oradata/prod/perftbs01.dbf440400009/u01/app/oracle/oradata/prod/tbs2.dbf440400009rowsselected.selectf.file#,f.name,s.phyrds,s.phyblkrd,s.readtim,--所有的读取工作信息s.singleblkrds,s.singleblkrdtim,--SingleBlockI/O(s.phyblkrd-s.singleblkrds)asmultiblkrd,--MultiBlockI/O次数(s.readtim-s.singleblkrdtim)asmultiblkrdtim,--MultiBlockI/O时间round(s.singleblkrdtim/decode(s.singleblkrds,0,1,s.singleblkrds),3)assingleblk_avgtim,--SingleBlockI/O平均等待时间(cs)round((s.readtim-s.singleblkrdtim)/nullif((s.phyblkrd-s.singleblkrds),0),3)asmultiblk_avgtim--MultiBlockI/O平均等待时间(cs)fromv$filestats,v$datafilefwheres.file#=f.file#;