天天看点

等待事件分析

在Oracle 10g中的等待事件有872个,11g中等待事件1116个。 我们可以通过v$event_name 视图来查看等待事件的相关信息。

1.1 查看v$event_name视图的字段结构:

SQL> desc v$event_name

 Name

 ---------------------------

 EVENT#

 EVENT_ID

 NAME

 PARAMETER1

 PARAMETER2

 PARAMETER3

 WAIT_CLASS_ID

 WAIT_CLASS#

 WAIT_CLASS

1.2  查看等待事件总数:

SQL> select count(*) from v$event_name;

  COUNT(*)

----------

      1118

1.3  查看等待事件分类情况:

SQL>   SELECT   wait_class#,

  2             wait_class_id,

  3             wait_class,

  4             COUNT ( * ) AS "count"

  5      FROM   v$event_name

  6  GROUP BY   wait_class#, wait_class_id, wait_class

  7  ORDER BY   wait_class#;

WAIT_CLASS# WAIT_CLASS_ID WAIT_CLASS                                                            count

----------- ------------- ---------------------------------------------------------------- ----------

          0    1893977003 Other                                                                   719

          1    4217450380 Application                                                              17

          2    3290255840 Configuration                                                            24

          3    4166625743 Administrative                                                           54

          4    3875070507 Concurrency                                                              32

          5    3386400367 Commit                                                                    2

          6    2723168908 Idle                                                                     94

          7    2000153315 Network                                                                  35

          8    1740759767 User I/O                                                                 45

          9    4108307767 System I/O                                                               30

         10    2396326234 Scheduler                                                                 7

WAIT_CLASS# WAIT_CLASS_ID WAIT_CLASS                                                            count

----------- ------------- ---------------------------------------------------------------- ----------

         11    3871361733 Cluster                                                                  50

         12     644977587 Queueing                                                                  9

13 rows selected.

1.4  相关的几个视图:

V$SQLTEXT:  当数据库出现瓶颈时,通常可以从V$SESSION_WAIT找到那些正在等待资源的SESSION,通过SESSION的SID,联合V$SESSION和V$SQLTEXT视图就可以捕获这些SESSION正在执行的SQL语句。     (SQL层等待分析)

V$SESSION:  代表数据库活动的开始,视为源起。

V$SESSION_WAIT:  视图用以实时记录活动SESSION的等待情况,是当前信息。  (会话层等待分析)

如: select event,total_waits from v$session_event where sid=### order by total_waits desc;

V$SYSTEM_EVENT 由于V$SESSION记录的是动态信息,和SESSION的生命周期相关,而并不记录历史信息,所以ORACLE提供视图V$SYSTEM_EVENT来记录数据库自启动以来所有等待事件的汇总信息。通过这个视图,用户可以迅速获得数据库运行的总体概况。  (系统层等待分析)

如:  select event,total_waits from v$system_event order by total_waits desc;

V$SESSION_WAIT_HISTORY:  是对V$SESSION_WAIT的简单增强,记录活动SESSION的最近10次等待。

V$ACTIVE_SESSION_HISTORY: 是ASH的核心,用以记录活动SESSION的历史等待信息,每秒采样一次,这部分内容记录在内存中,期望值是记录一个小时的内容。

WRH#_ACTIVE_SESSION_HISTORY : 是V$ACTIVE_SESSION_HISTORY在AWR的存储地。

V$ACTIVE_SESSION_HISTORY: 中的信息会被定期(每小时一次)的刷新到负载库中,并缺省保留一个星期用于分析。

DBA_HIST_ACTIVE_SESS_HISTORY: 视图是WRH#_ACTIVE_SESSION_HISTORY视图和其他几个视图的联合展现,通常通过这个视图进行历史数据的访问。

1.5 常见的等待事件

1.5.1   db file scattered read

产生原因:

当PGA中无所需数据,数据块以multiblock read的行式被读取到SGA中时。如:FTS(full table scan),IFFS(index fast full scan)

解决对策:

无需解决、考虑索引、考虑并行

1.5.2   DB File Sequential Read  (单块读等待)

背景知识:

这里的sequential指的是将数据块读入到相连的内存空间中(contiguous memory space),而不是指所读取的数据块是连续的。

产生原因:

a:  最为常见的是执行计划中包含了INDEX FULL SCAN/UNIQUE SCAN,此时出现”db file sequential read”等待是预料之中的,一般不需要我们去特别关注

b:  当执行计划包含了INDEX RANGE SCAN-(“TABLE ACCESS BY INDEX ROWID”/”DELETE”/”UPDATE”), 服务进程将按照”访问索引->找到rowid->访问rowid指定的表数据块并执行必要的操作”顺序访问index和table,每次物理 读取都会进入”db file sequential read”等待,且每次读取的都是一个数据块;这种情况下clustering_factor将发挥其作用,需要我们特别去关注,本例中提及的解决方法对 这种情景也有效

c:  Extent boundary,假设一个Extent区间中有33个数据块,而一次”db file scattered read”多块读所读取的块数为8,那么在读取这个区间时经过4次多块读取后,还剩下一个数据块,但是请记住多块读scattered read是不能跨越一个区间的(span an extent),此时就会单块读取并出现”db file sequential read”。这是一种正常现象,一般不需要额外关注

d:  假设某个区间内有8个数据块,它们可以是块a,b,c,d,e,f,g,h,恰好当前系统中除了d块外的其他数据块都已经被缓存在buffer cache中了,而这时候恰好要访问这个区间中的数据,那么此时就会单块读取d这个数据块,并出现”db file sequential read”等待。注意这种情况不仅于表,也可能发生在索引上。这是一种正常现象,一般不需要额外关注

e:  chained/migrated rows即链式或迁移行,这里我们不介绍链式行的形成原因,chained/migrated rows会造成服务进程在fetch一行记录时需要额外地单块读取,从而出现”db file sequential read”。这种现象需要我们特别去关注,因为大量的链式/迁移行将导致如FULL SCAN等操作极度恶化(以往的经验是一张本来全表扫描只需要30分钟的表,在出现大量链式行后,全表扫描需要数个小时),同时也会对其他操作造成不那么 明显的性能影响。可以通过监控v$sysstat视图中的”table fetch continued row”操作统计来了解系统中链式/迁移行访问的情况,还可以通过DBA_TBALES视图中的CHAIN_CNT来了解表上的链式/迁移行情况,当然这 要求定期收集表上的统计信息;如果没有定期收集的习惯,那么可以配合@?/rdbms/admin/utlchain脚本和analyze table list chained rows 命令来获取必要的链式行信息

f:  创建Index entry,显然当对表上执行INSERT操作插入数据时,虽然在执行计划中你看不到过多的细节,但实际上我们需要利用索引来快速验证表上的某些约束是否 合理,还需要在索引的叶子块中插入相关的记录,此时也可能出现”db file sequential read”等待事件,当然这还和具体的插入的方式有关系。这是一种正常现象,一般不需要额外关注

1.5.3  Direct Path Read

产生原因:

数据被直接读取到PGA内存中时,发生的等待。如:排序数据由于内存不足,被写到磁盘上(temp表空间数据文件)

,然后重新读取时。

解决办法:

无需解决、增大内存排序区(PGA)、调整操作的并行度、改善磁盘I/O、

1.5.4  Direct Path  write

产生原因:

数据从PGA内存中直接写到磁盘上,发生的等待。 如:排序数据由于内存不足,被写到磁盘上(temp表空间数据文件)

1.5.5  Log File Sync

产生原因:

用户commit(rollback)时,lgwr需要将log buffer的数据写到log file上面,发生的等待。

解决本法:

减少commit的频率(错误的频繁提交)、提高I/O性能、增加lgwr进程个数

1.5.6   buffer busy waits  (热快)

产生原因:

在SGA中读取或修改缓冲区的会话必须首先获取cache buffers chains锁存器,并且遍历这个缓冲区链,直到他发现必需的缓冲区头。然后,他必须以共享模式或独占模式获取一个缓冲区锁或缓冲区头上的pin,这取决于他计划的操作。一旦缓冲区头被钉住,会话就释放cache buffers chains锁存器,并在缓冲区自身上执行计划的操作。如果无法获取一个pin,会话就在buffer busy waits等待事件上等待。这种等待时间不会应用于在会话的私有PGA中执行的读取或写入操作。

解决办法:

1、出现此情况通常可能通过几种方式调整:增大data  buffer;

2、增加freelist,减小pctused;怎样的目的是将一个block上可以使用的空间减少,这样的话:一个block上的数据存放的较少,可以提高应用的访问并发率,减少hot block的产生;

3、增加回滚段数目,增大initrans,考虑使用LMT, 确认是不是由于热点块造成(如果是可以用反转索引,或者用更小块大小);

3、可以建立block较小的表空间,见热点对象移动到此表空间上去;

4、优化应用,优化索引,提高索引的命中率;

◎ Oracle会话正在等待钉住一个缓冲区。必须在读取或修改缓冲区前将它钉住。在任何时刻只有一个进程可以钉住一个缓冲区。

◎ buffer busy waits表明读/读、读/写、写/写争用。

◎ 采取的适当措施取决于P3参数中的原因码。

A、如果等待处于字段头部,应增加自由列表(freelist)的组数,或者增加pctused到pctfree之间的距离。

B、如果等待处于回退段(undo)头部块,可以通过增加回滚段(rollback segment)来解决缓冲区的问题;

C、如果等待处于回退段(undo)非头部块上,就需要降低驱动一致读取的表中的数据密度,或者增大DB_CACHE_SIZE;

D、如果等待处于数据块,可以将数据移到另一数据块以避开这个"热"数据块、增加表中的自由列表或使用LMT表空间;

E、如果等待处于索引块,应该重建索引、分割索引或使用反向键索引。

1.5.7    free buffer waits

产生原因:

server process无法找一个可用的内存空间。

(系统I/O成为瓶颈(或者性能不够)、等待资源 latch争用、SGA太小、SGA太大,dbwr无法快速的把脏数据刷到磁盘上)

解决办法:

优化I/O、增加多个dbwr 进程、增大SGA

个人总结与网络总结

部分参考:http://www.askmaclean.com/archives/db-file-sequential-read-wait-event.html

继续阅读