详解 db file sequential read 等待事件

db file sequential read (本文由thomaswoo_dba翻译,转载请注明出处)

db file sequential read 事件有三个参数:file#,first block#, block count, 在oracle 10g里,此等待事件在归于 User I/O wait class 下面的. 处理db file sequential read 事件要牢牢把握下面三个主要思想:

1)oracle 进程需要访问的block不能从SGA 中获取,因此oracle 进程会等待block从I/O读到SGA

2)两个重要参数TIME_WAITED,AVERAGE_WAIT,是以单个session获取的

3)影响较大的db file sequential read 一般很像应用程序问题

Common Causes, Diagnosis, and Actions

db file sequential read 等待事件被SQL 语句初始化,主要从index,rollback(or undo) segments, tables(通过rowid访问表),control files 和data file headers中进行single-block read.

访问数据对象(table,index)总是会产生Physical I/o需求,当出现db file sequential read等待事件时,并不意味着数据库产生系统问题,基至它大量出现都不是一件坏事.真正要引起注意的是像enqueue 和latch free等待事件,它们总是引起系统性题的根源.并且它们使single-block(单块读取)变得因难了.

那么什么情况下, 当出现db file sequential read等待事件,才可以视为性能问题呢?

什么情况下,db file sequential read可以视为系统的超额负担,并且基准线应该怎样去定义?

这是一个比较复杂的问题.在没有工业标准指引的情况下.我们要依据数据库运行环境来制定标准线.

比如,我们定义超过多少时间的db file sequential read等待事件,可以视为性能问题,还可以用最原始的方法,那就是等待用户抱怨.

在V$SESSION_EVENT视图中,db file sequential read的高TIME_WAITED是较为容易发现的,当时因为V$SESSION_EVENT是记录从实例启动以来的数据,所以我们同以前的TIME_WAITED进行比较,当然跟同一个session,同一个LOGON_TIME的非空闲事件进行比较是可以的,也是比较准确的.当实例不间断运行很长一段时间(数天或数星期)之后,TIME_WAITED的累计值就会很高,这当然不能说是性能问题.

select a.sid,

a.event,

a.time_waited,

a.time_waited / c.sum_time_waited * 100 pct_wait_time,

round((sysdate - b.logon_time) * 24) hours_connected

from v$session_event a, v$session b,

(select sid, sum(time_waited) sum_time_waited

from v$session_event

where event not in (

‘Null event‘,

‘client message‘,

‘KXFX: Execution Message Dequeue - Slave‘,

‘PX Deq: Execution Msg‘,

‘KXFQ: kxfqdeq - normal deqeue‘,

‘PX Deq: Table Q Normal‘,

‘Wait for credit - send blocked‘,

‘PX Deq Credit: send blkd‘,

‘Wait for credit - need buffer to send‘,

‘PX Deq Credit: need buffer‘,

‘Wait for credit - free buffer‘,

‘PX Deq Credit: free buffer‘,

‘parallel query dequeue wait‘,

‘PX Deque wait‘,

‘Parallel Query Idle Wait - Slaves‘,

‘PX Idle Wait‘,

‘slave wait‘,

‘dispatcher timer‘,

‘virtual circuit status‘,

‘pipe get‘,

‘rdbms ipc message‘,

‘rdbms ipc reply‘,

‘pmon timer‘,

‘smon timer‘,

‘PL/SQL lock timer‘,

‘SQL*Net message from client‘,

‘WMON goes to sleep‘)

having sum(time_waited) > 0 group by sid) c

where a.sid = b.sid

and a.sid = c.sid

and a.time_waited > 0

and a.event = ‘db file sequential read‘

order by hours_connected desc, pct_wait_time;

(本条语句来源于OWI 材料,但是本SQL语句计算的结果是不精确的,因为session sid是时时改变的)

减少db file sequential read 等待事件,我们可以从两方面入手:

1)第一条当然是优化SQL语句,以减少物理读和逻辑读

2)第二条是从统计上减少平均等待时间(比如优化最高wait_time的等待事件)

备注:特别是给客户看结果时效果最明显,因为图形给人的感观是比较明显的

相对每一条来说,除非用你10046事件或自己做一个不间断等待事件程序,不然是非常难以锁定哪一条SQL引起长时间的wait_time.退一步讲,当前的SQL也不一定就是引起wait_time的原因.所以我们发现要解决等待事件的问题没有历史数据是很困难的.

你也可以通过查询V$SQL视图获取平均DISK_READS,当然我们不能就认为此SQL就属于某个SESSION,所以下次对session进行trace,一般可以定位SQL,然后优化SQL以减少物理读与逻辑读.

备注:除了DISK_READS之外,oracle 10g为V$SQL 和V$SQLAREA视图增加了一些另人兴奋不己的新列:

USER_IO_WAIT_TIME

DIRECT_WRITES

APPLICATION_WAIT_TIME

CONCURRENCY_WAIT_TIME

CLUSTER_WAIT_TIME

PLSQL_EXEC_TIME

JAVA_EXEC_TIME

当然我们通过高累计的USER_IO_WAIT_TIME去定位SQL是可能的,但V$SQL和V$SQLAREA两个视图的访问速度是较慢的.

另外可以减少db file sequential read等待事件影响的方法是减少AVERAGE_WAIT ,AVERAGE_WAIT列是一个session等待single block被从硬盘获取的平均等待时间(英文好读,中文有点扭,主要我的水平不够)

This is the average time a session has to wait for a single block fetch from disk(英文原句).AVERAGE_TIME是V$SESSION_EVENT视图中的列.在高速的存储系统中,平均的single-block读不能够超过10ms(milliseconds,千分之一秒) 或1cs(centiseconds,百分之一秒).一般的情况下,SAN(storage area network,网络存储)的AVERAGE_TIME平均等待事间在4至8ms之间,因为SAN的cache都较大.

AVERAGE_TIME的值越大,single-block读的系统资源开耗也随之增大,也即进程的响应时间会受到影响.

从另外一个方面来讲,较低的AVERAGE_TIME值反应进程等待single-block读的时间会较短.当然

AVERAGE_TIME调优的优先级远没有SQL优化的优先级高,因为优化一个占用大量资源的SQL的效果是非常明显和有效的.

需要注意的db file sequential read 并不总是对index对像进行资源占用,有时也会对table/partition对像进行资源占用.所以我们需要将P1/P2参数的值进行转换,在此我们会用到视图DBA_EXTENTS以获取对像名.

但是DBA_EXTENTS是一个复杂的,响应极慢的视图.要想用快一点的方法,X$和DBA_OBJECTS将是一个更好的选择.因为X$BH不占用BUFFER_CACHE所以,访问X$BH会有I/O产生,还有就是DBA-OBJECTS视图不包括rollback 和undo 段,所以如果db file sequential read访问这两个对象,也是不能被解析的.

查询的例子:

select b.sid,       nvl(substr(a.object_name,1,30),                  ‘P1=‘||b.p1||‘ P2=‘||b.p2||‘ P3=‘||b.p3) object_name,       a.subobject_name,       a.object_typefrom   dba_objects a, v$session_wait b, x$bh cwhere  c.obj = a.object_id(+)and    b.p1 = c.file#(+)and    b.p2 = c.dbablk(+)and    b.event = ‘db file sequential read‘unionselect b.sid,       nvl(substr(a.object_name,1,30),                  ‘P1=‘||b.p1||‘ P2=‘||b.p2||‘ P3=‘||b.p3) object_name,       a.subobject_name,       a.object_typefrom   dba_objects a, v$session_wait b, x$bh cwhere  c.obj = a.data_object_id(+)and    b.p1 = c.file#(+)and    b.p2 = c.dbablk(+)and    b.event = ‘db file sequential read‘order  by 1;

SID OBJECT_NAME               SUBOBJECT_NAME            OBJECT_TYPE----- ------------------------- ------------------------- -----------------   12 DVC_TRX_REPOS             DVC_TRX_REPOS_PR64        TABLE PARTITION  128 DVC_TRX_REPOS             DVC_TRX_REPOS_PR61        TABLE PARTITION  154 ERROR_QUEUE               ERROR_QUEUE_PR1           TABLE PARTITION  192 DVC_TRX_REPOS_1IX         DVC_TRX_REPOS_20040416    INDEX PARTITION  194 P1=22 P2=30801 P3=1  322 P1=274 P2=142805 P3=1  336 HOLD_Q1_LIST_PK                                     INDEX
像本例中的object_type,如果是table,要进SQL进行相应的优化.
Sequential Reads Against Indexes
db file sequential read 主要的问题不是对index的访问,而且超额的对错误index的访问.当系统的访问路径发生更改时,可能对效能慢的index进行访问,从而产生等待.当然如果一个SQL执行了大量的index读这也可能是一个性能问题.所以分析SQL的执行计划是一个比较好的方法,当要用FULL TABLE SCAN时,用index就会产生性能问题.还有就是FIRST_ROWS 和ALL_ROWS的问题,当然从大的方面讲OLTP与DSS的混用也会产生不合时适的db file sequential read.还有关于驱动表(driving table)的问题.不对的驱动表,性能也不会好.
记住,所有的努力的目的应该是一样的,那就是降低logical and physical I/Os
下面有个种方法:1)分析SQL,弄清SQL的逻辑,看看SQL到底想获取什么,然后优化,甚至重写2)将index放在快磁盘上,尤其不要放在RAID-5上,因为慢磁盘导致高average time,然而I/O优化的优先级  不可以高于SQL CODE的优化.因为SQL有问题再快的磁盘的也不行,最好用OUTLINE稳固执计计划,尤其是第三方软件3)关于index表,最好将数据进行排列,以减少I/O.可以通过DBA_INDEXS.CLUSTERING_FACTOR来查看index有没有达到  表的所有块的数量,如有是,说明大部份列是排列的,如是不是,表时表是随机排列的.这时可以通过重组表以解决问题.4)看看表最近没有没建立新的index,使SQL的执行计划发生改变.(下面的语句可以查看到)  看看有没有invalid的index.
select owner,        substr(object_name,1,30) object_name,        object_type,        created   from   dba_objects   where  object_type in (‘INDEX‘,‘INDEX PARTITION‘)   order by created;
5)OPTIMIZER_INDEX_COST_ADJ 和OPTIMIZER_INDEX_CACHING
(来源于网上)其次,由于测试环境的不同,Tom的测试结果是在缺省值(100)的环境下,就已经和上面取值500时一样了,即对T2全表扫描而T1使用索引。Tom试验中,减小取值直至0,访问路径就变成使用两个索引,而并不会出现均不使用索引的情况。除去系统的不同(可能导致取缺省值时访问路径是否一致),只看变化趋势,显然10g中灵活性更高,1-10000的取值使得CBO可以覆盖所有的访问路径。另一方面,正如Tom的结论所说,OPTIMIZER_INDEX_COST_ADJ的取值越大,优化器越倾向于使用全表扫描,取值越小,优化器越倾向于使用索引。                 再次,我们对比相同访问路径下的不同点。在取值从1变化到200(1-50-100-200)的过程中,优化器计算出的代价是持续增长的,而从1000到10000则是不变的。这说明这个参数与索引I/O的代价有关,而和全表扫描并无关系,这与Tom所说的并不矛盾,不过显然更精确一点。                 最后我们其实应该看到,虽然有如上所说的代价变化问题,同一访问路径下实际的运行性能并无区别,由于数据量比较小,上面的例子也许不能很好的说明这一点,不过想想Oracle用相同的路径去执行,也没有理由不同性能吧。              OPTIMIZER_INDEX_CACHING值为0,值越大,系统越tendence去用nested loops .Find out what values the sessions are running with. Up to Oracle9i Database, this information could only be obtained by tracing the sessions with the trace event 10053 at level 1 and examining the trace files. In Oracle Database 10g, this is as simple as querying the V$SES_OPTIMIZER_ENV view.可以通过10053事件查看SESSION相应的OPTIMIZER_INDEX_COST_ADJ 和OPTIMIZER_INDEX_CACHING值是多少,在10g中省不了事,直接查V$SES_OPTIMIZER_ENV视图就可以了,下面的是例子:
select * FROM V$SES_OPTIMIZER_ENV  WHERE NAME=LOWER(‘OPTIMIZER_INDEX_COST_ADJ‘) or                                          name=lower(‘OPTIMIZER_INDEX_CACHING‘);
SID   ID    NAME                       ISDEFAULT  VALUE--------------------------------------------------------144   67    optimizer_index_caching    YES        0145   66    optimizer_index_cost_adj   YES        100145   67    optimizer_index_caching    YES        0
因为oracle的optimizer依赖于表与索引的statistics,所以要确保现在的statistics能够代表现有数据,不正确的statistics会让optimizer 产生低效的执行计划,当然statistics也不必天天更新,因为这样的话,执行计划就也会天天更新,这对性能问题的分析会产生干扰
System-Level Diagnosis
V$SYSTEM_EVENT视图为系统级别的诊断提供数据,基中AVERAGE_TIME和TIME_WAITED与I/O相关事件关联记住TIME_WAITED只是记录自实例启动以来的记录,当实例运行比较长的一段时间后,db file sequential read 通常较高.当然,经常查询V$SYSTEM_EVENT并且以TIME_WAITED排序,能够通过相互比较而找到比较明显的等待事件.当db file sequential read 不位于top five时,不要担心,因为可能有更大的问题要去发现当db file sequential read 位于top five时,也总能说明数据库进行了大量的single-block读.这里可以看系统级别的诊断能力是非常受限的.但事件总是两面情,这里却可以看系统硬件上瓶颈这在v$session_wait事件里可是看不到的.当你想升级系统,可是你的直接上司要求你提供系统瓶颈报告时,下面就是那个好办法:
select a.event,        a.total_waits,        a.time_waited,        a.time_waited/a.total_waits average_wait,  这里的average_wait是很用的       sysdate – b.startup_time days_oldfrom   v$system_event a, v$instance border by a.time_waited;  当average single-block读超过你所定的阀门的时候,你要看看I/O子系统是不是得到优化了.当然用操作系统的I/O控制命令(iostat,vmstat)去监控硬盘,可以发现I/O的瓶颈,可以去评估各I/O子系统之间是不是平衡.Device:                  tps         Blk_read/s         Blk_wrtn/s         Blk_read         Blk_wrtndev8-0                  3.93              17.03              34.66         54592552  111099454dev8-1                 12.08              56.68              99.93  181659920  320286944dev8-2                 23.38             194.11             189.93  622154550  608747464dev8-3                 16.00             230.43             128.04  738570544  410383416dev8-4                  4.73              59.89              80.98  191965458  259557752通过上例,可以看到dev8-2,dev8-3的块读写是远远超过其它的,所以可以考虑平衡一下I/O
另外,除了从V$SYSTEM_EVENT视图中进行系统级别的db file sequential read average wait之外,oracle也提供了另外一个视图v$filestat来获取single-block读的统计数据.
select a.file#,        b.file_name,        a.singleblkrds,        a.singleblkrdtim,        a.singleblkrdtim/a.singleblkrds average_waitfrom   v$filestat a, dba_data_files b where  a.file# = b.file_id   and    a.singleblkrds > 0order by average_wait;

FILE# FILE_NAME                     SINGLEBLKRDS SINGLEBLKRDTIM AVERAGE_WAIT----- ----------------------------- ------------ -------------- ------------   367 /dev/vgEMCp113/rPOM1P_4G_039          5578            427   .076550735  368 /dev/vgEMCp113/rPOM1P_4G_040          5025            416    .08278607  369 /dev/vgEMCp113/rPOM1P_4G_041         13793           1313   .095193214  370 /dev/vgEMCp113/rPOM1P_4G_042          6232            625   .100288832  371 /dev/vgEMCp113/rPOM1P_4G_043          4663            482   .103366931  372 /dev/vgEMCp108/rPOM1P_8G_011        164828         102798   .623668309  373 /dev/vgEMCp108/rPOM1P_8G_012        193071         125573    .65039804  374 /dev/vgEMCp108/rPOM1P_8G_013        184799         126720   .685717996  375 /dev/vgEMCp108/rPOM1P_8G_014        175565         125969   .717506337
时间: 2024-08-09 00:40:31

详解 db file sequential read 等待事件的相关文章

db file sequential read等待事件 --转载

db file sequential read db file sequential read等待事件有3个参数:file#,first block#,和block数量.在10g中,这等待事件受到用户I/O等待级别的影响.当处理db file sequential read等待事件的时候,牢记以下关键想法. l         Oracle进程需要一个当前不在SGA中的块,等待数据库块从磁盘读入到SGA中 l         要看的两个重要的数字是单独会话的TIME_WAITED和AVERAGE

db file sequential read等待事件

db file sequential read:直接路径读: 官方说明如下: This event signifies that the user process is reading a buffer into the SGA buffer cache and is waiting for a physical I/O call to return. A sequential read is a single-block read. Single block I/Os are usually

db file scattered read 等待事件

db file scattered read 等待事件: 我们经常会见到db file scattered read  等待事件,在生产环境中,这个等待事件可能更为常见.这个事件表明用户进程正在读数据到Buffer Cache中,等待直到I/O调用返回.db file scattered read发出离散读,将存储上连续的数据块离散的读入到多个不连续的内存位置.Scattered Read通常是多块读,在Full Table Scan或Fast Full Scan等访问方式下使用.Scatter

control file sequential read 等待事件

可能的原因 control file sequential read Reading from the control file. This happens in many cases. For example, while: 1.Making a backup of the control files 2.Sharing information (between instances) from the control file 3.Reading other blocks from the c

Oracle db file parallel write 和 log file parallel write 等待事件

一. db file parallel write等待事件 引自如下blog: http://oradbpedia.com/wiki/Wait_Events_-_db_file_parallel_write db文件并行写 db文件并行写等待事件属于Oracle数据库写入程序(DBWR)进程,因为它是将块从SGA写入数据文件的唯一进程.当是写入时,DBWR进程编译一组脏块,将批处理交给操作系统,并等待db文件并行写事件以完成I / O.虽然用户会话从来没有遇到db文件并行写等待事件,但这并不意味

Oracle 等待事件之 db file sequential read

db file sequential read: 官网解释: This event signifies that the user process is reading a buffer into the SGA buffer cache and is waiting for a physical I/O call to return. A sequential read is a single-block read. Single block I/Os are usually the resu

db file sequential read

db file sequential read这个等待事件在实际生产库非常常见,是个与User I/O相关的等待事件,通常显示与单个数据块相关的读取操作,在大多数情况下,读取一个索引块或者通过索引读取一个数据块时,都会记录这个等待.当Oracle 需要每次I/O只读取单个数据块这样的操作时,会产生这个等待事件.最常见的情况有索引的访问(除IFFS外的方式),回滚操作,以ROWID的方式访问表中的数据,重建控制文件,对文件头做DUMP等. 在V$SESSION_WAIT这个视图里面,这个等待事件有

远程文件同步详解(Remote File Sync)

1. 远程文件同步的常见方式: 1.cron + rsync 优点: 简单 缺点:定时执行,实时性比较差:另外,rsync同步数据时,需要扫描所有文件后进行比对,进行差量传输.如果文件数量达到了百万甚至千万量级,扫描所有文件将是非常耗时的.远程对比时发送所有的文件树or目录树属性,而且正在发生变化的往往是其中很少的一部分,这是非常低效的方式. 2. inotify + rsync 优点:比较简单 缺点:每个变更文件都使用了rsync.而每一次rsync都要建立SSH链接,这个其实是比较费时间的.

文件上传详解 (HTML FILE)

FileUpload 对象 在 HTML 文档中 <input type="file"> 标签每出现一次,一个 FileUpload 对象就会被创建. 该元素包含一个文本输入字段,用来输入文件名,还有一个按钮,用来打开文件选择对话框以便图形化选择文件. 该元素的 value 属性保存了用户指定的文件的名称,但是当包含一个 file-upload 元素的表单被提交的时候,浏览器会向服务器发送选中的文件的内容而不仅仅是发送文件名. 为安全起见,file-upload 元素不允许