Oracle常见的等待事件

Buffer busy waits

   

   这个等待事件说明了一个会话在等待一个Buffer(数据块),但是导致这个现象的原因却有很多种。

   

   在10g R1以前的版本中buffer busy waits包含两种情况:
    1)当一个会话视图修改一个数据块,但这个数据块正在被另一个会话修改时。
    2)当一个会话需要读取一个数据块,但这个数据块正在被另一个会话读取到内存中时。
   从10g R1版本开始,第2)种情况作为read by other session 事件提交,而 buffer busy waits 事件则只表示第1)种情况


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

   Buffer busy waits等待事件常见于数据库中存在的热快的时候,当多个用户频繁地读取或者修改同样的数据块时,这个等待事件就会产生。
  
   这个等待事件有三个参数:
   File#: 等待访问数据块所在的文件id号。
   Blocks: 等待访问的数据块号。
   ID: 在10g之前,这个值表示一个等待时间的原因,10g之后则表示等待事件的类别。

  

  以下链接是vage对这个事件情况的详细描述,可以作为参考:

  http://www.itpub.net/thread-1593488-1-1.html


 

Bache buffers chains latch

 

  latch: cache buffers chains 这个等待事件通常有两种原因:
  

  1)逻辑读太高,SQL执行计划走错。因为逻辑读高了之后,就要去判断大量的block 是否存在于buffer cache中,而判断block是否存在于数据库中就要获得 latch: cache buffers chains。 解决办法一般是优化Top SQL,对表收集最新的统计信息等。
  

  2)热点块,或者是 hash bucket 不足。buffer cache中block的header是被放置到hash chains上,而hash chains又是放在hash bucket中,多个hash bucket被一个cache buffers chains latch保护。当多个session并发访问同一个数据块上的数据,每个session都 要首先获得cache buffers chains latch,这样将造成cache buffers chains latch的争用。解决办法是找出热快,分散热块数据,减少争用。
    
     http://www.xifenfei.com/1109.html

 


Control file parallel write


    control file parallel write等待事件通常发生在服务器进程(Server Process)更新控制文件时,此时必须等待I/O的完成,这也代表控制文件所在的磁盘I/O相当频繁。
   控制文件里记录了数据库的SCN信息,当前日志号,归档日志信息,备份集信息,数据文件信息等等。而这些信息,很多都是需要更新的,更新的频率视情况而定。更新当前日志号的信息,是发生日志切换的时候需要做的,更新备份集的信息是在用RMAN备份的时候需要做的。一般来说,大体有一下几种常见的情况:
  1)日志文件过小,或者数据库DML操作太多,导致日志切换太过频繁。

     日志的切换都是需要更新控制文件的,此时的表现就是  LGWR进程等待control file parallel write事件。

  2)MTTR设置的过小,导致检查点频繁发生。

     我们知道控制文件里是记录SCN信息的,检查点发生的时候,是需要更新SCN的,    特别是10g以后的增量检查点,当发生增 量检查点的时候,会3秒更新一次控制文件中记录的RBA信息。

  3)NOLOGGING 导致的频繁更新数据文件。

     对数据文件在nologging选项下执行修改工作时,为了修改unrecoverable scn需要更新控制文件。这时,服务器进程将等待crontrol   file parallel write事件。

  4)i/o系统的性能缓慢时

     将控制文件分开放置,以分散I/O,也可以考虑启用操作系统Asynchronous I/O与设置Oracle参数DISK_ASYNCH_IO。


    http://space.itpub.net/22034023/viewspace-680923


Control file sequential read


   读取控制文件的时候遇到I/O等待就会出现这个等待事件,例如备份控制文件的时候、读取BLOCK头部都会引起这个等待事件,等待的时间就是消耗在读取控制文件上的时间。
   解决办法同Control file parallel write。


Control file single write

   

   类似于control file sequential read,这个等待事件出现在写控制文件的共享信息到磁盘的时候,这是个自动操作,并且通过一个实例来保护的,如果是并行的数据库服务器,那么对于并行服务器来说也只能有一个实例能够执行这个操作。这个事件的等待事件就是写操作所消耗的时间。
   解决办法同Control file parallel write。


Cursor: pin S wait on X

   

   当一个会话对一个游标请求共享互斥pin的时候,这个游标已经被其他会话独占持有,这个时候就发生了cursor: pin S wait on X等待事件。
   这个等待事件的出现受到很多因素的影响,在高并发的情况下:
  1)sga自动管理,sga的频繁扩展和收缩
  2)过渡硬解析,造成library cache中的cursor object被频繁的reload
  3)bug


   http://blog.csdn.net/tianlesoftware/article/details/6549018

   

Db file parallel read

   

   这是一个很容易引起误导的等待事件,实际上这个等待事件和并行操作(比如并行查询,并行DML)没有关系。 这个事件发生在数据库恢复的时候,当有一些数据块需要恢复的时候,Oracle会以并行的方式把他们从数据文件中读入到内存中进行恢复操作。

 

Db file parallel write

  

   这是一个后台等待事件,它同样和用户的并行操作没有关系,它是由后台进程DBWR产生的,当后台进程DBWR想磁盘上写入脏数据时,会发生这个等待。
   DBWR会批量地将脏数据并行地写入到磁盘上相应的数据文件中,在这个批次作业完成之前,DBWR将出现这个等待事件。 如果仅仅是这一个等待事件,对用户的操作并没有太大的影响,当伴随着出现free buffer waits等待事件时,说明此时内存中可用的空间不足,这时候会影响到用户的操作,比如影响到用户将脏数据块读入到内存中。
   当出现db file parallel write等待事件时,可以通过启用操作系统的异步I/O的方式来缓解这个等待。 当使用异步I/O时,DBWR不在需要一直等到所有数据块全部写入到磁盘上,它只需要等到这个数据写入到一个百分比之后,就可以继续进行后续的操作。

 

 

Db file scattered read

  

   这个等待事件在实际生产库中经常可以看到,这是一个用户操作引起的等待事件,当用户发出每次I/O需要读取多个数据块这样的SQL 操作时,会产生这个等待事件,最常见的两种情况是全表扫描(FTS: Full Table Scan)和索引快速扫描(IFFS: index fast full scan)。
   这个名称中的scattered( 发散),可能会导致很多人认为它是以scattered 的方式来读取数据块的,其实恰恰相反,当发生这种等待事件时,SQL的操作都是顺序地读取数据块的,比如FTS或者IFFS方式(如果忽略需要读取的数据块已经存在内存中的情况)。
   这里的scattered指的是读取的数据块在内存中的存放方式,他们被读取到内存中后,是以分散的方式存在在内存中,而不是连续的。

 

 

Db file sequential read

 

   这个等待事件在实际生产库也很常见,当Oracle 需要每次I/O只读取单个数据块这样的操作时,会产生这个等待事件。 最常见的情况有索引的访问(除IFFS外的方式),回滚操作,以ROWID的方式访问表中的数据,重建控制文件,对文件头做DUMP等。
   这里的sequential也并非指的是Oracle 按顺序的方式来访问数据,和db file scattered read一样,它指的是读取的数据块在内存中是以连续的方式存放的。

 

Db file single write

 

   这个等待事件通常只发生在一种情况下,就是Oracle 更新数据文件头信息时(比如发生Checkpoint)。

   当这个等待事件很明显时,需要考虑是不是数据库中的数据文件数量太大,导致Oracle 需要花较长的时间来做所有文件头的更新操作(checkpoint)。


 

Direct path read

 

   这个等待事件发生在会话将数据块直接读取到PGA当中而不是SGA中的情况,这些被读取的数据通常是这个会话私有的数据,所以不需要放到SGA作为共享数据,因为这样做没有意义。这些数据通常是来自与临时段上的数据,比如一个会话中SQL的排序数据,并行执行过程中间产生的数据,以及Hash Join,merge join产生的排序数据,因为这些数据只对当前的会话的SQL操作有意义,所以不需要放到SGA当中。

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


Direct path write

 

   这个等待事件和direct path read 正好相反,是会话将一些数据从PGA中直接写入到磁盘文件上,而不经过SGA。

   这种情况通常发生在:

     使用临时表空间排序(内存不足)

     数据的直接加载(使用append方式加载数据)

     并行DML操作。


 

Enqueue

 

   Enqueue 这个词其实是lock 的另一种描述语。
   当我们在AWR 报告中发现长时间的enqueue 等待事件时,说明数据库中出现了阻塞和等待,可以关联AWR报告中的enqueue activity部分来确定是哪一种锁定出现了长时间等待。

 

 

Free buffer waits

 

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


 

global cache cr request


当一个进程访问需要一个或者多个块时,Oracle会首先检查自己的Cache是否存在该块,如果发现没有,就会先通过global cache赋予这些块共享访问的权限,然后再访问。假如,通过global cache发现这些块已经在另一个实例的Cache里面,那么这些块就会通过Cache Fusion,在节点之间直接传递,同时出现global cache crrequest等待事件。

     在10G中,global cachecr request已经简称为gc crrequest。

    从remote cache运输块到本地cache花费的时间还得看这些块是共享还是独占模式,如果块是共享(scur)的,Remote Cache就克隆信息传送过来,否则就要产生一个PI,然后再传送过去。显然,global cache cr request等待事件和db file sequential/scatteredread 等待事件有着直接的关系。

     通常,RAC中的进程会等待1s去尝试从本地或者远程Cache读取数据块信息,当然,这还得依靠块处于什么样的模式。如果超过了1s,那就表明节点之间连接慢,这个时候节点之间就使用private连接,而客户端的连接使用public,有时候,节点之间的连接, Cache Fusion就不会通过公共网络,在这种情况下,就会有大量的global cachecr request等待事件出现。

     通常,大量的global cache cr request主要有以下几个原因。

   (1)节点之间内部连接慢或者节点之间传输带宽窄。这个可以通过重新连接获取高速连接。

   (2)存在热点数据块的竞争。

   (3)CPU负载过高或者LMS后台进程不够。正常情况下,只有两个LMS后台进程从CPU那里获取资源,增加LMS进程的数量或者提高它的优先权能 够帮助从CPU那里获取更多的资源。隐藏参数_lm_lms是设置LMS进程数量的。

   (4)大量未提交的事务或者系统磁盘设备传输慢。


     http://blog.csdn.net/tianlesoftware/article/details/7777511 


Latch free

 

   在10g之前的版本里,latch free 等待事件代表了所有的latch等待,在10g以后,一些常用的latch事件已经被独立了出来:

   SQL> select name from v$event_name where name like 'latch%' order by 1;

   NAME
  
   ----------------------------------------------------------------
  
   latch activity
  
   latch free
  
   latch: Change Notification Hash table latch
  
   latch: In memory undo latch
  
   latch: MQL Tracking Latch
  
   latch: PX hash array latch
  
   latch: Undo Hint Latch
  
   latch: WCR: processes HT
  
   latch: WCR: sync
  
   latch: cache buffer handles
  
   latch: cache buffers chains
  
   latch: cache buffers lru chain
  
   latch: call allocation
  
   latch: change notification client cache latch
  
   latch: checkpoint queue latch
  
   latch: enqueue hash chains
  
   latch: gc element
  
   latch: gcs resource hash
  
   latch: ges resource hash list
  
   latch: lob segment dispenser latch
  
   latch: lob segment hash table latch
  
   latch: lob segment query latch
  
   latch: messages
  
   latch: object queue header operation
  
   latch: parallel query alloc buffer
  
   latch: redo allocation
  
   latch: redo copy
  
   latch: redo writing
  
   latch: row cache objects
  
   latch: session allocation
  
   latch: shared pool
  
   latch: undo global data
  
   latch: virtual circuit queues
  

   所以latch free 等待事件在10g以后的版本中并不常见,而是以具体的Latch 等待事件出现。

 


 

Library cache lock

  

   这个等待时间发生在不同用户在共享中由于并发操作同一个数据库对象导致的资源争用的时候,比如当一个用户正在对一个表做DDL 操作时,其他的用户如果要访问这张表,就会发生library cache lock等待事件,它要一直等到DDL操作完成后,才能继续操作。

 

Library cache pin

 

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


Log file parallel write

 

   后台进程LGWR 负责将log buffer当中的数据写到REDO 文件中,以重用log buffer的数据。 如果每个REDO LOG组里面有2个以上的成员,那么LGWR进程会并行地将REDO 信息写入这些文件中。 

   如果数据库中出现这个等待事件的瓶颈,主要的原因可能是磁盘I/O性能不够或者REDO 文件的分布导致了I/O争用,比如同一个组的REDO 成员文件放在相同的磁盘上。

 

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性能


Log file sequential read

 

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


Log file single write

 

     这个等待事件发生在更新redo log文件的文件头时,当为日志组增加新的日志成员时或者redo log的sequence号改变时,LGWR 都会更新redo log文件头信息。

 

Log file switch(archiving needed)

 

   在归档模式下,这个等待事件发生在在线日志切换(log file switch)时,需要切换的在线日志还没有被归档进程(ARCH)归档完毕的时候。 当在线日志文件切换到下一个日志时,需要确保下一个日志文件已经被归档进程归档完毕,否则不允许覆盖那个在线日志信息(否则会导致归档日志信息不完整)。

   出现这样的等待事件通常是由于某种原因导致ARCH 进程死掉,比如ARCH进程尝试向目的地写入一个归档文件,但是没有成功(介质失效或者其他原因),这时ARCH进程就会死掉。如果发生这种情况,在数据库的alert log文件中可以找到相关的错误信息。


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)等待事件,原因可能是日志文件太小或者日志组太少,所以解决的方法是,增加日志文件的大小或者增加日志组的数量。

 

Log file switch (private strand flush incomplete)

 

   

   和log file switch (Checkpoint incomplete)等待事件一样。
   
   产生的原因:
   current表示当前的联机日志正在被使用;
   active是活动的,但非当前正在使用的联机日志,可能已经归档也可能没有被归档。
   active状态表示:该组联机日志文件中的检查点尚未完成,如果日志文件循环使用再次达到该文件时,数据库就会处于等待的停顿状态,
   
   其实,正是日志文件在等待DBWR完成检查点触发的写操作完成。
   当日志组都处于CURRENT和ACTIVE状态时,就会发生该等待
   
   解决方法:
   1、适当增加日志组数
   2、适当增加日志文件大小
   3、增加DBWn 进程数



Log file sync

 

   这是一个用户会话行为导致的等待事件,当一个会话发出一个commit命令时,LGWR进程会将这个事务产生的redo log从log buffer里面写到磁盘上,以确保用户提交的信息被安全地记录到数据库中。
   会话发出的commit指令后,需要等待LGWR将这个事务产生的redo 成功写入到磁盘之后,才可以继续进行后续的操作,这个等待事件就叫作log file sync。
   当系统中出现大量的log file sync等待事件时,应该检查数据库中是否有用户在做频繁的提交操作。
   这种等待事件通常发生在OLTP系统上。 OLTP 系统中存在很多小的事务,如果这些事务频繁被提交,可能引起大量的log file sync的等待事件。


 

Row cache lock


   ROW CACHE LOCK等待事件是一个共享池相关的等待事件。是由于对于字典缓冲的访问造成的。
   P1 – Cache Id
   P2 – Mode Held
   P3 – Mode Requested


   mode 和REQUEST的取值:
   KQRMNULL 0 null mode – not locked
   KQRMS 3 share mode
   KQRMX 5 exclusive mode
   KQRMFAIL 10 fail to acquire instance lock


   如果是RAC/OPS环境,前台进程发出锁请求,LCK0进程发出锁请求。如果是单实例模式,由前台进程直接发出锁请求。
   在RAC/OPS环境下,前台进程会循环等待锁的获取,最多会等待60秒钟。在单实例环境,前台进程会循环1000次,等待3秒钟。PMON进程无论在哪种模式,都会等待5秒钟。
   要注意的是单实例模式下和多实例模式下申请该锁调用的模块是不同的(kqrget()- 单实例,kqgigt()- 多实例)。
   如果发现这个等待十分高,一般来说可能由于2种原因,一是共享池太小了,需要增加共享池,另外一种情况是SQL分析过于频繁,对于共享池的并发访问量过大。

   对于任何一种情况,绝大多数情况下加大共享池会有助于降低该等待,不过加大共享池的时候也要注意,并不一定所有的情况下增加共享池都会有明显的效果,特别是对于第二种情况,精确的分析十分重要。另外进一步分析,弄清楚哪些ROW CACHE的等待最为严重,有助于解决问题。


   http://www.xifenfei.com/3195.html



SQL*Netbreak/reset to client

 

   当出现这个等待事件时,说明服务器端在给客户端发送一个断开连接或者重置连接的请求,正在等待客户的响应,通常的原因是服务器到客户端的网络不稳定导致的。


 

SQL*Netbreak/reset to dblink

 

   这个等待事件和SQL*Net break/reset to client 相同。 不过它表示的是数据库通过dblink访问另一台数据库时,他们之间建立起一个会话,这个等待事件发生在这个会话之间的通信过程中,同样如果出现这个等待事件,需要检查两台数据库之间的通信问题。

 

SQL*Netmessage from client

 

   这个等待事件基本上是最常见的一个等待事件。 当一个会话建立成功后,客户端会向服务器端发送请求,服务器端处理完客户端请求后,将结果返回给客户端,并继续等待客户端的请求,这时候会产生SQL*Net message from client 等待事件。

   很显然,这是一个空闲等待,如果客户端不再向服务器端发送请求,服务器端将一直处于这个等待事件状态。


SQL*Net message from dblink

 

   这个等待事件和SQL*Net message from client相同,不过它表示的是数据库通过dblink 访问另一个数据库时,他们之间会建立一个会话,这个等待事件发生在这个会话之间的通信过程中。

   这个等待事件也是一个空闲等待事件。

 

SQL*Net message to client

 

   这个等待事件发生在服务器端向客户端发送消息的时候。 当服务器端向客户端发送消息产生等待时,可能的原因是用户端太繁忙,无法及时接收服务器端送来的消息,也可能是网络问题导致消息无法从服务器端发送到客户端。

 

SQL*Net message to dblink

 

   这个等待事件和SQL*Net message to client 相同,不过是发生在数据库服务器和服务器之间的等待事件,产生这个等待的原因可能是远程服务器繁忙,而无法及时接收发送过来的消息,也可能是服务器之间网络问题导致消息无法发送过来。

 

SQL*Net more data from client

 

   服务器端等待用户发出更多的数据以便完成操作,比如一个大的SQL文本,导致一个SQL*Net 数据包无法完成传输,这样服务器端会等待客户端把整个SQL 文本发过来在做处理,这时候就会产生一个SQL*Net more data from client 等待事件。


SQL*Net more data from dblink

 

   在一个分布式事务中,SQL 分布在不同的数据库中执行,远程数据库执行完毕后将结果通过dblink返给发出SQL的数据库,在等待数据从其他数据库中通过dblink传回的过程中,如果数据在远程数据库上处理时间很久,或者有大量的结果集需要返回,或者网络性能问题都会产生SQL*Net more data from dblink 等待事件,它的意思是本地数据库需要等到所有的数据从远程处理完毕通过dblink传回后,才可以在本机继续执行操作。


 

SQL*Net more data to client

 

   当服务器端有太多的数据需要发给客户端时,可能会产生SQL*Net more data to client等待事件,也可能由于网络问题导致服务器无法及时地将信息或者处理结果发送给客户端,同样会产生这个等待。

 

SQL*Net more data to dblink

 

   这个等待事件和SQL*Net more data to client 等待时间基本相同,只不过等待发生在分布式事务中,即本地数据库需要将更多的数据通过dblink发送给远程数据库。由于发送的数据太多或者网络性能问题,就会出现SQL*Net more data to dblink等待事件。

 

Write complete waits


    write complete watis 等待与buffer busy waits 等待相同,可以通过buffer lock争用引起的等待进行分类。DBWR将脏缓冲区记录到磁盘上的期间,对缓冲区以exclusive模式占有buffer lock,这时,读取或修改缓冲区的其他进程就需要等待此项工作结束,这时等待write complete waits事件。
    出现write complete waits 等待的主要原因就是DBWR进程的性能问题,也就是会所dbwr将脏缓冲区的数据写入磁盘的时间过长。       其原因大致分为如下两类:
    1)I/O系统性能缓慢:如果在DBWR上显示的db file parallel write等待时间较长,可以判断存在i/o系统问题。在dbwr上,db file parallel write等待时间变长,则服务器进程连续经历free buffer waits等待或者write complete waits等待。我们知道,组合使用裸设备和AIO(asynchronous IO 异步io) 是改善io性能的最好方法。使用aio(异步io)时,一般认为增加dbwr数量没有意义。因为使用多个dbwr的最红目的是以软件的方式实现aio。但若是写入繁忙的系统,可以同时使用aio和多个dbwr。
    2)dbwr的工作量过多:一般情况 过小的FAST_START_MTTR_TARGET值,频繁的增量检查点,重做日志文件过小(频繁日志切换,导致检查点频繁发生),parallel query 引发direct path read时,还有truncate ,drop, hot backup时发生检查点。。。虽然这些时候io性能没有问题,但是还是因为大量的dbwr工作,还会出现write complete waits。


    http://www.zhouyinghou.com/archives/832

     http://www.linuxidc.com/Linux/2012-09/70657p2.htm





你可能感兴趣的:(Oracle,等待事件)