Rumah > Artikel > pangkalan data > 五, 监控oracle的等待事件
五 , 监控 oracle 的等待事件 select event, sum (decode(wait_Time, 0 , 0 , 1 )) "Prev", sum (decode(wait_Time, 0 , 1 , 0 )) "Curr", count (*) "Tot" from v$session_Wait group by event order by 4 ; 5.1 等待事件概述 Oracle 的等待事件是衡量 orac
select event,
sum(decode(wait_Time, 0, 0, 1)) "Prev",
sum(decode(wait_Time, 0, 1, 0)) "Curr",
count(*) "Tot"
from v$session_Wait
groupby event
orderby4;
Oracle的等待事件是衡量oracle运行状况的重要依据及指标.
等待事件的概念是在Oracle7.0.1.2中引入的,大致有100个等待事件。在Oracle 8.0中这个数目增加到了大约150个,在Oracle8i中大约有200个事件,在Oracle9i中大约有360个等待事件。
主要有两种类别的等待事件,即空闲(idle)等待事件和非空闲(non-idle)等待事件。
空闲等待事件是指Oracle正等待某种工作,比如用sqlplus登录之后,但没有进一步发出任何命令,此时该session就处于SQL*Net message from/to client等待事件状态,等待用户发出命令,任何的在诊断和优化数据库的时候,我们不用过多注意这部分事件。非空闲等待事件专门针对Oracle的活动,指数据库任务或应用运行过程中发生的等待,这些等待事件是我们在调整数据库的时候应该关注与研究的。
每一个等待事件都属于某一类, 下面给出了每一类等待事件的描述.
管理类: administrative
类等待事件是由于DBA的管理命令引起的,这些命令要求用户处于等待状态,比如,重建索引。
应用程序类:
此类等待事件是由于用户应用程序的代码引起的(比如:锁等待).
群集类:Cluster
此类等待事件和真正应用群集RAC的资源有关。(比如:gc cr block busy等待事件).
提交确认类:Commit
此类等待事件只包含一种等待事件--在执行了一个commit命令后,等待一个重做日志写确认(也就是log file sync).
并发类:Concurrency
此类等待事件是由内部数据库资源引起的,比如闩锁。
配置类:Configuration
此类等待事件是由数据库或实例的不当配置造成的,比如,重做日志文件尺寸太小,共享池的大小等。
空闲类:Idle
此类等待事件意味着会话不活跃,等待工作。比如,sql * net messages from client。
网络类:Network
和网络环境相关的一些等待事件,比如sql* net more data to dblink。
Other
此类等待事件通常比较少见。
调度类:Scheduler
Resource Manager related waits (for example, '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。
1, db file scattered read (DB文件分散读取)
这种情况通常与全表扫描相关. 当数据库进行全表扫描时, 基于性能的考虑, 数据会分散(scattered)读入buffer cache. 如果这个等待事件比较显著, 可能考虑查看对应的表有没有创建合适的索引.
然而这个等待事件并不一定就意味着性能低下, 在某些条件下oracle会主动使用全表扫描来替换索引扫描以提高性能, 这和访问的数据量有关, 在CBO下oracle会进行更为智能的选择, RBO下oracle更倾向于使用索引.
因为全表扫描到内存的数据块被置于LRU链表的冷端, 所以这些数据块将可能在较短时间内被置换出物理内存, 为了避免反复物理IO, 对频繁访问的较小的数据表,可以选择把他们cache到内存中.
当这个等待时间比较显著时, 可以结合v$session_longops动态性能视图来进行诊断, 该视图中记录了长时间(运行时间超过6秒)运行的事务, 可能很多是全表扫描操作.
Column |
Datatype |
Description |
SID |
NUMBER |
Session identifier |
SERIAL# |
NUMBER |
Session serial number |
OPNAME |
VARCHAR2(64) |
Brief description of the operation |
TARGET |
VARCHAR2(64) |
The object on which the operation is carried out |
TARGET_DESC |
VARCHAR2(32) |
Description of the target |
SOFAR |
NUMBER |
The units of work done so far |
TOTALWORK |
NUMBER |
The total units of work |
UNITS |
VARCHAR2(32) |
The units of measurement |
START_TIME |
DATE |
The starting time of operation |
LAST_UPDATE_TIME |
DATE |
Time when statistics last updated |
TIME_REMAINING |
NUMBER |
Estimate (in seconds) of time remaining for the operation to complete |
ELAPSED_SECONDS |
NUMBER |
The number of elapsed seconds from the start of operations |
CONTEXT |
NUMBER |
Context |
MESSAGE |
VARCHAR2(512) |
Statistics summary message |
USERNAME |
VARCHAR2(30) |
User ID of the user performing the operation |
SQL_ADDRESS |
RAW(4) |
Used with the value of the SQL_HASH_VALUE column to identify the SQL statement associated with the operation |
SQL_HASH_VALUE |
NUMER |
Used with the value of the SQL_ADDRESS column to identify the SQL statement associated with the operation |
QCSID |
NUMBER |
Session identifier of the parallel coordinator |
2, db file sequential read(DB 文件顺序读取)
这一事件通常显示与单个数据块相关的读取操作, 比如对索引块的读取. 如果这个等待事件比较显著, 可能表示在多表连接中, 表的链接顺序存在问题, 可能没有正确的使用驱动表; 或者可能说明不加选择地进行索引.
3, free buffer (释放缓冲区)
这个等待事件表明系统正在等待内存中的可用空间,这说明当前Buffer 中已经没有Free 的内存空间。Free Buffer 等待可能说明DBWR 的写出速度不够,或者磁盘存在严重的竞争,可以需要考虑增加检查点、使用更多的DBWR 进程,或者增加物理磁盘的数量,分散负载,平衡IO。
4, buffer busy(缓冲区忙)
该等待事件表示正在等待一个以unshareable方式使用的缓冲区,或者表示当前正在被读入buffer cache。一般来说Buffer Busy Wait不应大于1%。检查缓冲等待统计部分(或V$WAITSTAT),看一下等待是否位于段头(Segment Header)。如果是,可以考虑增加自由列表(freelist,对于Oracle8i DMT)或者增加freelist groups(在很多时候这个调整是立竿见影的,在8.1.6之前,这个freelists参数不能动态修改;在8.1.6及以后版本,动态修改 feelists需要设置COMPATIBLE至少为8.1.6).
This view lists block contention statistics. This table is only updated when timed statistics are enabled.
Column |
Datatype |
Description |
CLASS |
VARCHAR2(18) |
Class of the block |
COUNT |
NUMBER |
Number of waits by this OPERATION for this CLASS of block |
TIME |
NUMBER |
Sum of all wait times for all the waits by this OPERATION for this CLASS of block |
select * from V$WAITSTAT
CLASS |
COUNT |
TIME |
data block |
318671 |
91287 |
undo header |
50352 |
1172 |
undo block |
28 |
1 |
segment header |
10 |
5 |
file header block |
8 |
1 |
1st level bmb |
3 |
0 |
bitmap index block |
0 |
0 |
system undo block |
0 |
0 |
system undo header |
0 |
0 |
unused |
0 |
0 |
bitmap block |
0 |
0 |
save undo header |
0 |
0 |
save undo block |
0 |
0 |
sort block |
0 |
0 |
free list |
0 |
0 |
3rd level bmb |
0 |
0 |
2nd level bmb |
0 |
0 |
extent map |
0 |
0 |
如果这一等待位于undo header,可以通过增加回滚段(rollback segment)来解决缓冲区的问题。如果等待位于undo block上,我们可能需要检查相关应用,适当减少大规模的一致性读取,或者降低一致性读取(consistent read)的表中的数据密度或者增大DB_CACHE_SIZE。
如果等待处于data block,可以考虑将频繁并发访问的表或数据移到另一数据块或者进行更大范围的分布(可以增加pctfree值,扩大数据分布,减少竞争),以避开这个"热点"数据块,或者可以考虑增加表中的自由列表或使用本地化管理的表空间(Locally Managed Tablespaces)。
如果等待处于索引块,应该考虑重建索引、分割索引或使用反向键索引。为了防止与数据块相关的缓冲忙等待,也可以使用较小的块:在这种情况下,单个块中的记录就较少,所以这个块就不是那么"繁忙";或者可以设置更大的pctfree,使数据扩大物理分布,减少记录间的热点竞争。
在执行DML (insert/update/ delete)时,Oracle向数据块中写入信息,对于多事务并发访问的数据表,关于ITL的竞争和等待可能出现,为了减少这个等待,可以增加 initrans,使用多个ITL槽。在Oracle9i 中,引入了一个新概念:ASSM(Segment Space Management Auto)。通过这个新特性Oracle 使用位图来管理空间使用。
ASSM 结合LMT 彻底改变了Oracle 的存储机制,位图freelist 能够减轻缓冲区忙等待(buffer busy wait),这个问题在Oracle9i 以前的版本里曾是一个严重的问题。
Oracle 宣称ASSM 显著地提高了DML 并发操作的性能,因为(同一个)位图的不同部分可以被同时使用,这样就消除了寻找剩余空间的串行化。根据Oracle 的测试结果,使用位图freelist 会消除所有分段头部(对资源)的争夺,还能获得超快的并发插入操作。在Oracle9i 之中,Buffer Busy wait 不再常见!
5, latch free (latch 释放)
latch是一种低级排队机制,用于保护SGA中共享内存结构。latch就像是一种快速地被获取和释放的内存锁。用于防止共享内存结构被多个用户同时访问。如果latch不可用,就会记录latch释放失败(latch free miss )。有两种与闩有关的类型:
■ 立刻。
■ 可以等待。
假如一个进程试图在立刻模式下获得闩,而该闩已经被另外一个进程所持有,如果该闩不能立可用的话,那么该进程就不会为获得该闩而等待。它将继续执行另一个操作。
大多数latch问题都与以下操作相关:
没有很好的是用绑定变量(library cache latch)、重作生成问题(redo allocation latch)、缓冲存储竞争问题(cache buffers LRU chain),以及buffer cache中的存在"热点"块(cache buffers chain)。
通常我们说,如果想设计一个失败的系统,不考虑绑定变量,这一个条件就够了,对于异构性强的系统,不使用绑定变量的后果是极其严重的。
另外也有一些latch等待与bug有关,应当关注Metalink相关bug的公布及补丁的发布。当latch miss ratios大于0.5%时,就应当研究这一问题。
6, log buffer space(日志缓冲空间)
当你将日志缓冲(log buffer)产生重做日志的速度比LGWR 的写出速度快,或者是当日志切换(log switch)太慢时,就会发生这种等待。这个等待出现时,通常表明redo log buffer 过小,为解决这个问题,可以考虑增大日志文件的大小,或者增加日志缓冲器的大小。
另外一个可能的原因是磁盘I/O 存在瓶颈,可以考虑使用写入速度更快的磁盘。在允许的条件下设置可以考虑使用裸设备来存放日志文件,提高写入效率。在一般的系统中,最低的标准是,不要把日志文件和数据文件存放在一起,因为通常日志文件只写不读,分离存放可以获得性能提升。
1, v$session_wait
这是一个寻找性能瓶颈的关键视图, 它提供任何情况下session在数据库中当前正在等待什么(如果session当前什么也没在做, 则显示它最后等待的事件)
每一个链接到实例的session都对应一条记录.
Column |
Datatype |
Description |
|
|
Session identifier |
|
|
Sequence number that uniquely identifies this wait. Incremented for each wait. |
|
|
Resource or event for which the session is waiting session当前正在等待的事件, 或者最后一次等待事件. |
|
|
Description of first additional parameter |
|
|
First additional parameter |
|
|
First additional parameter |
|
|
Description of second parameter |
|
|
Second additional parameter |
|
|
Second additional parameter |
|
|
Description of third parameter |
|
|
Third additional parameter |
|
|
Third additional parameter |
|
|
A nonzero value is the session's last wait time. A zero value means the session is currently waiting. |
|
|
If |
|
|
Wait state: · · · · |
2, v$session_event
本视图记录了每个session的每一项等待事件. 由上文所知v$session_wait显示了session的当前等待事件, 而v$sesion_event则记录了session自启动起所有的事件.
Column |
Datatype |
Description |
|
|
The ID of the session |
|
|
The name of the wait event See Also:Appendix A, "Oracle Wait Events" |
|
|
The total number of waits for this event by this session |
|
|
The total number of timeouts for this event by this session |
|
|
The total amount of time waited for this event by this session, in hundredths of a second |
|
|
The average amount of time waited for this event by this session, in hundredths of a second |
|
|
The maximum time (in hundredths of a second) waited for this event by this session |
3, 查询所有连接的实例的session的相关信息
-- session总体等待
select a.SID,a.USERNAME,a.machine,a.TERMINAL,b.EVENT,b.TOTAL_WAITS,b.TOTAL_TIMEOUTS
from v$session a,
V$SESSION_EVENT b
where a.SID = b.SID
and a.status = 'ACTIVE'
anduser# >0;
-- session当前等待
select a.SID,a.USERNAME,a.machine,a.TERMINAL,b.EVENT,b.WAIT_TIME,b.SECONDS_IN_WAIT,b.STATE
from v$session a,
V$SESSION_wait b
where a.SID = b.SID
and a.status = 'ACTIVE'
anduser# >0;
-- 当前session正在执行语句
select a.SID,a.USERNAME,a.machine,a.TERMINAL,b.PIECE,b.SQL_TEXT
from v$session a,
v$sqltext b
where b.ADDRESS = decode(a.SQL_HASH_VALUE,0,a.PREV_SQL_ADDR,a.SQL_ADDRESS)
and a.status = 'ACTIVE'
anduser# >0
orderby a.SQL_ADDRESS,b.PIECE;
-- session当前等待
select a.SID,a.USERNAME,a.machine,a.TERMINAL,c.NAME,b.VALUE
from v$session a,
V$SESStat b,
v$statname c
where a.SID = b.SID
and b.STATISTIC# = c.STATISTIC#
and a.status = 'ACTIVE'
anduser# >0
and b.value > 0;