一、等待事件发展

oracle等待事件引入,可以更加细粒度直观地观察Oracle行为,提供oracle优化入口,大致分为三个阶段:

  • 以命中为主要参考指标:以各种命中率为主要的优化入口依据,常见的有”library cache hit radio“等,该方式具有一定的局限性,命中率高性能不一定好。
  • 以等待事件为主要参考指标:以各种等待事件为优化入口依据,比如“db_scattered_read”,可以较为明确地提供一段时间内,什么等待事件,导致现在的优化瓶颈出现。
  • 以时间模型为主要参考指标:以各种资源消耗为优化入口依据。整体地了解数据库在一段时间内的消耗情况。较等待事件方式,有更强的概括性。比如 db time;

二、等待事件分类

大致上分为空闲等待及非空闲等待事件,而非空闲等待事件可以继续更细致的划分:

select distinct(wait_class),count(*),event from v$session_wait group by wait_class,event;

如上表示,WAIT_CLASS为 Idle表示空闲等待,其它的都是非空闲等待。

1、区分空闲等待与非空闲等待

  • 空闲等待事件:是指oracle正在等待某种工作,比如‘SQL*Net message from client’ 表示一个登录sqlplus的会话,当前正在空闲。诊断时一般不过多关注该类事件。
  • 非空闲等待事件:专门针对ORACLE的活动,指数据库任务和应用运行过程中发生的等待,这些等待事件是调整数据库时应该关注和研究的。

2、等待事件分类说明

-- 查看等待事件分类情况:
SELECT WAIT_CLASS#,WAIT_CLASS_ID, WAIT_CLASS, COUNT(*) "COUNT"
FROM V$EVENT_NAME
GROUP BY WAIT_CLASS#, WAIT_CLASS_ID, WAIT_CLASS
ORDER BY WAIT_CLASS#;
  • 管理类Administrative:此类等待事件是由于DBA的管理命令引起的,这些命令要求用户处于等待状态(比如重建索引等)。
  • 应用程序类-Application:此类等待事件是由于用户应用程序代码所引起(比如锁)。
  • 集群类(cluster):此类等待事件和真正应用群集RAC的资源有关(比如,gc cr block busy等待事件)。
  • 提交确认类-Commit:此类等待事件只包含一种等待事件----在执行一个commit命令之后,等待一个重做日志写确认(也就是 log file sync)
  • 并发类Concurrency:此类等待事件是内部数据库资源引起的(比如闩锁)
  • 配置类Configuration:此类等待事件是由数据库或者实例配置不当导致的(比如,重做日志文件尺寸太小,共享池的大小等)
  • 空闲类-Idle:此类等待事件意味着会话不活跃,等待工作比如‘SQL*Net message from client’
  • 网络类-NetWork:和网络相关的一些等待事件比如sql* net more data to dblink) 。
  • 其它类-Other:此类等待事件通常比较少见(比如wait for EMON to spawn)
  • 调度类-Scheduler:此类等待事件和资源管理相关(比如resmgr: become active)
  • 系统I/O类-System I/O:此类等待事件是由后台进程I/O操作引起的(比如DBWR等待-db file paralle write)
  • 用户I/O类-User I/O:此类等待事件通常由用户I/O操作引起的(比如db file sequential read)

三、理解等待事件

  • 每一个等待事件,都表明数据库的一种活动状态;
  • 视图V$EVENT_NAME可以方便去了解每个等待事件,以及与等待事件相对应的资源的相关信息;
  • 可以通过视图v$session_wait来查看系统当前的等待事件,以及与等待事件相对应的资源的相关信息,从而可确定出产生瓶颈的类型及其对象。v$SESSION_WAIT的p1、p2、p3告诉我们等待事件的具体含义,根据事件不同其内容也不相同

四、常见等待事件

  1. db file scattered read DB文件分散读(太多索引读以及全表扫描----调整代码将小表放入内存):

    这种情况是与全表扫描相关的等待事件。全表扫描被限制在内存时,它们很少会进入缓冲区内,而是分散于整个缓冲存储器中。如果这个数目很大,就表明该表找不到索引,或者只能找到有限的索引。尽管存在特定条件下全表扫描比索引扫描更有效,但需要确认这种扫描是否必要。因为全表扫描被置于LRU(Least Recently Used,最近最少适用)列表的冷端(cold end),所以应尽量存储较小的表以避免一次又一次地重复读取;

    SELECT P1TEXT,P1,P2,WAIT_CLASS FROM V$SESSION;

    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文件顺序读取 (表连接顺序不佳-----调整代码,特别是表连接),单块读等待是一种最为常见的物理IO等待事件,这里sequential 指的是将数据块读入到相连的内存空间中(contiguous memory),而不是指读取的数据块是连续的。该wait event可能在以下情景中发生:

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

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

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

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

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

    analyze table list chained rows命令来获取必要的链式行信息还有包:

    BEGIN

    DBMS_STATS.GATHER_TABLE_STATS(ownname => 'USERNAME', tabname => 'TABLE_NAME');

    END;

    /

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

    7.针对表上的UPDATE/DELETE,不同于之前提到的"INDEX RANGE SCAN-UPDATE/DELETE",如果我们使用rowid去更新或删除数据时,服务进程会先访问rowid指向的表块(注意是先访问table block)上的行数据,之后会根据该行上的具体数据去访问索引叶子块(注意Oracle并不知道这些leaf block在哪里,所以这里同样要如 range-scan/unique-scan那样去访问 index branch block),这些访问都将会是单块读取,并会出现'db file sequential read',完成必要的读取后才会执行更新或删除的实际EXEC操作

  3. free buffer waits释放缓冲区等待(增大DB_CACHE_SIZE,加速检查点,调整代码):这种等待表明系统正在等待内存中的缓冲,因为内存中已经没有可用的缓冲空间了。如果所有的sql都得到了调优,这种等待可能表示你需要增大DB_BUFFER_CACHE。释放缓冲区等待也可能表示不加选择的SQL导致数据溢出带有索引块的缓冲存储器,没有为等待系统处理的特定语句留有缓冲区。这种情况通常表示正在执行相当多数量的DML(插入、更新、删除),并且数据库书写器(DBWR)写的速度不够快,缓冲存储器可能充满了相同缓冲器的多个版本,从而导致效率非常低。为了解决这个问题,可能需要考虑增加检查点,利用更多的DBWR进程,或者增加物理磁盘的数量。

  4. buffer bussy 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指定的数量)。
  5. 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等待,通常由以下三个问题产生结果:
        1)是唯一索引中的重复索引,则需要执行提交(commit)/回滚(rollback)操作来释放enqueue。
        2)是对同一位图索引段的多次更新。因为单个位图段可能包含多个行地址(rowid),所以当多个用户试图更新同一段时,你需要执行提交或回滚操作,以释放enqueue。
        3)也是最可能发生的问题是多个用户同事更新同一个块。如果没有自由的ITL槽,就会发生块级锁定。通过增大initrans 和/或maxtrans以允许使用多个ITL槽,或者增大表上的pctfree值,就可以个很轻松避免这个情况。
    D、TM enqueue在DML期间产生,以避免对受影响的对象使用DDL。如果有外来关键字,一定要对它们进行索引,以避免这种常见的索引为题;

  6. log buffer space 日志缓冲空间(写 REDO慢----增大log_buffer,redo log file放到快速磁盘上)
    当日志缓冲(log buffer)写入重做日志(redo log)的速度比LGWR的写入数据慢,或者是当日志转换(log switch)太慢是,就会发生这种给等待。
    为解决这个问题,可以增大日志文件的大小,或者增大日志缓冲器的大小,或者使用写入速度更快的磁盘。甚至可以考虑使用固态磁盘,因为他们的速度很高。

  7. log file switch 日志文件转换(归档慢-----增加或者扩大重做日志)
    有两种情况:
    A、log file switch(archiving needed)
        当日志切换的时候由于日志组循环使用了一圈但日志归档还没有完成,通常是IO有严重问题,可增大日志文件和增加日志组,调整log_archive_max_processes
    B、log file switch(checkpoint incomplete)
        当日志切换的时候由于日志玄幻使用了一圈但将被使用的checkpoint还没有完成所造成,通常是IO有严重问题,可以增大日志文件和增加日志组

  8. log file sync 日志文件同步(提交太频繁----批量提交)
    当用户commit的时候通知lgwr写日志但lgwr正忙,造成的原因可能是commit太频繁或者lgwr一次写日志的时间太长(可能是因为一次log io size 太大)
    可调整 _log_io_size,结合log_buffer,使得(_log_io_size*db_block_size)*n=log_buffer,这样可以避免和增大log_buffer引起冲突;放置日志文件于高速磁盘上

  9. library cache pin
    该事件通常是发生在先有会话在运行PL/SQL,VIEW,TYPES等object时,又有另外的会话执行重新编译这些object,即先给对象加上了一个共享锁,
    然后又给它加排它锁,这样在加排它锁的会话上就会出现这个等待。P1,P2可与x$kglpn及X$KGLOB表相关
        X$KGLOB(Kernel Generi Library Cache Manager Object)
        X$KGLPN(Kernel Generi 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"等待的根源,从而解决由此引起的性能问题

  10. library cache lock
    该事件通常是由于执行多个DDL操作导致的,即在library cache object上添加一个排它锁后,又从另一个会话给它添加一个排它锁,
    这样在蝶儿个会话就会生成等待。可通过到基表想x$kgllk中查找其对应的对象。
    --查询引起该等待时间的阻塞者的sid、会话用户、锁住的对象

    --查询引起该等待时间的阻塞者的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或者其他方式处理
    
    比如尝试使用kill方式进行会话释放
    set linesize 200
    set pagesize 2000
    col username for a30
    col status for a20
    col event for a40
    select username,sid,STATUS,EVENT from v$session where status='INACTIVE';
    --假设尝试kill空闲类等待
    SQL*Net message from clientselect b.sid,a.user_name,a.kglnaobj,c.spid
    from x$kgllk a,V$session b,v$process c
    where a.kgllkhdl in
    (select p1raw from v$session_wait where wait_time=0 and event='SQL*Net message from client')
    and a.kgllkmod<>0 and b.saddr=a.kgllkuse and a.addr=c.addr;
    --根据此句SQL可以找到对应的SPID根据SPID进行kill 操作完成会话释放
    select s.sid,s.username,s.event,s.status,p.addr,p.spid from v$session s,v$process p where s.paddr=p.addr and s.event='SQL*Net message from client';
  11. db file parallel write
    与DBWR进程相关的等待,一般代表I/O能力出现了问题。通常与配置的多个DBWR进程或者DBWU的I/O slaves个数相关。当然也可能意味着设备上存在I/O竞争。

  12. direct path read 和 direct path write
    表示与直接I/O读相关的等待。当直接读数据到PGA内存时,direct path read出现。这种类型的读请求典型地作为:排序IO(为排序不能在内存中完成的时候),
    并行Slave查询或者预先读请求等。通常这种等待与I/O能力或者I/O竞争有关。

  13. free buffer inspected
    表示在将数据读入数据调整缓存区的时候等待进城找到足够大的内在空间通常这类等待表示数据调整缓存区偏小

  14. library catche load lock
    表示在将对象装载到库高速缓存时出现了等待,这种事件通常代表发生了负荷很高的语句重载或者装载,可能由于sql语句没有共享或者共享池偏小所导致。

  15. log file parallel write
    表示等待LGWR操作向系统请求I/O开始直到完成I/O,在触发LGWR写的情况下如3s、1/3,1mb ,DBWR写之前可能发生。这类事件通常表示日志文件发生I/O竞争或者
    文件所在的驱动器较慢。

  16. log file single write
    表示写日志文件头块时出现了等待,一般都是发生在检查点发生时。

  17. transaction
    表示发生了一个阻塞回滚的操作等待。

  18. undo segment extension
    表示在等待回归短的动态扩展,这表示可能事物量过大,同事也意味着可能回滚段的大小不是最优,MINEXTENTS设置偏小,考虑减少事务,或者使用最小区数更大的回滚段。

  19. 未完待补充。。。。

ORACLE等待事件相关相关推荐

  1. oracle 等待原因查找,oracle等待事件相关查询

    --------------------------查询数据库等待时间和实际执行时间的相对百分比--------------------- select * from v$sysmetric a wh ...

  2. CPU值满resmgr:cpu quantum造成的Oracle等待事件解决办法

    cpu quantum造成的Oracle等待事件解决办法 不少接触数据库的朋友有一个困扰已久的问题--resmgr:cpu quantum.已经遇过不少次这种CPU突然全绿的情况,通过隐含参数屏蔽了一 ...

  3. ORACLE 等待事件的分类

    等待事件是总个性能调优的入口. 在总体查看ORACLE数据库性能时,总是会先看TOP  N WAIT,比如: 下面我切了一段我的AWR报表内容: Top Timed Events      '*' C ...

  4. 浅析Oracle等待事件

    oracle 等待事件 一.简述 Oracle等待事件是在Oracle 7.0.12中引入的,当时等待事件大致有100多个:在Oracle 8.0中Oracle等待事件数目增加到150多个,在Orac ...

  5. oracle library cache lock,【案例】Oracle等待事件library cache lock产生原因和解决办法...

    [案例]Oracle等待事件library cache lock产生原因和解决办法 时间:2016-12-07 18:56   来源:Oracle研究中心   作者:网络   点击: 次 天萃荷净 O ...

  6. Oracle Study之--Oracle等待事件(3)

    Oracle Study之--Oracle等待事件(3) Db file parallel read 这是一个很容易引起误导的等待事件,实际上这个等待事件和并行操作(比如并行查询,并行DML)没有关系 ...

  7. oracle顺序读等待,Oracle Study之--Oracle等待事件(4)

    Oracle Study之--Oracle等待事件(4) Db file scattered read这个等待事件在实际生产库中经常可以看到,这是一个用户操作引起的等待事件,当用户发出每次I/O需要读 ...

  8. oracle logfile sync,oracle等待事件3构造一个DirectPathwrite等待事件和构造一个LogFileSync等待事件...

    第一篇<oracle等待事件1分别用表和索引上数据的访问来产生dbfilescatteredread等待事件>http://leonarding.blog.51cto.com/604552 ...

  9. oracle等待资源时间加长,案例:Oracle等待事件latch: cache buffers chains故障优化处理总结...

    天萃荷净 数据库的CPU使用率为100%,应用相应迟缓.查看AWR中数据库的latch:cache buffers chains等待较多 当一个数据块读入sga区,相应的buffer header会被 ...

最新文章

  1. [3D]绘制XYZ小坐标轴
  2. MAXIEYE创始人周圣砚:以规模化迎接智能驾驶科技平权时代 | MEET2022
  3. SQL Server查询性能优化——堆表、碎片与索引(一)
  4. java生成二维码/java解析二维码
  5. html 值追加,从JSON中读取数据追加到HTML中
  6. 逗号操作符以及(0,function)()
  7. Mac下cocos2dx-3.2+Xcode环境配置和项目创建
  8. Winfrom实现圆角设计
  9. 前端性能优化的七大手段
  10. 网站统计功能的设计与实现
  11. 全国各省市县统计年鉴/中国环境统计年鉴/中国工业企业数据库/中国专利数据库/污染排放数据库
  12. Ericsson面试经验总结及自我反省
  13. 浙大PAT 乙级(Basic Level) Practice 题解合集(全AC版)
  14. 常见耳机品牌简介及鉴赏
  15. JS 案例 个人所得税计算器
  16. javaSE基础大全--知识点总结
  17. 如何绕过强制门户——克隆 MAC 地址
  18. 简单阶乘计算 (本题要求实现一个计算非负整数阶乘的简单函数)
  19. Win10/UWP 扫描二维码
  20. 零售EDI:家乐福Carrefour EDI需求分析

热门文章

  1. 转载分享:Android8.0 连接需要认证的WIFI或不可用的WIFI后自动断开数据流量连接的实现
  2. 佐藤ひろ美 - わたしのそらのいろ
  3. prgrmz的作品集
  4. 矩阵分解及其Eigen实现
  5. 求2的零次方 加 2的一次方 加2的二次方等等的和
  6. 新款宝马MINI钥匙增加!轻松搞定,这MINI看着还可以噢
  7. 使用手机调试Android软件
  8. Git及Github之入门到进阶
  9. 118句最新QQ励志个性签名
  10. 中点分割裁剪算法 c语言,裁剪算法——中点分割算法/Liang-Barsky算法