zoukankan      html  css  js  c++  java
  • 常见等待事件

    1. Buffer busy waits

            原因:
            当一个会话试图修改一个数据块,但这个数据块正在被另一个会话修改时。
            当一个会话需要读取一个数据块,但这个数据块正在被另一个会话读取到内存中时。
            备注:数据处理的最小单位是块

    select name,parameter1,parameter2,parameter3 from v$event_name where name='buffer busy waits'; 
    NAME              PARAMETER1 PARAMETER2 PARAMETER3
    -------------------- ---------- ---------- ----------
    buffer busy waits file#      block#     class#

    File#:等待访问数据块所在的文件id号。
    Blocks:等待访问的数据块号。
    class#:原因码
    A、如果等待处于字段头部,应增加自由列表(freelist)的组数,或者增加pctused到pctfree之间的距离。
    B、如果等待处于回退段(undo)头部块,可以通过增加回滚段(rollback segment)来解决缓冲区的问题;
    C、如果等待处于回退段(undo)非头部块上,就需要降低驱动一致读取的表中的数据密度,或者增大DB_CACHE_SIZE;
    D、如果等待处于数据块,可以将数据移到另一数据块以避开这个"热"数据块、增加表中的自由列表或使用LMT表空间;
    E、如果等待处于索引块,应该重建索引、分割索引或使用反向键索引。

     问题处理:

    select segment_type, owner || '.' || segment_name
    from dba_extents
    where file_id = file_id
    and block_id between block_id and block_id + blocks - 1;

    2、DB file scattered read
    最常见的两种情况是全表扫描(FTS:Full Table Scan)和索引快速扫描(IFFS:index fast full scan)

    3、Direct path read
    当发生direct path read等待事件时,意味着磁盘上有大量的临时数据产生,比如排序,并行执行等操作。或者意味着PGA中空闲空间不足。

    4、Direct path write
    这个等待事件和direct path read正好相反,是会话将一些数据从PGA中直接写入到磁盘文件上,而不经过SGA。
    这种情况通常发生在:
    a.使用临时表空间排序(内存不足);
    b.数据的直接加载(使用append方式加载数据);
    c.并行DML操作。

    5、Free buffer waits
    当一个会话将数据块从磁盘读到内存中时,它需要到内存中找到空闲的内存空间来存放这些数据块,当内存中没有空闲的空间时,就会产生这个等待;除此之外,还有一种情况就是会话在做一致性读时,需要构造数据块在某个时刻的前映像(image),此时需要申请内存来存放这些新构造的数据块,如果内存中无法找到这样的内存块,也会发生这个等待事件。
    当数据库中出现比较严重过的free buffer waits等待事件时,可能的原因是:
    (1)、data buffer太小,导致空闲空间不够;
    (2)、内存中的脏数据太多,DBWR无法及时将这些脏数据写到磁盘中以释放空间。
    这个等待事件包含2个参数:
    File#:需要读取的数据块所在的数据文件的文件号。
    Block#:需要读取的数据块块号。

    6、Library cache lock
    一般可以理解的是alter table或者alter package/procedure会以X模式持有library cache lock,造成阻塞。
    但是常见的问题还有以下几种原因:
    1)错误的用户名密码:
    2)正在执行搜集统计信息,这是大家往往会忽略的,一般会看last_ddl_time,却忽略了last_analyzed,
    检查脚本如下:
    比如EMP是遇到library cache lock中的表名:

    select owner,object_name,object_type,to_char(last_ddl_time,'yyyy-mm-dd hh24:mi:ss') from dba_objects where object_name='EMP';
    select table_name,to_char(last_analyzed,'yyyy-mm-dd hh24:mi:ss') from dba_tables where table_name='EMP';

    也需要检查所有dependency的对象,因为oracle对象是相互关联的,一个对象失效会导致一串失效。

    复制代码
    select owner,object_name,object_type,to_char(last_ddl_time,'yyyy-mm-dd hh24:mi:ss') ddl_time from dba_objects where object_name in
    (
    select p.name
    from sys.obj$ d, sys.dependency$ dep, sys.obj$ p
    where d.obj# = dep.d_obj# and p.obj# = dep.p_obj#
    start with d.name='EMP'
    connect by prior dep.p_obj#=dep.d_obj#)
    order by ddl_time desc;
    
    select table_name,to_char(last_analyzed,'yyyy-mm-dd hh24:mi:ss') from dba_tables where table_name in
    (
    select p.name
    from sys.obj$ d, sys.dependency$ dep, sys.obj$ p
    where d.obj# = dep.d_obj# and p.obj# = dep.p_obj#
    start with d.name='EMP'
    connect by prior dep.p_obj#=dep.d_obj#)
    order by last_analyzed desc;
    复制代码

    3)错误的语句解析(failed parse)

    4)bug

    7、Library cache pin
    这个等待事件和library cache lock一样是发生在共享池中并发操作引起的事件。通常来讲,如果Oracle要对一些PL/SQL或者视图这样的对象做重新编译,需要将这些对象pin到共享池中。
    如果此时这个对象被其他的用户特有,就会产生一个library cache pin的等待。

    8、Log buffer space
    当log buffer中没有可用空间来存放新产生的redo log数据时,就会发生log buffer space等待事件。如果数据库中新产生的redo log的数量大于LGWR写入到磁盘中的redo log数量,必须等待LGWR完成写入磁盘的操作,LGWR必须确保redo log写到磁盘成功之后,才能在redo buffer当中重用这部分信息。
    如果数据库中出现大量的log buffer space等待事件,可以考虑如下办法:
    (1)、增加redo buffer的大小。
    (2)、提升磁盘的I/O性能。

    9、Log file sequential read
    这个等待事件通常发生在对redo log信息进行读取时,比如在线redo的归档操作,ARCH进程需要读取redo log的信息,由于redo log的信息是顺序写入的,所以在读取时也是按照顺序的方式来读取的。

    10、Log file switch(archiving needed)
    在归档模式下,这个等待事件发生在在线日志切换(log file switch)时,需要切换的在线日志还没有被归档进程(ARCH)归档完毕的时候。当在线日志文件切换到下一个日志时,需要确保下一个日志文件已经被归档进程归档完毕,否则不允许覆盖那个在线日志信息(否则会导致归档日志信息不完整)。
    出现这样的等待事件通常是由于某种原因导致ARCH进程死掉,比如ARCH进程尝试向目的地写入一个归档文件,但是没有成功(介质失效或者其他原因),这时ARCH进程就会死掉。如果发生这种情况,在数据库的alert log文件中可以找到相关的错误信息。

    11、Log file switch(checkpoint incomplete)
    当一个在线日志切换到下一个在线日志时,必须保证要切换到的在线日志上的记录信息(比如一些脏数据块产生的redo log)被写到磁盘上(checkpoint),这样做的原因是,如果一个在线日志文件的信息被覆盖,而依赖这些redo信息做恢复的数据块尚未被写到磁盘上(checkpoint) ,此时系统down掉的话,Oracle将没有办法进行实例恢复。
    在v$log视图里记录了在线日志的状态。通常来说,在线日志有三种状态。
    Active:这个日志上面保护的信息还没有完成checkpoint。
    Inactive:这个日志上面保护的信息已完成checkpoint。
    Current:当前的日志。
    Oracle在做实例恢复时,会使用状态为current和active的日志进行实例恢复。
    如果系统中出现大量的log file switch(checkpoint incomplete)等待事件,原因可能是日志文件太小或者日志组太少,所以解决的方法是,增加日志文件的大小或者增加日志组的数量。

    12、Log file sync
    引起log file sync的原因:
    1.频繁提交或者rollback,检查应用是否有过多的短小的事务,如果有,可以使用批处理来缓解。
    2.OS的IO缓慢:解决办法是将日志文件放裸设备上或绑定在RAID 0或RAID 1+0中,而不是绑定在RAID 5中。
    3.过大的日志缓冲区(log_buffer ) 过大的log_buffer,允许LGWR变得懒惰,因为log buffer中的数据量无法达不到_LOG_IO_SIZE,导致更多的重做条目堆积在日志缓冲区中。
    当事务提交或者3s醒来时,LGWR才会把所有数据都写入到redo log file中。 由于数据很多,LGWR要用更多时间等待redo写完毕。
    这种情况,可以调小参数_LOG_IO_SIZE参数,其默认值是LOG_BUFFER的1/3或1MB,取两者之中较小的值。
    换句话说,你可以具有较大的日志缓冲区,但较小的_LOG_IO_SIZE将增加后台写入次数,从而减少log file sync的等待时间。
    4.CPU负载高。详见下面的描述。
    5.RAC私有网络性能差,导致LMS同步commit SCN慢

    判断:
    1.如果log file sync的等待时间很高,而log file parallel write的等待时间并不高,这意味着log file sync的原因并不是缓慢的日志I/O,而是应用程序过多的提交造成。
    当log file sync的等待时间和 log file parallel write等待时间基本相同,说明是IO问题造成的log file sync等待事件。
    2.Lgwr trace file(10.2.0.4开始),大于500ms会写入
    trace文件中如果有Warning: log write time 1000ms, size 2KB,很有可能IO慢。3.分析CPU资源使用情况的工具,CPU过于繁忙,lgwr无法及时获取CPU调度,出现log file sync。
    vmstat,关注r是否大于CPU核数,大于说明cpu繁忙。
    log file sync=CPU+几个latch+log file parallel write(此处latch申请一般不是瓶颈)
    --如果log file sync远大于log file parallel write的等待时间,只会为以下三种情况
    1、CPU资源紧张
    2、LGWR在申请latch资源时遇到竞争(IMU未使用,RAC环境下不适用)
    3、同时提交的进程太多

    解决办法:
    1.如果确实是因为频繁提交造成的log file sync,那么减少commit,批量提交。
    2.如果确实是因为io引起的,那么解决办法是将日志文件放裸设备上或绑定在RAID 1+0中,而不是放在在RAID 5中(切记,redo log file一定不要放在SSD上!!!)。
    3.确保CPU资源充足。CPU资源不足,LGWR通知user session后,user session无法及时获得CPU调度,不能正常工作。
    4.是否有些表可以使用nologging,会减少redo产生量5.检查redo log file足够大,确保redo log file每15到20分钟切换一次。

    13、cursor: pin S wait on X
    cursor: pin S,cursor: pin X,cursor: pin S wait on X这三个等待事件,实际上就是替代了cursor的library cache pin,pin S代表执行(share pin),pin X代表解析(exclusive pin),
    pin S wait on X代表执行正在等待解析操作。
    这里需要强调一下,它们只是替换了访问cursor的library cache pin,而对于访问procedure这种实体对象,依然是传统的library cache pin。
    cursor: pin S wait on X,这个等待事件主要是由硬解析引起的
    --硬解析,软解析,软软解析在共享池中的等待事件
    1、硬解析:latch: shared pool,硬解析需要所有类型的mutex,包括library cache: mutex,cursor: pin,HASH Table,cursor Parent
    2、软解析:library cache: mutex,cursor: pin,HASH Table,cursor Parent
    3、软软解析(将子游标堆6的信息,缓存在PGA中。子游标堆6:保存执行计划信息):两次cursor: pin S和一次library cache: mutex X(如果使用绑定变量或且使用静态游标,会导致一次library cache: mutex X)
    4、sql版本过多:library cache和HASH Table类型等待
    总结:如果只有cursor: pin类型和library cache: mutex型竞争激烈,是软软解析问题;如果还有其他类mutex型等待,则是软解析导致。如果再有shared pool latch竞争激烈,一定是硬解析过多,由于大量进程同时请求从共享池中分配内存导致;
    版本过多的硬解析:library cache lock和HASH Table类型等待同时出现,如果只有HASH Table类型等待而没有library cache lock,则是版本过多的父游标有很多并发的软解析。

    硬解析导致异常等待处理:使用绑定变量(应用层面),cursor sharing=true 禁用ACS(adaptive cursor sharing),配置充足的shared pool v$sqlarea sql_text列中相似的sql很多,说明未使用绑定变量
    软解析争用处理:调整session cached cursors参数,使软解析变为软软解析
    软软解析导致争用处理:cursor pin:s ,使用提示符/**/改变sql hash值,将一条SQL变为多条减少争用;应用层缓存游标,实现一次解析,多次执行


    --导致oracle high version count(高版本游标)
    原因:1、owner不同 2、表统计信息发生变化 3、系统环境统计信息发生变化
    SELECT * FROM v$sql_shared_cursor e WHERE e.SQL_ID = 'a4tjn5xjzx2mt'
    绑定变量长度变大会导致BIND_MISMATCH

    14、latch:cache buffers chains
    一般产生CACHE BUFFERS CHAINS的原因有几个方面:

    1、buffer cache太少(也说明SQL语句效率低,较多的逻辑读意味着较多的latch get操作,从而增加了锁存器争用。多个进程同时扫描大范围的索引或表时,可能广泛地发生cache buffers chains 锁存器争用);

    2、热块挣用。(从oracle9i开始,对latch:cache buffer chains支持只读共享访问,这可以减少部分争用,但并不能完全消除争用。)
    当多个会话重复访问一个或多个由同一个子cache buffers chains锁存器保护的块时,就会产生热块挣用。当多个会话争用cache buffers chains锁存器时,找出是否有热块的最好的方法是检查latch free等待事件的P1RAW参数值。
    判断热块挣用的另一种方法是从 v$session_wait 视图获得锁存器地址后进行比较。v$session_wait的P1RAW就相当于子锁存器地址,若从 v$session_wait 视图获得的锁存器地址过多重复出现,就意味着对相应锁存器发生次数偏多,此时可解释为热快引起的争用。如果会话正在相同的锁存器地址上等待,就是热块。

    SQL> select sid,p1raw,p2,p3,seconds_in_wait,wait_time,state from v$session_wait where event='latch: cache buffers chains' order by 3,2;

    使用P1RAW=00000300DA316800为例子进行关联热快对象。

    SQL> 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 = '00000300DA316800'
    union select hladdr,file#,dbablk,tch,obj,null from x$bh
    where obj in (select obj from x$bh where hladdr = '00000300DA316800' minus select object_id from dba_objects minus select data_object_id from dba_objects) and hladdr = '00000300DA316800' order by 4;

    转自:https://www.cnblogs.com/vadim/p/6930819.html

  • 相关阅读:
    SQL-排名函数
    SQL-简单查询
    SQL-判断表是否存在
    HDU1557权利选举
    Bresenham画直线,任意斜率
    LCS最长公共子序列HDU1159
    zoj1276矩阵连乘dp
    OJ的文件流操作
    dp题目
    翻纸牌 高校俱乐部 英雄会 csdn
  • 原文地址:https://www.cnblogs.com/JIKes/p/14235533.html
Copyright © 2011-2022 走看看