一、等待事件的相关知识
1、等待事件分类
等待事件主要可以分为两类,即空闲(IDLE)等待事件和非空闲(NON-IDLE)等待事件。
1).空闲等待事件指ORACLE正等待某种工作,在诊断和优化数据库的时候,不用过多注意这部分事件。
2).非空闲等待事件专门针对ORACLE的活动,指数据库任务或应用运行过程中发生的等待,这些等待事件 是在调整数据库的时候需要关注与研究的。
在Oracle 10g中的等待事件有872个,11g中等待事件1116个。可以通过v$event_name 视图来查看等待事件的相关信息。
2、查看v$event_name视图的字段结构
SQL> desc v$event_name; 名称 是否为空? 类型 ----------------------------------------- -------- --------------- EVENT# NUMBER EVENT_ID NUMBER NAME VARCHAR2(64) PARAMETER1 VARCHAR2(64) PARAMETER2 VARCHAR2(64) PARAMETER3 VARCHAR2(64) WAIT_CLASS_ID NUMBER WAIT_CLASS# NUMBER WAIT_CLASS VARCHAR2(64) |
3、查看等待事件总数
11gr2: SQL> select count(*) from v$event_name; COUNT(*) ---------- 1116 |
10gr2 rac: sys@ORCL> select count(*) from v$event_name; COUNT(*) ---------- 889 |
10gr2: SQL> select count(*) from v$event_name; COUNT(*) ---------- 874 |
4、查看等待事件分类情况
/* Formatted on 6/27/2011 12:54:45 PM (QP5 v5.114.809.3010) */ SELECT wait_class#, wait_class_id, wait_class, COUNT ( * ) AS "count" FROM v$event_name GROUP BY wait_class#, wait_class_id, wait_class ORDER BY wait_class#; WAIT_CLASS# WAIT_CLASS_ID WAIT_CLASS count ----------- ------------- -------------------- ---------- 0 1893977003 Other 717 1 4217450380 Application 17 2 3290255840 Configuration 24 3 4166625743 Administrative 54 4 3875070507 Concurrency 32 5 3386400367 Commit 2 6 2723168908 Idle 94 7 2000153315 Network 35 8 1740759767 User I/O 45 9 4108307767 System I/O 30 10 2396326234 Scheduler 7 11 3871361733 Cluster 50 12 644977587 Queueing 9 |
5、相关的几个视图
V$SESSION |
代表数据库活动的开始,视为源起 |
V$SESSION_WAIT |
视图用以实时记录活动SESSION的等待情况,是当前信息 |
V$SESSION_WAIT_HISTORY |
是对V$SESSION_WAIT的简单增强,记录活动SESSION的最近10次等待 |
V$SQLTEXT |
当数据库出现瓶颈时,通常可以从V$SESSION_WAIT找到那些正在等待资源的SESSION,通过SESSION的SID,联合V$SESSION和V$SQLTEXT视图就可以捕获这些SESSION正在执行的SQL语句 |
V$ACTIVE_SESSION_HISTORY |
是ASH的核心,用以记录活动SESSION的历史等待信息,每秒采样一次,这部分内容记录在内存中,期望值是记录一个小时的内容 |
WRH#_ACTIVE_SESSION_HISTORY |
是V$ACTIVE_SESSION_HISTORY在AWR的存储地。 V$ACTIVE_SESSION_HISTORY中 的信息会被定期(每小时一次)的刷新到负载库中,并缺省保留一个星期用于分析。 |
DBA_HIST_ACTIVE_SESS_HISTORY |
视图是WRH#_ACTIVE_SESSION_HISTORY视图和其他几个视图的联合展现,通常通过这个视图进行历史数据的访问 |
V$SYSTEM_EVENT |
由于V$SESSION记录的是动态信息,和SESSION的生命周期相关,而并不记录历史信息,所以ORACLE提供视图V$SYSTEM_EVENT来记录数据库自启动以来所有等待事件的汇总信息。通过这个视图,用户可以迅速获得数据库运行的总体概况。 |
6、等待事件相关查询
查询数据库等待时间和实际执行时间的相对百分比 select * from v$sysmetric a where a.METRIC_NAME in ('Database CPU Time Ratio', 'Database Wait Time Ratio') and a.INTSIZE_CSEC = (select max(intsize_csec) from v$sysmetric); |
查询数据库中过去30分钟引起最多等待的sql语句 select ash.USER_ID, u.username, sum(ash.WAIT_TIME) ttl_wait_time, s.SQL_TEXT from v$active_session_history ash, v$sqlarea s, dba_users u where ash.SAMPLE_TIME between sysdate - 60 / 2880 and sysdate and ash.SQL_ID = s.SQL_ID and ash.USER_ID = u.user_id group by ash.USER_ID, s.SQL_TEXT, u.username order by ttl_wait_time desc |
查询数据库中的等待事件 select event, count(*) from v$session_wait group by event order by count(*) desc |
查询数据库过去15分钟最重要的等待事件 select ash.EVENT, sum(ash.WAIT_TIME + ash.TIME_WAITED) total_wait_time from v$active_session_history ash where ash.SAMPLE_TIME between sysdate - 30 / 2880 and sysdate group by event order by total_wait_time desc |
在过去15分钟哪些用户经历了等待 select s.SID, s.USERNAME, sum(ash.WAIT_TIME + ash.TIME_WAITED) total_wait_time from v$active_session_history ash, v$session s where ash.SAMPLE_TIME between sysdate - 30 / 2880 and sysdate and ash.SESSION_ID = s.SID group by s.SID, s.USERNAME order by total_wait_time desc; |
查询等待时间最长的对象 select a.CURRENT_OBJ#, d.object_name, d.object_type, a.EVENT, sum(a.WAIT_TIME + a.TIME_WAITED) total_wait_time from v$active_session_history a, dba_objects d where a.SAMPLE_TIME between sysdate - 30 / 2880 and sysdate and a.CURRENT_OBJ# = d.object_id group by a.CURRENT_OBJ#, d.object_name, d.object_type, a.EVENT order by total_wait_time desc; |
查询过去15分钟等待时间最长的sql语句 select a.USER_ID, u.username, s.SQL_TEXT, sum(a.WAIT_TIME + a.TIME_WAITED) total_wait_time from v$active_session_history a, v$sqlarea s, dba_users u where a.SAMPLE_TIME between sysdate - 30 / 2880 and sysdate and a.SQL_ID = s.SQL_ID and a.USER_ID = u.user_id group by a.USER_ID, s.SQL_TEXT, u.username order by total_wait_time desc; |
那些SQL消耗更多的IO select * from (select s.PARSING_SCHEMA_NAME, s.DIRECT_WRITES, substr(s.SQL_TEXT, 1, 500), s.DISK_READS from v$sql s order by s.DISK_READS desc) where rownum < 20 |
查看哪些会话正在等待IO资源 SELECT username, program, machine, sql_id FROM V$SESSION WHERE EVENT LIKE 'db file%read'; |
查看正在等待IO资源的对象 SELECT d.object_name, d.object_type, d.owner FROM V$SESSION s, dba_objects d WHERE EVENT LIKE 'db file%read' and s.ROW_WAIT_OBJ# = d.object_id |
查看redo日志切换频率 Select round(FIRST_TIME, 'DD'), THREAD#, Count(SEQUENCE#) From v$log_history Group By round(FIRST_TIME, 'DD'), THREAD# Order By 1, 2 SELECT trunc(first_time) "Date", to_char(first_time, 'Dy') "Day", count(1) "Total", SUM(decode(to_char(first_time, 'hh24'),'00',1,0)) "h0", |
二、常见的等待事件
1、Buffer busy waits
从本质上讲,这个等待事件的产生仅说明了一个会话在等待一个Buffer(数据块),但是导致这个现象的原因却有很多种。常见的两种是:
- 当一个会话视图修改一个数据块,但这个数据块正在被另一个会话修改时。
- 当一个会话需要读取一个数据块,但这个数据块正在被另一个会话读取到内存中时。
在新的版本中,第二种情况已经被独立出来,以read by other session取代。
Oracle操作的最小单位是块(Block),即使你要修改一条记录,也需要对这条记录所在的这个数据块做操作。当你对这个数据块做修改时,其他的会话将被阻止对这个数据块上的数据做修改(即使其他用户修改的不是当前用户修改的数据),但是可以以一致性的方式读取这个数据块(from undo)。当前的用户修改完这个数据块后,将会立即释放掉加在这个数据块上的排他锁,这样另一个会话就可以继续修改它。修改操作是一个非常短暂的时间,这种加锁的机制我们叫Latch。
当一个会话修改一个数据块时,是按照以下步骤来完成的:
- 以排他的方式获得这个数据块(Latch)
- 修改这个数据块。
- 释放Latch。
Buffer busy waits等待事件常见于数据库中存在的热快的时候,当多个用户频繁地读取或者修改同样的数据块时,这个等待事件就会产生。 如果等待的时间很长,我们在AWR或者statspack 报告中就可以看到。
这个等待事件有三个参数。 查看有几个参数我们可以用以下SQL:
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: 等待访问的数据块号。 ID: 在10g之前,这个值表示一个等待时间的原因,10g之后则表示等待事件的类别。 |
2、Buffer latch
内存中数据块的存放位置是记录在一个hash列表(cache buffer chains)当中的。 当一个会话需要访问某个数据块时,它首先要搜索这个hash 列表,从列表中获得数据块的地址,然后通过这个地址去访问需要的数据块,这个列表Oracle会使用一个latch来保护它的完整性。 当一个会话需要访问这个列表时,需要获取一个Latch,只有这样,才能保证这个列表在这个会话的浏览当中不会发生变化。
产生buffer chains太长,我们可以使用多个buffer pool的方式来创建更多的buffer chains,或者使用参数DB_BLOCK_LRU_LATCHES来增加latch的数量,以便于更多的会话可以获得latch,这两种方法可以同时使用。
产生buffer latch的等待事件的主要原因是:
- Buffer chains太长,导致会话搜索这个列表花费的时间太长,使其他的会话处于等待状态。
- 同样的数据块被频繁访问,就是我们通常说的热快问题。
这个等待事件有两个参数:
Latch addr: 会话申请的latch在SGA中的虚拟地址,通过以下的SQL语句可以根据这个地址找到它对应的Latch名称。
select * from v$latch a, v$latchname b where addr= latch addr -- 这里的latch addr 是你从等待事件中看到的值 and a.latch#=b.latch#; |
chain#: buffer chains hash列表中的索引值,当这个参数的值等于s0xfffffff时,说明当前的会话正在等待一个LRU latch。
3、Control file parallel write
当数据库中有多个控制文件的拷贝时,Oracle 需要保证信息同步地写到各个控制文件当中,这是一个并行的物理操作过程,因为称为控制文件并行写,当发生这样的操作时,就会产生control file parallel write等待事件。
控制文件频繁写入的原因很多,比如:
- 日志切换太过频繁,导致控制文件信息相应地需要频繁更新。
- 系统I/O 出现瓶颈,导致所有I/O出现等待。
当系统出现日志切换过于频繁的情形时,可以考虑适当地增大日志文件的大小来降低日志切换频率。
当系统出现大量的control file parallel write等待事件时,可以通过比如降低控制文件的拷贝数量,将控制文件的拷贝存放在不同的物理磁盘上的方式来缓解I/O争用。
这个等待事件包含三个参数:
- Files: Oracle 要写入的控制文件个数。
- Blocks: 写入控制文件的数据块数目。
- Requests:写入控制请求的I/O 次数。
4、Control file sequential read
当数据库需要读取控制文件上的信息时,会出现这个等待事件,因为控制文件的信息是顺序写的,所以读取的时候也是顺序的,因此称为控制文件顺序读,它经常发生在以下情况:
- 备份控制文件
- RAC 环境下不同实例之间控制文件的信息共享
- 读取控制文件的文件头信息
- 读取控制文件其他信息
这个等待事件有三个参数:
- File#:要读取信息的控制文件的文件号。
- Block#: 读取控制文件信息的起始数据块号。
- Blocks:需要读取的控制文件数据块数目。
5、Db file parallel read
这是一个很容易引起误导的等待事件,实际上这个等待事件和并行操作(比如并行查询,并行DML)没有关系。这个事件发生在数据库恢复的时候,当有一些数据块需要恢复的时候,Oracle会以并行的方式把他们从数据文件中读入到内存中进行恢复操作。
这个等待事件包含三个参数:
- Files: 操作需要读取的文件个数。
- Blocks: 操作需要读取的数据块个数。
- Requests:操作需要执行的I/O次数。
6、Db file parallel write
这是一个后台等待事件,它同样和用户的并行操作没有关系,它是由后台进程DBWR产生的,当后台进程DBWR想磁盘上写入脏数据时,会发生这个等待。
DBWR会批量地将脏数据并行地写入到磁盘上相应的数据文件中,在这个批次作业完成之前,DBWR将出现这个等待事件。 如果仅仅是这一个等待事件,对用户的操作并没有太大的影响,当伴随着出现free buffer waits等待事件时,说明此时内存中可用的空间不足,这时候会影响到用户的操作,比如影响到用户将脏数据块读入到内存中。
当出现db file parallel write等待事件时,可以通过启用操作系统的异步I/O的方式来缓解这个等待。 当使用异步I/O时,DBWR不在需要一直等到所有数据块全部写入到磁盘上,它只需要等到这个数据写入到一个百分比之后,就可以继续进行后续的操作。
这个等待事件有两个参数:
- Requests: 操作需要执行的I/O次数
- Timeouts:等待的超时时间。
7、Db file scattered read
这个等待事件在实际生产库中经常可以看到,这是一个用户操作引起的等待事件,当用户发出每次I/O需要读取多个数据块这样的SQL 操作时,会产生这个等待事件,最常见的两种情况是全表扫描(FTS: Full Table Scan)和索引快速扫描(IFFS: index fast full scan)。
这个名称中的scattered(发散),可能会导致很多人认为它是以scattered的方式来读取数据块的,其实恰恰相反,当发生这种等待事件时,SQL的操作都是顺序地读取数据块的,比如FTS或者IFFS方式(如果忽略需要读取的数据块已经存在内存中的情况)。这里的scattered指的是读取的数据块在内存中的存放方式,他们被读取到内存中后,是以分散的方式存在于内存中,而不是连续的。
这个等待事件有三个参数:
- File#: 要读取的数据块所在数据文件的文件号。
- Block#: 要读取的起始数据块号。
- Blocks:需要读取的数据块数目。
8、Db file sequential read
这个等待事件在实际生产库也很常见,当Oracle 需要每次I/O只读取单个数据块这样的操作时,会产生这个等待事件。最常见的情况有索引的访问(除IFFS外的方式),回滚操作,以ROWID的方式访问表中的数据,重建控制文件,对文件头做DUMP等。这里的sequential也并非指的是Oracle按顺序的方式来访问数据,和db file scattered read一样,它指的是读取的数据块在内存中是以连续的方式存放的。
这个等待事件有三个参数:
- File#: 要读取的数据块锁在数据文件的文件号。
- Block#: 要读取的起始数据块号。
- Blocks:要读取的数据块数目(这里应该等于1)。
9、Db file single write
这个等待事件通常只发生在一种情况下,就是Oracle 更新数据文件头信息时(比如发生Checkpoint)。当这个等待事件很明显时,需要考虑是不是数据库中的数据文件数量太大,导致Oracle 需要花较长的时间来做所有文件头的更新操作(checkpoint)。
这个等待事件有三个参数:
- File#: 需要更新的数据块所在的数据文件的文件号。
- Block#:需要更新的数据块号。
- Blocks:需要更新的数据块数目(通常来说应该等于1)。
10、Direct path read
这个等待事件发生在会话将数据块直接读取到PGA当中而不是SGA中的情况,这些被读取的数据通常是这个会话私有的数据,所以不需要放到SGA作为共享数据,因为这样做没有意义。这些数据通常是来自与临时段上的数据,比如一个会话中SQL的排序数据,并行执行过程中间产生的数据,以及Hash Join,merge join产生的排序数据,因为这些数据只对当前的会话的SQL操作有意义,所以不需要放到SGA当中。
当发生direct path read等待事件时,意味着磁盘上有大量的临时数据产生,比如排序,并行执行等操作。或者意味着PGA中空闲空间不足。
这个等待事件有三个参数:
- Descriptor address: 一个指针,指向当前会话正在等待的一个direct read I/O。
- First dba: descriptor address 中最旧的一个I/O数据块地址。
- Block cnt: descriptor address上下文中涉及的有效的buffer 数量。
11、Direct path write
这个等待事件和direct path read 正好相反,是会话将一些数据从PGA中直接写入到磁盘文件上,而不经过SGA。
这种情况通常发生在:
- 使用临时表空间排序(内存不足)
- 数据的直接加载(使用append方式加载数据)
- 并行DML操作。
这个等待事件有三个参数:
- Descriptor address: 一个指针,指向当前会话正在等待的一个direct I/O。
- First dba: descriptor address 中最旧的一个I/O数据块地址。
- Block cnt: descriptor address上下文中涉及的有效的buffer 数量。
12、Enqueue
Enqueue 这个词其实是lock 的另一种描述语。当我们在AWR 报告中发现长时间的enqueue 等待事件时,说明数据库中出现了阻塞和等待,可以关联AWR报告中的enqueue activity部分来确定是哪一种锁定出现了长时间等待。
这个等待事件有2个参数:
- Name: enqueue 的名称和类型。
- Mode: enqueue的模式。
可以使用如下SQL 查看当前会话等待的enqueue名称和类型:
SELECT CHR (TO_CHAR (BITAND (p1, -16777216)) / 16777215) || CHR (TO_CHAR (BITAND (p1, 16711680)) / 65535) "Lock", TO_CHAR (BITAND (p1, 65535)) "Mode" FROM v$session_wait WHERE event = 'enqueue'; |
13、Free buffer waits
当一个会话将数据块从磁盘读到内存中时,它需要到内存中找到空闲的内存空间来存放这些数据块,当内存中没有空闲的空间时,就会产生这个等待;除此之外,还有一种情况就是会话在做一致性读时,需要构造数据块在某个时刻的前映像(image),此时需要申请内存来存放这些新构造的数据块,如果内存中无法找到这样的内存块,也会发生这个等待事件。
当数据库中出现比较严重的free buffer waits等待事件时,可能的原因是:
- data buffer 太小,导致空闲空间不够
- 内存中的脏数据太多,DBWR无法及时将这些脏数据写到磁盘中以释放空间
这个等待事件包含2个参数:
- File#: 需要读取的数据块所在的数据文件的文件号。
- Block#: 需要读取的数据块块号。
查询阻塞的语句:
SELECT /*+ ORDERED USE_HASH(H,R) */ h.sid hold_sid, holds.username h_user, holds.lockwait h_lockwait, holds.status, holds.module h_module, holds.row_wait_obj# h_obj, holds.row_wait_row# h_row, r.sid wait_sid, waits.username w_user, waits.lockwait v_lockwait, waits.status w_status, waits.module w_module, waits.row_wait_obj# w_obj, waits.row_wait_row# w_row, h.type h_type, h.id1 h_id1, h.id2 h_id2, h.lmode h_lmode, h.request h_request, h.ctime h_ctime, h.block h_block, r.type r_type, r.id1 r_id1, r.id2 r_id2, r.lmode r_lmode, r.request r_request, r.ctime r_ctime, r.block r_block, 'alter system kill session ''' || holds.sid || ',' || holds.serial# || '''; --kill 9 ' || nvl(holdp.spid, 'null') killhold, holdsql.sql_text hsql, waitsql.sql_text wsql FROM v$lock h, v$lock r, v$session holds, v$session waits, v$process holdp, v$sqlarea holdsql, v$sqlarea waitsql WHERE h.block = 1 AND r.block =0 AND h.type 'MR' AND r.type 'MR' AND h.id1 = r.id1 AND h.id2 = r.id2 AND h.sid = holds.sid AND holds.paddr = holdp.addr(+) AND holds.sql_address = holdsql.address(+) AND holds.sql_hash_value = holdsql.hash_value(+) AND waits.sql_address = waitsql.address(+); |
14、Latch free
在10g之前的版本里,latch free 等待事件代表了所有的latch等待,在10g以后,一些常用的latch事件已经被独立了出来:
11gr2: 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 已选择33行。 |
10gr2 rac: 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: KCL gc element parent latch latch: MQL Tracking Latch latch: Undo Hint Latch latch: cache buffer handles latch: cache buffers chains latch: cache buffers lru chain latch: checkpoint queue latch latch: enqueue hash chains latch: gcs resource hash latch: ges resource hash list latch: library cache latch: library cache lock latch: library cache pin latch: messages latch: object queue header heap 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 29 rows selected. |
这个等待事件有三个参数:
- Address: 会话等待的latch地址
- Number: latch号,通过这个号,可以从v$latchname视图中找到这个latch的相关信息。
SQL> select * from v$latchname where latch#=number; |
- Tries: 会话尝试获取Latch 的次数。
15、Library cache lock
这个等待时间发生在不同用户在共享中由于并发操作同一个数据库对象导致的资源争用的时候,比如当一个用户正在对一个表做DDL 操作时,其他的用户如果要访问这张表,就会发生library cache lock等待事件,它要一直等到DDL操作完成后,才能继续操作。
这个等待事件包含四个参数:
- Handle address: 被加载的对象的地址
- Lock address: 锁的地址
- Mode: 被加载对象的数据片段
- Namespace: 被加载对象在v$db_objects_cache视图中的namespace名称。
10gr2 rac: select name from v$event_name where name like 'library%' order by 1; NAME -------------------------------------------------- library cache load lock library cache lock library cache pin library cache revalidation library cache shutdown |
16、Library cache pin
这个等待事件和library cache lock 一样是发生在共享池中并发操作引起的事件。通常来讲,如果Oracle 要对一些PL/SQL 或者视图这样的对象做重新编译,需要将这些对象pin到共享池中。如果此时这个对象被其他的用户特有,就会产生一个library cache pin的等待。
这个等待事件包含四个参数:
- Handle address: 被加载的对象的地址
- Lock address: 锁的地址
- Mode: 被加载对象的数据片段
- Namespace: 被加载对象在v$db_objects_cache视图中的namespace名称。
17、Log file parallel write
后台进程LGWR负责将log buffer当中的数据写到REDO文件中,以重用log buffer的数据。如果每个REDO LOG组里面有2个以上的成员,那么LGWR进程会并行地将REDO信息写入这些文件中。
如果数据库中出现这个等待事件的瓶颈,主要的原因可能是磁盘I/O性能不够或者REDO文件的分布导致了I/O争用,比如同一个组的REDO 成员文件放在相同的磁盘上。
这个等待事件有三个参数:
- Files: 操作需要写入的文件个数
- Blocks: 操作需要写入的数据块个数
- Requests: 操作需要执行的I/O次数
18、Log buffer space
当log buffer中没有可用空间来存放新产生的redo log数据时,就会发生log buffer space等待事件。如果数据库中新产生的redo log的数量大于LGWR写入到磁盘中的redo log数量,必须等待LGWR完成写入磁盘的操作,LGWR必须确保redo log写到磁盘成功之后,才能在redo buffer当中重用这部分信息。
如果数据库中出现大量的log buffer space等待事件,可以考虑如下方法:
- 增加redo buffer的大小。
- 提升磁盘的I/O性能
19、Log file sequential read
这个等待事件通常发生在对redo log信息进行读取时,比如在线redo 的归档操作,ARCH进程需要读取redo log的信息,由于redo log的信息是顺序写入的,所以在读取时也是按照顺序的方式来读取的。
这个等待事件包含三个参数:
- Log#: 发生等待时读取的redo log的sequence号
- Block#: 读取的数据块号
- Blocks: 读取的数据块个数
20、Log file single write
这个等待事件发生在更新redo log文件的文件头时,当为日志组增加新的日志成员时或者redo log的sequence号改变时,LGWR 都会更新redo log文件头信息。
这个等待事件包含三个参数:
- Log#: 写入的redo log组的编号。
- Block#:写入的数据块号。
- Blocks:写入的数据块个数
21、Log file switch(archiving needed)
在归档模式下,这个等待事件发生在在线日志切换(log file switch)时,需要切换的在线日志还没有被归档进程(ARCH)归档完毕的时候。当在线日志文件切换到下一个日志时,需要确保下一个日志文件已经被归档进程归档完毕,否则不允许覆盖那个在线日志信息(否则会导致归档日志信息不完整)。
出现这样的等待事件通常是由于某种原因导致ARCH进程死掉,比如ARCH进程尝试向目的地写入一个归档文件,但是没有成功(介质失效或者其他原因),这时ARCH进程就会死掉。如果发生这种情况,在数据库的alert log文件中可以找到相关的错误信息。
这个等待事件没有参数。
22、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)等待事件,原因可能是日志文件太小或者日志组太少,所以解决的方法是,增加日志文件的大小或者增加日志组的数量。
这个等待事件没有参数。
23、Log file sync
这是一个用户会话行为导致的等待事件,当一个会话发出一个commit命令时,LGWR进程会将这个事务产生的redo log从log buffer里面写到磁盘上,以确保用户提交的信息被安全地记录到数据库中。会话发出的commit指令后,需要等待LGWR将这个事务产生的redo成功写入到磁盘之后,才可以继续进行后续的操作,这个等待事件就叫作log file sync。
以下几种情况,可能产生这个等待:
- 高提交频率
解决方式是简单的消除不必要的提交,事务是工作单元。工作单元应该是全部成功或全部失败。
- 缓慢的I/O子系统
较高的IO吞吐量可以改善log file sync和log file parallel write事件的平均等待时间。频繁的提交会弄乱数据库布局和IO子系统。解决办法是将日志文件放裸设备上或绑定在RAID 0或RAID 0+1中,而不是绑定在RAID 5中。
- 过大的日志缓冲区
过大的日志缓冲区也可能延长log file sync等待。大型的日志缓冲区减少后台写入的数量,允许LGWR变得懒惰,并导致更多的重做条目堆积在日志缓冲区中。同事可以调整参数_LOG_IO_SIZE参数,其默认值是LOG_BUFFER的1/3或者1MB,取两者之中较小的值。换句话说,你可以具有较大的日志缓冲区,但较小的_LOG_IO_SIZE将增加后台写入,从而减少log file sync的等待时间。
- 过小的日志缓冲区
过小的日志缓冲区,还会导致log buffer space等待
- 日志组多少与日志大小不合适
这个等待时间包含一个参数:
- Buffer#: redo buffer中需要被写入到磁盘中的buffer。
24、SQL*Net break/reset to client
当出现这个等待事件时,说明服务器端在给客户端发送一个断开连接或者重置连接的请求,正在等待客户的响应,通常的原因是服务器到客户端的网络不稳定导致的。
这个等待事件包含两个参数:
- Driver id: 服务器和客户端连接使用的协议信息
- Breaks: 零表示服务端向客户端发送一个重置(reset)信息,非零表示服务器端向客户端发送一个断开(break)消息
25、SQL*Net break/reset to dblink
这个等待事件和SQL*Net break/reset to client 相同。不过它表示的是数据库通过dblink访问另一台数据库时,他们之间建立起一个会话,这个等待事件发生在这个会话之间的通信过程中,同样如果出现这个等待事件,需要检查两台数据库之间的通信问题。
这个等待事件包含两个参数:
- Driver id: 服务器和客户端连接使用的协议信息
- Breaks: 零表示服务端向客户端发送一个重置(reset)信息,非零表示服务器端向客户端发送一个断开(break)消息
26、SQL*Net message from client
这个等待事件基本上是最常见的一个等待事件。当一个会话建立成功后,客户端会向服务器端发送请求,服务器端处理完客户端请求后,将结果返回给客户端,并继续等待客户端的请求,这时候会产生SQL*Net message from client 等待事件。很显然,这是一个空闲等待,如果客户端不再向服务器端发送请求,服务器端将一直处于这个等待事件状态。
这个等待事件包含两个参数:
- Driver id: 服务器和客户端连接使用的协议信息
- #bytes: 服务器端接收到的来自客户端的消息的字节数
27、SQL*Net message from dblink
这个等待事件和SQL*Net message from client相同,不过它表示的是数据库通过dblink 访问另一个数据库时,他们之间会建立一个会话,这个等待事件发生在这个会话之间的通信过程中。
这个等待事件也是一个空闲等待事件。
这个等待事件包含两个参数:
- Driver id: 服务器和客户端连接使用的协议信息
- #bytes: 服务器端通过dblink接收到的来自另一个服务器端消息的字节数
28、SQL*Net message to client
这个等待事件发生在服务器端向客户端发送消息的时候。当服务器端向客户端发送消息产生等待时,可能的原因是客户端太繁忙,无法及时接收服务器端送来的消息,也可能是网络问题导致消息无法从服务器端发送到客户端。
这个等待事件有两个参数:
- Driver id: 服务器端和客户端连接使用的协议消息
- #bytes: 服务器端向客户端发送消息的字节数
29、SQL*Net message to dblink
这个等待事件和SQL*Net message to client相同,不过是发生在数据库服务器和服务器之间的等待事件,产生这个等待的原因可能是远程服务器繁忙,而无法及时接收发送过来的消息,也可能是服务器之间网络问题导致消息无法发送过来。
这个等待事件包含两个参数:
- Driver id: 服务器端和客户端连接使用的协议信息
- #bytes: 服务器端通过dblink发送给连一个服务器消息的字节数
30、SQL*Net more data from client
服务器端等待用户发出更多的数据以便完成操作,比如一个大的SQL文本,导致一个SQL*Net 数据包无法完成传输,这样服务器端会等待客户端把整个SQL文本发过来在做处理,这时候就会产生一个SQL*Net more data from client等待事件。
这个等待事件包含两个参数:
- Driver id: 服务器端和客户端连接使用的协议信息
- #bytes: 服务器端从客户端接收到消息的字节数
31. SQL*Net more data from dblink
在一个分布式事务中,SQL 分布在不同的数据库中执行,远程数据库执行完毕后将结果通过dblink返给发出SQL的数据库,在等待数据从其他数据库中通过dblink传回的过程中,如果数据在远程数据库上处理时间很久,或者有大量的结果集需要返回,或者网络性能问题都会产生SQL*Net more data from dblink 等待事件,它的意思是本地数据库需要等到所有的数据从远程处理完毕通过dblink传回后,才可以在本机继续执行操作。
这个等待时间包含两个参数:
- Driver id: 服务器端和客户端连接使用的协议信息。
- #bytes: 服务器端通过dblink发送给另一个服务器消息的字节数。
32. SQL*Net more data to client
当服务器端有太多的数据需要发给客户端时,可能会产生SQL*Net more data to client等待事件,也可能由于网络问题导致服务器无法及时地将信息或者处理结果发送给客户端,同样会产生这个等待。
这个等待时间包含两个参数:
- Driver id: 服务器端和客户端连接使用的协议信息。
- #bytes: 服务器端向客户端发送消息的字节数。
33、SQL*Net more data to dblink
这个等待事件和SQL*Net more data to client 等待时间基本相同,只不过等待发生在分布式事务中,即本地数据库需要将更多的数据通过dblink发送给远程数据库。由于发送的数据太多或者网络性能问题,就会出现SQL*Net more data to dblink等待事件。
这个等待时间包含两个参数:
- Driver id: 服务器端和客户端连接使用的协议信息。
- #bytes: 服务器端通过dblink发送给另一个服务器消息的字节数。
34、Enq - UL Contention
TimesTen Cache user 在 Oracle 数据库内有 Enq - UL Contention 等待事件。
在 Oracle 的 AWR 中观察到以下等待事件:
Top 5 Timed Events
Event |
Waits |
Time(s) |
Avg Wait(ms) |
% Total Call Time |
Wait Class |
enq: UL - contention |
22,352 |
10,840 |
485 |
37.8 |
Application |
或者
Wait Events
- s - second
- cs - centisecond - 100th of a second
- ms - millisecond - 1000th of a second
- us - microsecond - 1000000th of a second
- ordered by wait time desc, waits desc (idle events last)
Event |
Waits |
%Time -outs |
Total Wait Time (s) |
Avg wait (ms) |
Waits /txn |
enq: UL - contention |
22,352 |
97.66 |
10,840 |
485 |
0.04 |
自动刷新 cache groups 会在 Oracle 数据库中产生锁,但是 AWT cache groups 不会。自动刷新线程,也就是把 Oracle 中的更新同步到 TimesTen 中的线程本身不会产生这些锁。而是自动刷新 cache groups 中的其他的进程(比如 garbage collector, marker 等等)产生的锁。
如果这些线程不能获取这些锁的话,则说明持有锁的线程在为所有的自动刷新 cache groups 执行某些任务。自动刷新 cache groups 中的不同线程之间发生锁冲突是可能的,而且是可以忽略的。因为在这种情况下,持有锁的线程在为所有的自动刷新 cache groups 执行某些任务。
注:转载于MOS ( ID 1945307.1)
三、
事件 |
说明 |
例子 |
Event 10013 - Monitor Transaction Recovery |
在Startup时跟踪事务恢复 |
ALTER SESSION SET EVENTS '10013 trace name context forever, level 1'; |
Event 10015 - Dump Undo Segment Headers- |
在事务恢复后做Dump回退段头信息 |
ALTER SESSION SET EVENTS '10015 trace name context forever, level 1'; |
Event 10032 - Dump Sort Statistics |
Dump排序的统计信息 |
ALTER SESSION SET EVENTS '10032 trace name context forever, level 10'; |
Event 10033 - Dump Sort Intermediate Run Statistics |
排序过程中,内存排序区和临时表空间的交互情况 |
ALTER SESSION SET EVENTS '10033 trace name context forever, level 10'; |
Event 10045 - Trace Free List Management Operations |
FREELIST的管理操作 |
ALTER SESSION SET EVENTS '10045 trace name context forever, level 1'; |
Event 10046 - Enable SQL Statement Trace |
跟踪SQL,有执行计划,邦定变量和等待的统计信息,level 12最详细。 |
ALTER SESSION SET EVENTS '10046 trace name context forever, level 12'; LEVEL定义如下: 1:SQL 语句,执行计划和执行状态 4:1的内容加上绑定变量信息 8:1的信息加上等待事件信息 12:1+4+8 |
Event 10053 - Dump Optimizer Decisions |
在分析SQL语句时,Dump出优化器所做的选择,级别level 1最详细 |
ALTER SESSION SET EVENTS '10053 trace name context forever, level 1'; LEVEL定义如下: 1:状态和估算信息 2:只显示估算信息 |
Event 10060 - Dump Predicates |
DUMP SQL语句中的断语信息。需要在需要DUMP的用户下创建以下表 CREATE TABLE kkoipt_table (c1 INTEGER, c2 VARCHAR2(80)); 断语信息会写入该表 |
ALTER SESSION SET EVENTS '10060 trace name context forever, level 1'; |
Event 10065 - Restrict Library Cache Dump Output for State Object Dumps |
限制对象状态DUMP的时候LIBRARY CACHE信息的详细程度 1 Address of library object only 2 As level 1 plus library object lock details 3 As level 2 plus library object handleand library object 缺省是LEVEL 3 |
ALTER SESSION SET EVENTS '10065 trace name context forever, level level'; |
Event 10079 - Dump SQL*Net Statistics- |
Dump SQL*NeT的统计信息 |
ALTER SESSION SET EVENTS '10079 trace name context forever, level 2'; |
Event 10081 - Trace High Water Mark Changes |
HWM的改变 |
ALTER SESSION SET EVENTS '10081 trace name context forever, level 1'; |
Event 10104 - Dump Hash Join Statistics |
HASH JOIN的统计信息 |
ALTER SESSION SET EVENTS '10104 trace name context forever, level 10'; |
Event 10128 - Dump Partition Pruning Information |
分区表调整信息 |
ALTER SESSION SET EVENTS '10128 trace name context forever, level level'; Level取值: 1 Dump pruning descriptor for each partitioned object 0x0002 Dump partition iterators 0x0004 Dump optimizer decisions about partition-wise joins 0x0008 Dump ROWID range scan pruning information 在9.0.1或者后面的版本,在level 2后还需要建立如下的表: CREATE TABLE kkpap_pruning ( partition_count NUMBER, iterator VARCHAR2(32), partition_level VARCHAR2(32), order_pt VARCHAR2(12), call_time VARCHAR2(12), part# NUMBER, subp# NUMBER, abs# NUMBER ); |
事件 |
说明 |
例子 |
Event 10200 - Dump Consistent Reads |
DUMP一致读的信息 |
ALTER SESSION SET EVENTS '10200 trace name context forever, level 1'; |
Event 10201 - Dump Consistent Read Undo Application |
DUMP一致性读涉及UNDO信息的内容 |
ALTER SESSION SET EVENTS '10201 trace name context forever, level 1'; |
Event 10220 - Dump Changes to Undo Header |
Dump出Undo头信息的改变 |
ALTER SESSION SET EVENTS '10220 trace name context forever, level 1'; |
Event 10221 - Dump Undo Changes |
Dump Undo的改变 |
ALTER SESSION SET EVENTS '10221 trace name context forever, level 7'; |
Event 10224 - Dump Index Block Splits / Deletes |
索引块的分裂和D删除信息 |
ALTER SESSION SET EVENTS '10224 trace name context forever, level 1'; |
Event 10225 - Dump Changes to Dictionary Managed Extents |
DUMP字段管理的扩展变化 |
ALTER SESSION SET EVENTS '10225 trace name context forever, level 1'; |
Event 10231 |
全表扫描时跳过坏块,在有坏块的情况下做数据拯救时很有用 |
ALTER SYSTEM SET EVENTS '10231 trace name context forever,level 10'; |
Event 10241 - Dump Remote SQL Execution |
远程SQL语句的执行信息 |
ALTER SESSION SET EVENTS '10241 trace name context forever, level 1'; |
Event 10246 - Trace PMON Process |
跟踪PMON进程 |
只能修改参数,不能用ALTER SYSTEM |
event = "10246 trace name context forever, level 1" |
||
Event 10248 - Trace Dispatcher Processes |
跟踪DISPATCHER的工作情况 |
event = "10248 trace name context forever, level 10" |
Event 10249 - Trace Shared Server (MTS) Processes- |
跟踪共享服务器的工作情况 |
event = "10249 trace name context forever, level 10" |
Event 10270 - Debug Shared Cursors |
跟踪共享CURSORS的情况 |
event = "10270 trace name context forever, level 10" |
Event 10299 - Debug Prefetching |
跟踪表数据块和索引数据块的PREFETCHING |
event = "10299 trace name context forever, level 1" |
Event 10357 - Debug Direct Path |
ALTER SESSION SET EVENTS '10357 trace name context forever, level 1'; |
|
Event 10390 - Dump Parallel Execution Slave Statistics |
跟踪并行操作中的SLAVE的状态 |
ALTER SESSION SET EVENTS '10390 trace name context forever, level 1; |
Event 10391-Dump Parallel Execution Granule Allocation |
跟踪并行操作的粒度 |
ALTER SESSION SET EVENTS '10391 trace name context forever, level 2'; |
Event 10393 - Dump Parallel Execution Statistics |
跟踪并行操作的状态(每个SLAVE单独列出状态) |
ALTER SESSION SET EVENTS '10393 trace name context forever, level 1'; |
Event 10500 - Trace SMON Process |
跟踪SMON进程 |
event = "10500 trace name context forever, level 1" |
Event 10608 - Trace Bitmap Index Creation |
跟踪BITMAP索引创建的详细过程 |
ALTER SESSION SET EVENTS '10608 trace name context forever, level 10'; |
Event 10704 - Trace Enqueues |
跟踪锁的使用情况 |
ALTER SESSION SET EVENTS '10704 trace name context forever, level 1'; |
Event 10706 - Trace Global Enqueue Manipulation |
跟踪全局锁的使用情况 |
ALTER SESSION SET EVENTS '10706 trace name context forever, level 1'; |
Event 10708 - Trace RAC Buffer Cache |
跟踪RAC环境下的BUFFER CACHE |
ALTER SESSION SET EVENTS '10708 trace name context forever, level 10'; |
事件 |
说明 |
例子 |
Event 10710 - Trace Bitmap Index Access |
跟踪位图索引的访问情况 |
ALTER SESSION SET EVENTS '10710 trace name context forever, level 1'; |
Event 10711 - Trace Bitmap Index Merge Operation |
跟踪位图索引合并操作 |
ALTER SESSION SET EVENTS '10711 trace name context forever, level 1'; |
Event 10712 - Trace Bitmap Index OR Operation |
跟踪位图索引或操作情况 |
ALTER SESSION SET EVENTS '10712 trace name context forever, level 1'; |
Event 10713 - Trace Bitmap Index AND Operation |
跟踪位图索引与操作 |
ALTER SESSION SET EVENTS '10713 trace name context forever, level 1'; |
Event 10714 - Trace Bitmap Index MINUS Operation |
跟踪位图索引minus操作 |
ALTER SESSION SET EVENTS '10714 trace name context forever, level 1'; |
Event 10715 - Trace Bitmap Index Conversion to ROWIDs Operation |
跟踪位图索引转换ROWID操作 |
ALTER SESSION SET EVENTS '10715 trace name context forever, level 1'; |
Event 10716 - Trace Bitmap Index Compress/Decompress |
跟踪位图索引压缩和解压缩情况 |
ALTER SESSION SET EVENTS '10716 trace name context forever, level 1'; |
Event 10717 - Trace Bitmap Index Compaction |
ALTER SESSION SET EVENTS '10717 trace name context forever, level 1'; |
|
Event 10719 - Trace Bitmap Index DML |
跟踪位图索引列的DML操作(引起位图索引改变的DML操作) |
ALTER SESSION SET EVENTS '10719 trace name context forever, level 1'; |
Event 10730 - Trace Fine Grained Access Predicates |
跟踪细粒度审计的断语 |
ALTER SESSION SET EVENTS '10730 trace name context forever, level 1'; |
Event 10731 - Trace CURSOR Statements |
跟踪CURSOR的语句情况 |
ALTER SESSION SET EVENTS '10731 trace name context forever, level level'; LEVEL定义 1 Print parent query and subquery 2 Print subquery only |
Event 10928 - Trace PL/SQL Execution |
跟踪PL/SQL执行情况 |
ALTER SESSION SET EVENTS '10928 trace name context forever, level 1'; |
Event 10938 - Dump PL/SQL Execution Statistics |
跟踪PL/SQL执行状态。使用前需要执行rdbms/admin下的tracetab.sql |
ALTER SESSION SET EVENTS '10938 trace name context forever, level 1'; |
flush_cache |
刷新BUFFER CACHE |
ALTER SESSION SET EVENTS 'immediate trace name flush_cache'; |
DROP_SEGMENTS |
手工删除临时段。当这些临时段无法自动清除的时候可以手工清除 |
alter session set events 'immediate trace name DROP_SEGMENTS level ts#+1'; ts#是指要删除临时段的表空间的ts# |