1. CPU time
CPU time其实不是真正的等待事件。是衡量CPU是否瓶颈的一个重要指标。一般来讲,一个良好的系统,CPU TIME 应该排在TOP 5 TIME Event的最前面。 当然这也是相对的, 如果不存在显著的 latch wait 或过高的logical read 等, CPU time 占的比例高才是令人放心的。 也就是说CPU在高效率干活是好事,但是是否因为低效的设置或SQL而消耗CPU时间就需要注意了。
- NUM_CPU_SOCKETS 物理CPU的数目
- NUM_CPU_CORES CPU的核数
- NUM_CPUS 逻辑CPU的数目
2. Buffer busy waits (buffer busy wait / read by other session)
一个SESSION需要访问BUFFER CACHE中的一个数据库块而又不能访问时发生的一种latch等待(Buffer Cache的Latch竞争)。缓冲区“busy”的两个原因是:
- 另一个SESSION正在将数据块读进BUFFER。--- read by other session 等待,一般来说本质上还是buffer cache过小或低效的SQL造成的;
- 另一个SESSION正在以排它模式占用着这块被请求的BUFFER。---常见原因是数据库中存在热块,一般来说无法通过提高硬件配置解决,可以在“Segments by Buffer Busy Waits”一节中找出发生这种等待的SEGMENT,然后通过使用reverse-key indexes并对热表进行分区而减少这种等待事件,也可以尝试考虑降低数据密度,修改表设计或者业务逻辑,让修改分散,提高并发性。
Latch是用来保护SGA中的内存结构。Latch保证对共享数据结构的排它性访问,以此来保证内存结构的完整性不受到损坏。在多个会话同时修改或者检视(inspect)SGA中同一个内存结构时,必须串行化访问以保证SGA中数据结构的完整性。 对数据库中对象的保护,使用的lock而不是latch。Buffer Cache的Latch竞争经常是由于热点块竞争或低效的SQL语句引起; Shared Pool的Latch竞争通常是由于SQL的硬解析引起。
3. SQL*Net message from client 等等
这个等待事件基本上是最常见的一个等待事件。 当一个会话建立成功后,客户端会向服务器端发送请求,服务器端处理完客户端请求后,将结果返回给客户端,并继续等待客户端的请求,这时候会产生SQL*Net message from client 等待事件。
很显然,这是一个空闲等待,如果客户端不再向服务器端发送请求,服务器端将一直处于这个等待事件状态。
4. Db file sequential read / Db file scattered read
- 一般在等待事件中排在4、5位,Avg wait time平均单次等待时间应当小于20ms.
- db file sequential read 如果数据库执行索引查找(index block access or table block access by a rowid),一般都是一个一个数据块读取的,读取的数据块在内存中是以连续的方式存放。db file sequential read 等待事件的P3参数一般都是1。
- db file scattered read 如果数据库执行全表扫描或者是全索引扫描, 一般都是同时读取多个块到内存中(Multi block I/O) ,为了性能和更有效的内存空间利用,oracle一般会把这些块分散在内存中。db file scattered read 等待事件的P3参数指出了每次I/O读取的块数。每次I/O读取多少个块,有参数db_file_multiblock_read_count控制。一般会从应用程序(SQL) 方面入手调整。
5. enq: TX - row lock contention
等待事件enq: TX - row lock contention中的enq是enquence的简写。enquence是协调访问数据库资源的内部锁。所有以“enq:”打头的等待事件都表示这个会话正在等待另一个会话持有的内部锁释放。
它的名称格式是enq:enqueue_type - related_details。这里的enqueue_type是TX,related_details是row lock contention。数据库动态性能视图v¥event_name提供所有以“enq:”开头的等待事件的列表。
虽然在awrrpt中看到大量enq: TX - row lock contention的等待,但这些是事后看到的信息。根据AWRRPT,我们无法只知道该等待事件的请求模式是什么,是6还是4。
如果数据库一出现enq: TX - row lock contention等待,可以去看v¥session和v¥session_wait等性能视图。
enq: TX - row lock contention 的产生有几种情况。
<1>In mode 6 :A 会话持有row level lock,B会话等待这个lock释放。
不同的session更新或删除同一个记录。(This occurs when one application is updating or deleting a row that another session is also trying to update or delete. )
解决办法:持有锁的会话commit或者rollback。
<2>In mode 4 : 唯一索引
表上存在唯一索引,A会话插入一个值(未提交),B会话随后也插入同样的值;A会话提交后,enq: TX - row lock contention消失。
解决办法:持有锁的会话commit或者rollback。
<3>in mode 4 : bitmap
源于bitmap的特性:位图索引的一个键值,会指向多行记录,所以更新一行就会把该键值指向的所有行锁定。
解决办法:commit或者rollback。
<4>其他原因
It could be a primary key problem; a trigger firing attempting to insert, delete, or update a row; a problem with initrans; waiting for an index split to complete; problems with bitmap indexes;updating a row already updated by another session; or something else.
6. Log file sync
这是一个用户会话行为导致的等待事件,会话发出的commit指令后,需要等待LGWR将这个事务产生的redo成功写入到磁盘之后,才可以继续进行后续的操作,这个等待事件就叫作log file sync。
如果此类事件频繁发生,可以判断为:
- commit 次数是否过多
- I/O 系统问题
- 重做日志是否不必要被创建
- redo log buffer 是否过大
7. Log file switch(archiving needed / checkpoint incomplete)
在归档模式下,这个等待事件发生在在线日志切换(log file switch)时,需要切换的在线日志还没有被归档进程(ARCH)归档完毕的时候。 当在线日志文件切换到下一个日志时,需要确保下一个日志文件已经被归档进程归档完毕,否则不允许覆盖那个在线日志信息(否则会导致归档日志信息不完整)。出现这样的等待事件通常是由于某种原因导致ARCH 进程死掉,比如ARCH进程尝试向目的地写入一个归档文件,但是没有成功(介质失效或者其他原因),这时ARCH进程就会死掉。 如果发生这种情况,在数据库的alert log文件中可以找到相关的错误信息。
当一个在线日志切换到下一个在线日志时,必须保证要切换到的在线日志上的信息(比如一些脏数据块产生的redo log)被写到磁盘上(checkpoint),这样做的原因是,如果一个在线日志文件的信息被覆盖,而依赖这些redo 信息做恢复的数据块尚未被写到磁盘上(checkpoint),此时系统down掉的话,Oracle将没有办法进行实例恢复。
如果系统中出现大量的log file switch(checkpoint incomplete)等待事件,原因可能是日志文件太小或者日志组太少,所以解决的方法是,增加日志文件的大小或者增加日志组的数量。
8. Library cache lock / Library cache pin
这类等待事件发生在不同用户由于并发操作同一个数据库对象导致资源争用的时候,比如当一个用户正在对一个表做DDL 操作时,其他的用户如果要访问这张表,就会发生library cache lock等待事件,它要一直等到DDL操作完成后,才能继续操作。
Library cache pin 和 Library cache lock 一样是发生在共享池中并发操作引起的事件。通常来讲,如果Oracle 要对一些PL/SQL 或者视图这样的对象做重新编译,需要将这些对象pin到共享池中。 如果此时这个对象被其他的用户特有,就会产生一个library cache pin的等待。
9. Direct path read / Direct path write
这类等待事件发生在会话将数据块直接读取到PGA当中而不是SGA中的情况,这些被读取的数据通常是这个会话私有的数据,所以不需要放到SGA作为共享数据,因为这样做没有意义。 这些数据通常是来自于临时段上的数据,比如一个会话中SQL的排序数据,并行执行过程中间产生的数据,以及Hash Join,merge join产生的排序数据,因为这些数据只对当前的会话的SQL操作有意义,所以不需要放到SGA当中。
当发生direct path read等待事件时,意味着磁盘上有大量的临时数据产生,比如排序,并行执行等操作。 或者意味着PGA中空闲空间不足。
与direct path read 正好相反,Direct path write是会话将一些数据从PGA中直接写入到磁盘文件上,而不经过SGA。这种情况通常发生在:
使用临时表空间排序(内存不足)
数据的直接加载(使用append方式加载数据)
并行DML操作。