ITPub博客

首页 > Linux操作系统 > Linux操作系统 > Oracle常见等待事件说明(1)

Oracle常见等待事件说明(1)

原创 Linux操作系统 作者:ceo_lxy 时间:2011-02-15 16:46:35 0 删除 编辑

Oracle的等待事件是衡量Oracle运行状况的重要依据及指标。等待事件的概念是在Oracle7.0.1.2中引入的,大致有100个等待事件。在Oracle 8.0中这个数目增加到了大约150个,在Oracle8i中大约有200个事件,在Oracle9i中大约有360个等待事件。主要有两种类别的等待事件,即空闲(idle)等待事件和非空闲(non-idle)等待事件。

  空闲事件指Oracle正等待某种工作,在诊断和优化数据库的时候,我们不用过多注意这部分事件。

  常见的空闲事件有:

  • dispatcher timer

  • lock element cleanup

  • Null event

  • parallel query dequeue wait

  • parallel query idle wait - Slaves

  • pipe get

  • PL/SQL lock timer

  • pmon timer- pmon

  • rdbms ipc message

  • slave wait

  • smon timer

  • SQL*Net break/reset to client

  • SQL*Net message from client

  • SQL*Net message to client

  • SQL*Net more data to client

  • virtual circuit status

  • client message

  非空闲等待事件专门针对Oracle的活动,指数据库任务或应用运行过程中发生的等待,这些等待事件是我们在调整数据库的时候应该关注与研究的。

  一些常见的非空闲等待事件有:

  • db file scattered read

  • db file sequential read

  • buffer busy waits

  • free buffer waits

  • enqueue

  • latch free

  • log file parallel write

  • log file sync

  1. db file scattered read-DB 文件分散读取

  这种情况通常显示与全表扫描相关的等待。当数据库进行全表扫时,基于性能的考虑,数据会分散(scattered)读入Buffer Cache。如果这个等待事件比较显著,可能说明对于某些全表扫描的表,没有创建索引或者没有创建合适的索引,我们可能需要检查这些数据表已确定是否进行了正确的设置。

  然而这个等待事件不一定意味着性能低下,在某些条件下Oracle 会主动使用全表扫描来替换索引扫描以提高性能,这和访问的数据量有关,在CBO 下Oracle 会进行更为智能的选择,在RBO 下Oracle 更倾向于使用索引。

  因为全表扫描被置于LRU(Least Recently Used,最近最少适用)列表的冷端(cold end),对于频繁访问的较小的数据表,可以选择把他们Cache 到内存中,以避免反复读取。

  当这个等待事件比较显著时,可以结合v$session_longops 动态性能视图来进行诊断,该视图中记录了长时间(运行时间超过6 秒的)运行的事物,可能很多是全表扫描操作(不管怎样,这部分信息都是值得我们注意的)。

  2. db file sequential read-DB 文件顺序读取。

  这一事件通常显示与单个数据块相关的读取操作(如索引读取)。如果这个等待事件比较显著,可能表示在多表连接中,表的连接顺序存在问题,可能没有正确的使用驱动表;或者可能说明不加选择地进行索引。

  在大多数情况下我们说,通过索引可以更为快速的获取记录,所以对于一个编码规范、调整良好的数据库,这个等待很大是很正常的。但是在很多情况下,使用索引并不是最佳的选择,比如读取较大表中大量的数据,全表扫描可能会明显快于索引扫描,所以在开发中我们就应该注意,对于这样的查询应该进行避免使用索引扫描。

  3. Free Buffer-释放缓冲区

  这个等待事件表明系统正在等待内存中的可用空间,这说明当前Buffer 中已经没有Free 的内存空间。如果应用设计良好,SQL 书写规范,充分绑定变量,那这种等待可能说明Buffer Cache 设置的偏小,你可能需要增大DB_BUFFER_CACHE。

  Free Buffer 等待可能说明DBWR 的写出速度不够,或者磁盘存在严重的竞争,可以需要考虑增加检查点、使用更多的DBWR 进程,或者增加物理磁盘的数量,分散负载,平衡IO。

  4. Buffer Busy-缓冲区忙

  该等待事件表示正在等待一个以unshareable方式使用的缓冲区,或者表示当前正在被读入buffer cache。一般来说Buffer Busy Wait不应大于1%。检查缓冲等待统计部分(或V$WAITSTAT),看一下等待是否位于段头(Segment Header)。如果是,可以考虑增加自由列表(freelist,对于Oracle8i DMT)或者增加freelist groups(在很多时候这个调整是立竿见影的,在8.1.6之前,这个freelists参数不能动态修改;在8.1.6及以后版本,动态修改feelists需要设置COMPATIBLE至少为8.1.6).

  如果这一等待位于undo header,可以通过增加回滚段(rollback segment)来解决缓冲区的问题。如果等待位于undo block上,我们可能需要检查相关应用,适当减少大规模的一致性读取,或者降低一致性读取(consistent read)的表中的数据密度或者增大DB_CACHE_SIZE。

  如果等待处于data block,可以考虑将频繁并发访问的表或数据移到另一数据块或者进行更大范围的分布(可以增加pctfree值 ,扩大数据分布,减少竞争),以避开这个"热点"数据块,或者可以考虑增加表中的自由列表或使用本地化管理的表空间(Locally Managed Tablespaces)。

  如果等待处于索引块,应该考虑重建索引、分割索引或使用反向键索引。为了防止与数据块相关的缓冲忙等待,也可以使用较小的块:在这种情况下,单个块中的记录就较少,所以这个块就不是那么"繁忙";或者可以设置更大的pctfree,使数据扩大物理分布,减少记录间的热点竞争。

  在执行DML (insert/update/ delete)时,Oracle向数据块中写入信息,对于多事务并发访问的数据表,关于ITL的竞争和等待可能出现,为了减少这个等待,可以增加initrans,使用多个ITL槽。在Oracle9i 中,引入了一个新概念:ASSM(Segment Space Management Auto)。通过这个新特性Oracle 使用位图来管理空间使用。

  ASSM 结合LMT 彻底改变了Oracle 的存储机制,位图freelist 能够减轻缓冲区忙等待(buffer busy wait),这个问题在Oracle9i 以前的版本里曾是一个严重的问题。

  Oracle 宣称ASSM 显著地提高了DML 并发操作的性能,因为(同一个)位图的不同部分可以被同时使用,这样就消除了寻找剩余空间的串行化。根据Oracle 的测试结果,使用位图freelist 会消除所有分段头部(对资源)的争夺,还能获得超快的并发插入操作。在Oracle9i 之中,Buffer Busy wait 不再常见!

原文出自【比特网】,转载请保留原文链接:看书笔记db file scattered read DB ,db file sequential read DB,free buffer waits,log buffer space,log file switch,log file sync
我们可以通过视图v$session_wait来查看系统当前的等待事件,以及与等待事件相对应的资源的相关信息,从而可确定出产生瓶颈的类型及其对象。v$session_wait的p1、p2、p3告诉我们等待事件的具体含义,根据事件不同其内容也不相同,下面就一些常见的等待事件如何处理以及如何定位热点对象和阻塞会话作一些介绍。
<1> db file scattered read DB 文件分散读取 (太多索引读,全表扫描-----调整代码,将小表放入内存)
这种情况通常显示与全表扫描相关的等待。当全表扫描被限制在内存时,它们很少会进入连续的缓冲区内,而是分散于整个缓冲存储器中。如果这个数目很大,就表明该表找不到索引,或者只能找到有限的索引。尽管在特定条件下执行全表扫描可能比索引扫描更有效,但如果出现这种等待时,最好检查一下这些全表扫描是否必要。因为全表扫描被置于LRU(Least Recently Used,最近最少适用)列表的冷端(cold end),所以应尽量存储较小的表,以避免一次又一次地重复读取它们。
==================================================
该类事件的p1text=file#,p1是file_id,p2是block_id,通过dba_extents即可确定出热点对象(表或索引)
select owner,segment_name,segment_type
from dba_extents
where file_id = &file_id
and &block_id between block_id and block_id + &blocks - 1;
==================================================
<2> db file sequential read DB 文件顺序读取 (表连接顺序不佳-----调整代码,特别是表连接)
这一事件通常显示单个块的读取(如索引读取)。这种等待的数目很多时,可能显示表的连接顺序不佳,或者不加选择地进行索引。对于大量事务处理、调整良好的系统,这一数值大多是很正常的,但在某些情况下,它可能暗示着系统中存在问题。你应当将这一等待统计量与Statspack 报告中的已知问题(如效率较低的SQL)联系起来。检查索引扫描,以保证每个扫描都是必要的,并检查多表连接的连接顺序。DB_CACHE_SIZE 也是这些等待出现频率的决定因素。有问题的散列区域(Hash-area)连接应当出现在PGA 内存中,但它们也会消耗大量内存,从而在顺序读取时导致大量等待。它们也可能以直接路径读/写等待的形式出现。
===================================================
该类事件的p1text=file#,p1是file_id,p2是block_id,通过dba_extents即可确定出热点对象(表或索引)
select owner,segment_name,segment_type
from dba_extents
where file_id = &file_id
and &block_id between block_id and block_id + &blocks - 1;
==================================================
<3> free buffer waits 释放缓冲区等待 (增大DB_CACHE_SIZE,加速检查点,调整代码)
这种等待表明系统正在等待内存中的缓冲,因为内存中已经没有可用的缓冲空间了。如果所有SQL 都得到了调优,这种等待可能表示你需要增大DB_BUFFER_CACHE。释放缓冲区等待也可能表示不加选择的SQL 导致数据溢出了带有索引块的缓冲存储器,没有为等待系统处理的特定语句留有缓冲区。这种情况通常表示正在执行相当多数量的DML(插入/更新/删除),并且数据库书写器(DBWR)写的速度不够快,缓冲存储器可能充满了相同缓冲器的多个版本,从而导致效率非常低。为了解决这个问题,可能需要考虑增加检查点、利用更多的DBWR 进程,或者增加物理磁盘的数量。
<4> buffer busy waits 缓冲区忙等待 (BUFFER热块)
这是为了等待一个以非共享方式使用的缓冲区,或者正在被读入缓冲存储器的缓冲区。缓冲区忙等待不应大于1%。检查缓冲等待统计部分(或V$WAITSTAT):
A、如果等待处于字段头部,应增加自由列表(freelist)的组数,或者增加pctused到pctfree之间的距离。
B、如果等待处于回退段(undo)头部块,可以通过增加回滚段(rollback segment)来解决缓冲区的问题;
C、如果等待处于回退段(undo)非头部块上,就需要降低驱动一致读取的表中的数据密度,或者增大DB_CACHE_SIZE;
D、如果等待处于数据块,可以将数据移到另一数据块以避开这个"热"数据块、增加表中的自由列表或使用LMT表空间;
E、如果等待处于索引块,应该重建索引、分割索引或使用反向键索引。
为了防止与数据块相关的缓冲忙等待,也可以使用较小的块:在这种情况下,单个块中的记录就较少,所以这个块就不是那么"繁忙"。在执行DML(插入/更新/删除)时,Oracle DBWR就向块中写入信息,包括所有对块状态"感兴趣"的用户(感兴趣的事务表,ITL)。为减少这一区域的等待,可以增加initrans,这样会在块中创建空间,从而使你能够使用多个ITL槽。你也可以增加该块所在表中的pctfree(当根据指定的initrans 建立的槽数量不足时,这样可以使ITL 信息数量达到maxtrans 指定的数量)。
<6> enqueue
enqueue 是一种保护共享资源的锁定机制。该锁定机制保护共享资源,如记录中的数据,以避免两个人在同一时间更新同一数据。enqueue 包括一个排队机制,即FIFO(先进先出)排队机制。注意:Oracle 的latch 机制不是FIFO。Enqueue 等待通常指的是ST enqueue、HW enqueue、TX4 enqueue 和TM enqueue。
A、ST enqueue 用于空间管理和字典管理的表空间的分配。利用LMT,或者试图对区域进行预分配,或者至少使下一个区域大于有问题的字典管理的表空间。
B、HW enqueue 与段的高水位标记一起使用;手动分配区域可以避免这一等待。
C、TX4 enqueue是最常见的enqueue 等待,通常是以下三个问题之一产生的结果:
第一个问题是唯一索引中的重复索引,需要执行提交(commit)/回滚(rollback)操作来释放enqueue。
第二个问题是对同一位图索引段的多次更新。因为单个位图段可能包含多个行地址(rowid),所以当多个用户试图更新同一段时,你需要执行提交或回滚操作,以释放enqueue。
第三个问题,也是最可能发生的问题是多个用户同时更新同一个块。如果没有自由的ITL槽,就会发生块级锁定。通过增大initrans 和/或maxtrans以允许使用多个ITL槽,或者增大表上的pctfree 值,就可以很轻松地避免这种情况。
D、TM enqueue 在DML 期间产生,以避免对受影响的对象使用DDL。如果有外来关键字,一定要对它们进行索引,以避免这种常见的锁定问题。
<7> log buffer space 日志缓冲空间 (写REDO慢-----增大log_buffer,redo log file放到快速磁盘上)
当日志缓冲(log buffer)写入重做日志(redo log)的速度比LGWR 的写入速度慢,或者是当日志转换(log switch)太慢时,就会发生这种等待。为解决这个问题,可以增大日志文件的大小,或者增加日志缓冲器的大小,或者使用写入速度更快的磁盘。甚至可以考虑使用固态磁盘,因为它们的速度很高。
<8> log file switch 日志文件转换 (归档慢-----增加或者扩大重做日志)
有两种情况:
A、log file switch (archiving needed)
当日志切换的时候由于日志组循环使用了一圈但日志归档还没有完成,通常是io有严重问题,可增大日志文件和增加日志组,调整log_archive_max_processes
B、log file switch (checkpoint incomplete)
当日志切换的时候由于日志组循环使用了一圈但将被使用的日志组中的checkpoint还没有完成造成,通常是io有严重问题,可增大日志文件和增加日志组
<9> log file sync 日志文件同步 (提交太频繁----批量提交)
当用户commit的时候通知lgwr写日志但lwgr正忙,造成的可能原因是commit太频繁或者lgwr一次写日志时间太长(可能是因为一次log io size 太大),可调整 _log_io_size,结合log_buffer,使得 (_log_io_size*db_block_size)*n = log_buffer,这样可避免和增大log_buffer引起冲突;放置日志文件于高速磁盘上
<10> library cache pin
该事件通常是发生在先有会话在运行PL/SQL,VIEW,TYPES等object时,又有另外的会话执行重新编译这些object,即先给对象加上了一个共享锁,然后又给它加排它锁,这样在加排它锁的会话上就会出现这个等待。P1,P2可与x$kglpn和x$kglob表相关
X$KGLOB (Kernel Generic Library Cache Manager Object)
X$KGLPN (Kernel Generic Library Cache Manager Object Pins)
-- 查询X$KGLOB,可找到相关的object,其SQL语句如下
(即把V$SESSION_WAIT中的P1raw与X$KGLOB中的KGLHDADR相关连)
select kglnaown,kglnaobj from X$KGLOB
where KGLHDADR =(select p1raw from v$session_wait
where event='library cache pin')
-- 查出引起该等待事件的阻塞者的sid
select sid from x$kglpn , v$session
where KGLPNHDL in
(select p1raw from v$session_wait
where wait_time=0 and event like 'library cache pin%')
and KGLPNMOD <> 0
and v$session.saddr=x$kglpn.kglpnuse
-- 查出阻塞者正执行的SQL语句
select sid,sql_text
from v$session, v$sqlarea
where v$session.sql_address=v$sqlarea.address
and sid=<阻塞者的sid>
这样,就可找到"library cache pin"等待的根源,从而解决由此引起的性能问题。
<11> library cache lock
该事件通常是由于执行多个DDL操作导致的,即在library cache object上添加一个排它锁后,又从另一个会话给它添加一个排它锁,这样在第二个会话就会生成等待。可通过到基表x$kgllk中查找其对应的对象。
-- 查询引起该等待事件的阻塞者的sid、会话用户、锁住的对象
select b.sid,a.user_name,a.kglnaobj
from x$kgllk a , v$session b
where a.kgllkhdl in
(select p1raw from v$session_wait
where wait_time=0 and event = 'library cache lock')
and a.kgllkmod <> 0
and b.saddr=a.kgllkuse
当然也可以直接从v$locked_objects中查看,但没有上面语句直观根据sid可以到v$process中查出pid,然后将其kill或者其它处理。
<5> latch free (等待LATCH FREE)
latch是一种低级排队机制(它们被准确地称为相互排斥机制),用于保护系统全局区域(SGA)中共享内存结构。latch 就像是一种快速地被获取和释放的内存锁。latch 用于防止共享内存结构被多个用户同时访问。如果latch 不可用,就会记录latch 释放失败。大多数latch 问题都与以下操作相关:不能使用邦定变量(库缓存latch)、重复生成问题(重复分配latch)、缓冲存储器竞争问题(缓冲器存储LRU 链),以及缓冲存储器中的"热"块(缓冲存储器链)。也有一些latch 等待与bug(程序错误)有关,如果怀疑是这种情况,可以检查MetaLink 上的bug 报告。
该事件的热点对象可通过以下语句查找,其中&2值是v$session_wait中的P1RAW,x$bh中的字段Hladdr表示该block buffer在哪个cache buffer chain latch 上,可以通过v$latch_children定位哪些segment是热点块。
===================================================
select a.hladdr, a.file#, a.dbablk, a.tch, a.obj, b.object_name
from x$bh a, dba_objects b
where (a.obj = b.object_id or a.obj = b.data_object_id)
and a.hladdr = &2
union
select hladdr, file#, dbablk, tch, obj, null
from x$bh
where obj in
(select obj from x$bh
where hladdr = &2
minus
select object_id from dba_objects
minus
select data_object_id from dba_objects)
and hladdr = &2
order by 4;
====================================================
***Latch 问题及可能解决办法
------------------------------
* Library Cache and Shared Pool (未绑定变量---绑定变量,调整shared_pool_size)
每当执行SQL或PL/SQL存储过程,包,函数和触发器时,这个Latch即被用到.Parse操作中此Latch也会被频繁使用.
* Redo Copy (增大_LOG_SIMULTANEOUS_COPIES参数)
重做拷贝Latch用来从PGA向重做日志缓冲区拷贝重做记录.
* Redo Allocation (最小化REDO生成,避免不必要提交)
此Latch用来分配重做日志缓冲区中的空间,可以用NOLOGGING来减缓竞争.
* Row Cache Objects (增大共享池)
数据字典竞争.过度parsing.
* Cache Buffers Chains (_DB_BLOCK_HASH_BUCKETS应增大或设为质数)
"过热"数据块造成了内存缓冲链Latch竞争.
* Cache Buffers Lru Chain (调整SQL,设置DB_BLOCK_LRU_LATCHES,或使用多个缓冲区池)
扫描全部内存缓冲区块的LRU(最近最少使用)链时要用到内存缓冲区LRU链Latch.太小内存缓冲区、过大的内存缓冲区吞吐量、过多的内存中进行的排序操作、DBWR速度跟不上工作负载等会引起此Latch竞争。
<12> db file parallel write
与DBWR进程相关的等待,一般代表了I/O能力出现了问题. 通常与配置的多个DBWR进程或者DBWU的I/O slaves个数有关.当然也可能意味着设备上存在着I/O竞争
<13> db file single write
表示在检查点发生时与文件头写操作相关的等待.通常与检查点同步数据文件头时文件号的紊乱有关.
<14> direct path read 和 direct path write
表示与直接I/O读相关的等待.当直接读数据到PGA内存时,direct path read 出现.这种类型的读请求典型地作为:排序IO(为排序不能在内存中完成的时候),并行Slave查询或者预先读请求等. 通常这种等待与I/O能力或者I/O竞争有关.
<15> free buffer inspected
表示在将数据读入数据调整缓存区的时候等待进程找到足够大的内在空间通常这类等待表示数据调整缓存区偏小.
<16> library cache load lock
表示在将对象装载到库高速缓存时出现了等待.这种事件通常代表着发生了负荷尔蒙很重的语句重载或者装载,可能由于SQL语句没有共享或者共享池区域编小造成的.
<17> log file parallel write
表示等待LGWR向操作系统请求I/O开始直到完成IO.在触发LGWR写的情况下如3秒、1/3、1MB、DBWR写之前可能发生.这种事件发生通常表示日志文件发生了I/O竞争或者文件所在的驱动器较慢
<18> log file single write
表示写日志文件头块时出现了等待.一般都是发生在检查点发生时.
<19> transaction
表示发生了一个阻塞回滚操作的等待
<20> undo segment extension
表示在等待回滚段的动态扩展.这表示可能事务量过大,同时也意味着可能回滚段的寝大小不是最优,MINEXTENTS设置得偏小.考虑减少事务,或者使用最小区数更大的回滚段.
详细出处参考:http://www.jb51.net/article/17387.htm

 

 

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

我们可以通过视图v$session_wait来查看系统当前的等待事件,以及与等待事件相对应的资源的相关信息

详细出处参考:http://www.jb51.net/article/17387.htm

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

请登录后发表评论 登录
全部评论

注册时间:2008-06-02

  • 博文量
    519
  • 访问量
    490238