Oracle等待事件

12 篇文章 0 订阅
6 篇文章 0 订阅

等待事件的起源

等待事件的概念大概是从Oracle 7.0.12中引入的,大致有100个等待事件。在Oracle 8.0中这个数据增大到了大约150个,8I中220个,在ORACLE 9i2 中大约有400个等待事件,而在10G R2中,大约有874个等待事件。

不同版本的等待事件都可以通过查询v$event_name视图获得。

SQL>select * from V$session;

select count(*) from v$event_name;

ORACLE的等待事件,主要可以分为两类,

oracle等待事件,可以分为如下两类:

  • 空闲等待事件:

Oracle正在等待某种工作,在诊断和优化数据库的时候,不用过多注意这部分事件

  • 非空闲等待事件:

专门针对oracle的活动,指数据库或应用运行过程中发生的等待,这些等待事件是在调整数据库的时候需要关注和研究的。

下面是oracle 10gR2中主要分类及各类别等待事件的个数“

select  wait_class#,wai_class_id,wait_class,count(*)  as "count"
from v$event_name
group by wait_class#,wait_class_id,wait_class
order by wait_class#;

等待事件总结

常见的空闲事件有:

dispatcher timer

lock element  cleanup

null event

parallel  query  dequeue  wait

parallel  query  idle  wait - Slaves

pipe  get

PL/SQL lock  timer

pmon  timer-pmon

rdbms  ipc  message

slave wait

smon  timer

 SQL*Net break/reset to client

SQL*Net  message from client

SQL*Net  message to client

SQL*Net  more  data  to  client

virtual  circuit  status

client  message

一些常见的非空闲等待事件有:

db file  sscattered  read

db  file  sequential  read

buffer  busy   waits

free  buffer  waits

enquence

latch  free

log  file  parallel  write

log  file  sync

几个视图的总结:

v$session   数据库活动开始,为源起

v$session_wait     视图用以实时记录活动session的等待情况,当前信息

v$session_wait_history   是对v$session_wait的简单增强,记录活动session的最近10次等待

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来记录数据库自启动以来所有等待事件的汇总信息。通过这个视图,用户可以迅速获得数据库运行的总体概况。

v$sqltext  当数据库出现瓶颈时,通常可以从v$sesion_wait找到正在等待资源的session,通过session的sid,联合从v$session和v$sqltext视图就可以捕获这些session正在执行的sql语句

重要等待事件

1.db  file  sequential  read(数据文件读取顺序)

        是个非常常见的IO相关的等待事件,通常显示于单个数据块相关的读取操作,在大多数情况下,读取一个索引块或者通过索引读取一个数据块时,都会记录这个等待。

        这个等待事件有3个参数,P1,P2,P3,其中P1代表oracle要读取的文件的绝对文件号,P2代表oracle从这个文件中开始读取的起始数据块块号,P3读取的block数量,通常这个值为1,表明是单个block被读取。

select name,parameter1,parameter2,parameter3 from v$session_name 
where name='db file sequential read';

NAME                           PARAMETER1 PARAMETER2 PARAMETER3

------------------------------ ---------- ---------- ----------
db file sequential read          file#       block#    blocks

        如果该等待事件比较显著,可能表示在多表连接中,表的连接顺序存在问题,可能没有正确的使用驱动表;或者可能索引的使用存在问题,并非索引总是最好的选择。

        在大多数情况下,通过索引可以更为快速的获取记录,所以对于一个编码规范,调整良好的数据库,这个等待事件很大可能是正常的。但是在很多情况下,使用索引并不是最佳的选择,比如读取较大表中的大量的数据,全表扫描可能会明显快于索引扫描,所以在开发中就应该注意,对于这样的查询因该避免使用索引扫描。

        从oracle 9iR2开始,oracle引入了段级统计信息收集的新特性,收集的统计信息共有1类:

select * from v$segstat_name;

        在oracle 10gR2中,这类统计信息增加为15个。

        对于CBO(cost basic optimizer)模式下的数据库,应当及时收集统计信息,使SQL可以选择正确的执行计划,避免因为统计信息陈旧而导致的执行错误等。

2.db file scattered read(数据文件离散读取)

select * from v$event_name where name='db file scattered read';

EVENT#      EVENT_ID   NAME                     PARAMETER1 PARAMETER2 PARAMETER3

---------- ---------- ------------------------- ---------- ---------- ----------
188        506183215   db file scattered read    file#      block#      blocks       

        从v$event_name视图中可以看到,该事件有3个参数,分别代表文件号、起始数据块、数据块的数量。

        起始数据块号加上数据块的数量,这意味着Oracle session正在等待多块连续操作的完成。这个操作可能是全表扫描(full table scan)或者快速全表索引扫描(index fast full scan)的连续读取相关。根据经验,通常大量的db file scattered read等待可能意味着应用问题或者索引缺失

        在实际环境的诊断过程中,可以通过v$session_wait视图发现session的等待,再结合其他视图找到存在问题的sql等根本原因,从而从根本上解决问题。当这个等待事件比较显著时,也可结合v$session_longops动态性能视图来进行诊断,该视图记录了长时间(运行时间超过6s的)运行的事务。

从oracle 9i开始,oracle新增了一个视图v$sql_plan用于记录当前系统library cache中sql语句的执行计划,可以通过这个视图找到存在问题的sql语句。

通过v$sql_paln视图,可以获得大量有用的信息:

获得全表扫描的对象

select distinct object_name,object_owner from v$sql_plan p where  p.operation='TABLE ACCESS' and p.options='FULL' and object_owner='SYS';

获得全索引扫描的对象

select distinct object_name,object_owner from v$sql_plan p where  p.operation='INDEX' and p.options='FULL SCAN' and object_owner='SYS';

通过v$sql_plan和v$sqltext联合,获得全表扫描的sql语句

select sql_text from v$sqltext t,v$sqlplan p
where t.hash_value=p.hash_value and p.operation='TABLE ACCESS' and p.options='FULL'
order by p.hash_value,t.price; 

3. direct path read/write(直接路径读/写)

直接路径读通常发生在Oracle直接读取数据到PGA时,这个读取不需要经过SGA。直接路径读等待参数分别是:file#(指绝对文件号)、first block#和block数量。

这类读取通常在以下情况被使用:

磁盘排序IO操作

并行查询从属进程

预读操作

        最常见的是第一种情况。在DSS系统(决策支持系统)中,存在大量的direct path read是很正常的。但是在OLTP系统中,通常显著的直接路径读都意味着系统应用存在问题,从而导致大量的词牌排序读取操作。

        直接路径写通常发生在Oracle直接从PGA写数据到数据文件或临时文件,这个写操作可以绕过SGA。直接路径读写等待事件的3个参数分别是:file#(指绝对文件号),first block#和block数量。

        这类读取通常在以下情况下使用:

直接路径加载

并行DML操作

磁盘排序

对未缓存的“LOB”段的写入,随后会记录为direct path write(lob)等待

最常见的直接路径写,多数因为磁盘排序导致。对于这一写入等待,应该找到IO操作最为频繁的数据文件(如果有过多的排序操作,很有可能就是临时文件),分散负载,加快写入操作

        如果系统存在过多的磁盘排序,会导致临时表空间操作频繁,对这种情况,可以考虑为不同用户分配不同的临时表空间,使用多个临时表空间,写入不同磁盘或者裸设备,从而降低竞争性提高性能

日志文件相关等待

select name from v$event_name where name like '%log%';

4. log  file  switch(日志文件切换)

log file switch 当日志文件发生切换时出现,在数据库进行日志切换时,LGWR需要关闭当前日志组,切换并打下一个日志组,在这个切换过程中,数据库的所有DML操作都属于停顿状态,直至这个切换完成。

log file switch主要包含两个子事件:

        1.log file switch (archived needed),即日志切换(需要归档)

        这个这个等待事件出现时通常是因为日志组循环写满以后,在需要覆盖先前日志时,发现日志归档尚未完成,出现该等待。由于redo不能写出,该等待出现时,数据库将陷入停顿状态。

        出现该等待,可能表示IO存在问题、归档进程写出缓慢,也有可能是日志组设置不合理原因导致。针对不同原因,可以考虑采用的解决办法有:

        可以考虑增大日志文件和增加日志组;

        移动归档文件到快速磁盘;

        调整log_archive_max_processes参数等;

        2.log file switch(checkpoint incomplete),即日志切换(检查点未完成)

        当所有的日志组都写满之后。LGWR视图覆盖某个日志文件,如果这时数据库没有完成写出这个日志文件所保护的脏数据时(检查点未完成),该等待事件出现。此时数据库同样将陷入停顿状态。

        该等待时间通常表示DBWR写出速度太慢或者IO存在问题。为解决该问题,可能需要考虑增加额外的DBWR或者增加日志组或日志文件大小

5. log file sync(日志文件同步)

当一个用户提交或回滚数据时,LGWR将会话期的重做日志由日志缓冲区写入到重做日志,LGWR完成任务后会通知用户进程。日志文件同步过程必须等待这一过程成功完成。对于回滚操作,该事件记录从用户发出rollback命令回滚完成的时间。

        如果该等待过多,可能说明LGWR的写出效率低下,或者系统提交过于频繁。针对该问题,可以通过log file parallel write等待事件或user commits、user rollback等统计信息来观察提交或回滚次数

可能的解决方案主要有:

1)提高LGWR性能,尽量使用快速磁盘,不要把redo log file存放在RAID5的磁盘上:RAID5对于频繁写入得系统 会带来较大得性能损失,可以考虑使用文件系统直接输入、输出,或者使用裸设备(raw device),这样可以获得写入得性能提高。

2)使用批量提交;

3)适当使用nologging、unrecoverable等选项

6. log file single write

        该事件仅与写日志文件头块相关,通常发生在增加新的组成员和增进序列号(log switch)时。头块写单个进行,因为头块得部分信息是文件号,每个文件不同,更新日志文件头这个操作在后台完成,一般很少出现,无需太多关注。

7. log file parallel write 

        从log buffer写redo记录到日志文件,主要指常规写操作(相对于log file sync)。如果log group存在多个组成员,当flush log buffer时,写操作是并行的,这时候此等待事件可能出现。

        尽管这个写操作并行处理,直到所有IO操作完成该写操作才会完成(如果你的磁盘支持异步IO或者使用IO SLAVE,那么即使只有一个redo  log  file  member,也有可能出现此等待)。

        这个参数和log file sync时间相比较可以用来衡量log file的写入成本。通常称为同步成本率

8. log buffer space(日志缓冲空间)

        当数据库产生日志的速度比lgwr的写出速度快,或者当日志切换太慢时,就会发生这种等待。这种等待出现时,通常表明redo log buffer过小,为解决这个问题,可以考虑增大日志文件的大小或者增加日志缓冲器的大小。

        另一个可能原因时磁盘IO存在性能瓶颈,可以考虑使用写入速度更快的磁盘。在允许的条件下,可以考虑使用裸设备来存放日志文件,提高写入效率。在一般的系统中,最低的标准是,不要把日志文件和数据文件存放在一起,因为通常日志文件只写不读,分离存放可以获得性能提升,尽量使用raid 10而不是raid5磁盘来存储日志文件。

9. enqueue(队列等待)

        enqueue 是一种保护共享资源的锁定机制。该锁定机制保护共享资源,以避免并发操作而损坏数据,比如通过锁保护一行记录,避免多个用户同时更新

enqueue 采用排队机制,即FIFO(先进先出)来控制资源的使用。

enqueue是一组锁定事件的集合,如果数据库中这个等待事件比较显著,还需要进一步追踪是哪一个类别的锁定引发了数据库等待。

select name,wait_class from v$event_name
where name like '%enq%' and  rownum<11;
--记录很多,只取出前10条

10  latch  free(闩锁释放)

        latch free通常被称为闩锁释放,这个名称常常引起误解,实际上应该在前面加上一个“等待(WAIT)”,当数据库出现这个等待时,说明有进程正在等待某个latch被释放,也就是waiting latch free。

        latch 是一种低级排队(串行)机制,用于SGA中共享内存结构。latch就像是一种快速的被动获取和释放的内存锁,用于防止共享内存结构被多个用户同时访问

        如果latch不可用,就会记录latch释放失败(latch free miss)。有两种与闩有关的类型:

1)立刻

2)可以等待

        假如一个进程视图在立刻模式下获得闩,而该闩已经被另外一个进程所持有,如果该闩不能立刻用的话,那么该进程就不会为获得该闩而等待。它将继续执行另一个操作。

        大多数latch问题都与以下操作相关:

        没有很好的使用绑定变量(library cache latch)、重做生成问题(redo allocation latch)、缓冲存储竞争问题(cache buffers LRU chain),以及buffer cache中的存在“热点”块(cache buffers chain)。

        通常我们说,如果想设计一个失败的系统,不考虑绑定变量,这一个条件就够了,对于异构性强的系统,不使用绑定变量的后果是极其严重的。

        另外也有一些latch等待与bug有关,应当关注metalink相关bug的公布及补丁的发布。当latch miss rations大于0.5%时,就应当研究这一问题。

        oracle的latch机制是竞争,其处理类似网络里的CSMA/CD,所有用户进程争夺latch,对于愿意等待类型(willing to wait)的latch,如果一个进程在第一次尝试中没有获得latch,那么它会等待并且再尝试一次,如果经过_spin_count次争夺不能获得latch,然后该进程转入睡眠状态,持续一段指定长度的时间,然后再次醒来,按顺序重复以前的步骤。在8i,9i中默认值是_spin_count=2000。

        如果sql语句不能调整,在8.1.6版本以上,Oracle提供了一个新的初始化参数: cursor_sharing , 可以通过设置cursor_sharing=force在服务器端强制绑定变量。设置该参数可能会带来一定的副作用,对于Java程序,有相关bug,具体应用应该关注metalink的bug公告。

     

11.free buffer-释放缓冲区

        这个等待事件表明系统正在等待内存中的可用空间,这说明当前buffer中已经没有free的内存空间。如果应用设计良好,sql书写规范,充分绑定变量,那这种等待可能说明buffer cache设置的偏小,你可能需要增大db_buffer_cache。

        free buffer等待可能说明dbwr的写出速度不够,或者磁盘存在严重的竞争,可以需要考虑增加检查点、使用更多的dbwr进程,或者增加物理磁盘的数量,分散负载,平衡IO

12.buffer busy--缓冲区忙

        该等待事件表示在等待一个以unshareable方式使用的缓冲区,或者表示当前正在被读入buffer cache。一般来说buffer busy wait不应大于1%。

        检查缓冲等待统计部分(或v$waitstat),看一下是否位于段头(segment header)。如果是,可以考虑增加自由列表(freelist,对于oracle 8i DMT)或者增加freelist groups(在很多时候这个调整是立竿见影的,在8.1.6之前,这个freelist参数是不能动态修改;在8.1.6及以后版本,动态修改freelist需要设置compatible至少为8.1.6)

        如果这一等待位于undo header,可以通过增加回滚段(rollback segment)来解决缓冲区的问题。如果等待位于undo block上,我们可能需要检查相关应用,适当减少大规模的一致性读取,或者降低一致性读取的表中的数据密度或者增大db_cache_size

        如果等待处于data block,可以考虑将频繁并发访问的表或数据移到另一数据块,或者进行更大范围的分布(可以增加pctfree值,扩大数据分布,减少竞争),以避开这个热点数据块,或者可以考虑增加表中的自由列表或使用本地化管理的表空间(locally managed  tablespaces)

        如果等待处于索引块,应该考虑重建索引、分割索引或使用反向键索引。为了防止与数据块相关的缓冲忙等待,也可以使用较小的块。在这种情况下,单个块中的记录就比较少,所以这个块就不是那么“繁忙”;或者可以设置更大的pctfree,使数据扩大物理分布,减少记录间的热点竞争。

        在执行DML(delete、update、insert)时,Oracle向数据块中写入信息,对于多事务并发访问的数据表,关于ITL的竞争和等待可能出现,为了减少这个等待,可以增加initrans,使用多个ITL槽。在oracle 9i中,引入了一个新概念(ASSM segment space management auto).通过这个新特性,使用位图来管理空间使用。

        ASSM结合LMT彻底改变了oracle的存储机制,位图freelist能够减轻缓冲区忙等待(buffer busy wait),这个问题在oracle 9i以前的版本里曾是一个严重的问题。

        oracle宣称assm显著的提高了DML并发操作的性能,因为(同一个)位图的不同部分可以被同时使用,这样就消除了寻找剩余空间的串行化。根据oracle的测试结果,使用位图freelist会消除所有分段头部(对资源)的争夺,还能获得超快的并发插入操作。在oracle 9i之中,buffer busy wait不再常见

13. cotrol file  parallel write控制文件并行写

        当server进程更新所有控制文件时,这个时间可能出现。如果等待很短,可以不用考虑,如果等待时间较长,检查存放控制文件的物理磁盘IO是否存在瓶颈。

        多个控制文件是完全相同的拷贝,用于镜像以提高安全性。对于业务系统,多个控制文件应该存放在不同的磁盘上,一般来说3个足够,如果只有2个物理硬盘,则两个控制文件也是可以接受的。在同一个磁盘上保存多个控制文件是不具备实际意义的。减少这个等待,可以考虑如下方法:

        减少控制文件的个数(在确保安全的前提下)

        如果系统支持,使用异步IO

        转移控制文件到IO负担轻的物理磁盘

14. control file sequential read/  control file single write控制文件连续读/控制文件单个写

        对单个控制文件IO存在问题时,这两个事件会出现。如果等待比较明显,检查单个控制文件,看存放位置是否存在IO瓶颈。

        控制文件连续读。由于集群双节点对控制文件频繁访问,该等待事件出现在top表上是很正常的。若是被其他等待事件挤出top 10,需要关注这些等待事件。

15.direct path write-直接路径写

        该等待发生在,系统等待确认所有未完成的异步IO都已写入磁盘。

        对于这一写入等待,我们应该找到IO操作最为频繁的数据文件(如果有过多的排序操作,很有可能时临时文件),分散负载,加快其写入操作。

        如果系统存在过多的磁盘排序,会导致临时表空间操作频繁,对于这种情况,可以考虑使用local 管理表空间,分成多个小文件,写入不同磁盘或者裸设备。

16. idle event 空闲事件

        一般来说,空闲事件是指系统因为无事可做的等待,或者等待用户的请求或者响应等,通常我们可以忽略这些等待事件。空闲事件可以通过stats$idle_event表查询得到

        我们看一下系统的主要空闲等待事件,对这些事件大家应该有个大致的印象,如果你的Top 5 等待事件中,主要都是这些事件,那么一般来说你的系统是比价清闲的。

资源来自如下:

Oracle 等待事件 - spring3mvc学习笔记 - 博客园

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值