监控oracle的等待事件
select event
sum(decode(wait_Time )) Prev
sum(decode(wait_Time )) Curr
count(*) Tot
from v$session_Wait
group by event
order by ;
等待事件概述
Oracle的等待事件是衡量oracle运行状况的重要依据及指标
等待事件的概念是在Oracle中引入的大致有个等待事件在Oracle 中这个数目增加到了大约个在Oraclei中大约有个事件在Oraclei中大约有个等待事件
主要有两种类别的等待事件即空闲(idle)等待事件和非空闲(nonidle)等待事件
空闲等待事件是指Oracle正等待某种工作比如用sqlplus登录之后但没有进一步发出任何命令此时该session就处于SQL*Net message from/to client等待事件状态等待用户发出命令任何的在诊断和优化数据库的时候我们不用过多注意这部分事件非空闲等待事件专门针对Oracle的活动指数据库任务或应用运行过程中发生的等待这些等待事件是我们在调整数据库的时候应该关注与研究的
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
等待事件详细描述
db file scattered read (DB文件分散读取)
这种情况通常与全表扫描相关 当数据库进行全表扫描时 基于性能的考虑 数据会分散(scattered)读入buffer cache 如果这个等待事件比较显着 可能考虑查看对应的表有没有创建合适的索引
然而这个等待事件并不一定就意味着性能低下 在某些条件下oracle会主动使用全表扫描来替换索引扫描以提高性能 这和访问的数据量有关 在CBO下oracle会进行更为智能的选择 RBO下oracle更倾向于使用索引
因为全表扫描到内存的数据块被置于LRU链表的冷端 所以这些数据块将可能在较短时间内被置换出物理内存 为了避免反复物理IO 对频繁访问的较小的数据表可以选择把他们cache到内存中
当这个等待时间比较显着时 可以结合v$session_longops动态性能视图来进行诊断 该视图中记录了长时间(运行时间超过秒)运行的事务 可能很多是全表扫描操作
Column
Datatype
Description
SID
NUMBER
Session identifier
SERIAL#
NUMBER
Session serial number
OPNAME
VARCHAR()
Brief description of the operation
TARGET
VARCHAR()
The object on which the operation is carried out
TARGET_DESC
VARCHAR()
Description of the target
SOFAR
NUMBER
The units of work done so far
TOTALWORK
NUMBER
The total units of work
UNITS
VARCHAR()
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
VARCHAR()
Statistics summary message
USERNAME
VARCHAR()
User ID of the user performing the operation
SQL_ADDRESS
RAW()
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
db file sequential read(DB 文件顺序读取)
这一事件通常显示与单个数据块相关的读取操作 比如对索引块的读取 如果这个等待事件比较显着 可能表示在多表连接中 表的链接顺序存在问题 可能没有正确的使用驱动表; 或者可能说明不加选择地进行索引
free buffer (释放缓沖区)
这个等待事件表明系统正在等待内存中的可用空间这说明当前Buffer 中已经没有Free 的内存空间Free Buffer 等待可能说明DBWR 的写出速度不够或者磁盘存在严重的竞争可以需要考虑增加检查点使用更多的DBWR 进程或者增加物理磁盘的数量分散负载平衡IO
buffer busy(缓沖区忙)
该等待事件表示正在等待一个以unshareable方式使用的缓沖区或者表示当前正在被读入buffer cache一般来说Buffer Busy Wait不应大于%检查缓沖等待统计部分(或V$WAITSTAT)看一下等待是否位于段头(Segment Header)如果是可以考虑增加自由列表(freelist对于Oraclei DMT)或者增加freelist groups(在很多时候这个调整是立竿见影的在之前这个freelists参数不能动态修改;在及以后版本动态修改 feelists需要设置COMPATIBLE至少为)
This view lists block contention statistics This table is only updated when timed statistics are enabled
Column
Datatype
Description
CLASS
VARCHAR()
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
undo header
undo block
segment header
file header block
st level bmb
bitmap index block
system undo block
system undo header
unused
bitmap block
save undo header
save undo block
sort block
free list
rd level bmb
nd level bmb
extent map
如果这一等待位于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槽在Oraclei 中引入了一个新概念:ASSM(Segment Space Management Auto)通过这个新特性Oracle 使用位图来管理空间使用
ASSM 结合LMT 彻底改变了Oracle 的存储机制位图freelist 能够减轻缓沖区忙等待(buffer busy wait)这个问题在Oraclei 以前的版本里曾是一个严重的问题
Oracle 宣称ASSM 显着地提高了DML 并发操作的性能因为(同一个)位图的不同部分可以被同时使用这样就消除了寻找剩余空间的串行化根据Oracle 的测试结果使用位图freelist 会消除所有分段头部(对资源)的争夺还能获得超快的并发插入操作在Oraclei 之中Buffer Busy wait 不再常见!
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大于%时就应当研究这一问题
log buffer space(日志缓沖空间)
当你将日志缓沖(log buffer)产生重做日志的速度比LGWR 的写出速度快或者是当日志切换(log switch)太慢时就会发生这种等待这个等待出现时通常表明redo log buffer 过小为解决这个问题可以考虑增大日志文件的大小或者增加日志缓沖器的大小
另外一个可能的原因是磁盘I/O 存在瓶颈可以考虑使用写入速度更快的磁盘在允许的条件下设置可以考虑使用裸设备来存放日志文件提高写入效率在一般的系统中最低的标准是不要把日志文件和数据文件存放在一起因为通常日志文件只写不读分离存放可以获得性能提升
等待事件相关视图
v$session_wait
这是一个寻找性能瓶颈的关键视图 它提供任何情况下session在数据库中当前正在等待什么(如果session当前什么也没在做 则显示它最后等待的事件)
每一个链接到实例的session都对应一条记录
Column
Datatype
Description
SID
NUMBER
Session identifier
SEQ#
NUMBER
Sequence number that uniquely identifies this wait Incremented for each wait
EVENT
VARCHAR()
Resource or event for which the session is waiting session当前正在等待的事件 或者最后一次等待事件
PTEXT
VARCHAR()
Description of first additional parameter
P
NUMBER
First additional parameter
PRAW
RAW()
First additional parameter
PTEXT
VARCHAR()
Description of second parameter
P
NUMBER
Second additional parameter
PRAW
RAW()
Second additional parameter
PTEXT
VARCHAR()
Description of third parameter
P
NUMBER
Third additional parameter
PRAW
RAW()
Third additional parameter
WAIT_TIME
NUMBER
A nonzero value is the sessions last wait time A zero value means the session is currently waiting
SECONDS_IN_WAIT
NUMBER
If WAIT_TIME = then SECONDS_IN_WAIT is the seconds spent in the current wait condition If WAIT_TIME > then SECONDS_IN_WAIT is the seconds since the start of the last wait and SECONDS_IN_WAIT WAIT_TIME / is the active seconds since the last wait ended
STATE
VARCHAR()
Wait state:
· WAITING (the session is currently waiting)
· WAITED UNKNOWN TIME (duration of last wait is unknown)
· WAITED SHORT TIME (last wait </th of a second)
·> WAITED KNOWN TIME (WAIT_TIME = duration of last wait)
v$session_event
本视图记录了每个session的每一项等待事件 由上文所知v$session_wait显示了session的当前等待事件 而v$sesion_event则记录了session自启动起所有的事件
Column
Datatype
Description
SID
NUMBER
The ID of the session
EVENT
VARCHAR()
The name of the wait event
See Also: Appendix A Oracle Wait Events
TOTAL_WAITS
NUMBER
The total number of waits for this event by this session
TOTAL_TIMEOUTS
NUMBER
The total number of timeouts for this event by this session
TIME_WAITED
NUMBER
The total amount of time waited for this event by this session in hundredths of a second
AVERAGE_WAIT
NUMBER
The average amount of time waited for this event by this session in hundredths of a second
MAX_WAIT
NUMBER
The maximum time (in hundredths of a second) waited for this event by this session
查询所有连接的实例的session的相关信息
session总体等待
select aSIDaUSERNAMEamachineaTERMINALbEVENTbTOTAL_WAITSbTOTAL_TIMEOUTS
from v$session a
V$SESSION_EVENT b
where aSID = bSID
and astatus = ACTIVE
and user# >;
session当前等待
select aSIDaUSERNAMEamachineaTERMINALbEVENTbWAIT_TIMEbSECONDS_IN_WAITbSTATE
from v$session a
V$SESSION_wait b
where aSID = bSID
and astatus = ACTIVE
and user# >;
当前session正在执行语句
select aSIDaUSERNAMEamachineaTERMINALbPIECEbSQL_TEXT
from v$session a
v$sqltext b
where bADDRESS = decode(aSQL_HASH_VALUEaPREV_SQL_ADDRaSQL_ADDRESS)
and astatus = ACTIVE
and user# >
order by aSQL_ADDRESSbPIECE;
session当前等待
select aSIDaUSERNAMEamachineaTERMINALcNAMEbVALUE
from v$session a
V$SESStat b
v$statname c
where aSID = bSID
and bSTATISTIC# = cSTATISTIC#
and astatus = ACTIVE
and user# >
and bvalue > ;