等待事件是Oracle数据库性能优化的关键抓手,自Oracle 7.0.12版本引入以来,已成为DBA定位瓶颈、优化系统的核心工具。它通过记录进程在数据库操作中的各类等待行为,直观反映系统资源竞争、I/O瓶颈等潜在问题,为针对性优化提供明确方向。
一、等待事件的核心概念与分类
1. 源起与发展
等待事件的数量随Oracle版本迭代持续扩充:从Oracle 7.0.12的100余个,到Oracle 11gR1已接近1000个。所有等待事件均可通过V$EVENT_NAME视图查询,该视图记录了事件名称、参数定义、分类ID等核心信息,是研究等待事件的起点。
2. 核心分类逻辑
- 基础分类:分为空闲(Idle)等待和非空闲(Non-idle)等待。空闲等待是进程等待工作的状态(如smon timer),优化时无需重点关注;非空闲等待是数据库活动中的真实等待(如I/O操作、锁竞争),是性能诊断的核心对象。
- 10g后精细分类:Oracle 10g起新增WAIT_CLASS字段,将等待事件划分为13大类,包括User I/O、Concurrency、Commit、Network等,通过V$SYSTEM_WAIT_CLASS可快速查看各类事件的等待时间占比,定位系统主要瓶颈。
二、关键动态性能视图
等待事件的诊断依赖一系列动态性能视图,核心视图及作用如下:
- V$EVENT_NAME:查询所有等待事件的定义、参数及分类信息,是基础参考视图。
- V$SESSION_WAIT:记录当前活动会话的实时等待状态,包括事件名称、参数值、等待时长等,可直接定位当前阻塞会话。
- V$SYSTEM_EVENT:汇总数据库自启动以来的所有等待事件统计,包括总等待次数、总等待时间、平均等待时长,用于全局性能概况分析。
- V$SESSION_EVENT:记录单个会话生命周期内的累积等待事件,支持追踪特定会话的历史等待行为。
- V$EVENT_HISTOGRAM:以柱状图形式展示等待事件的等待时间分布,便于识别长时等待的占比情况。
三、Oracle版本增强:从实时监控到历史追溯
1. Oracle 10g的核心突破
- V$SESSION_WAIT_HISTORY:记录活动会话最近10次等待事件,突破了V$SESSION_WAIT仅能查看实时状态的局限,可追溯历史等待细节。
- ASH(Active Session History):每秒钟采样一次活动会话的等待状态,数据存储在SGA的ASH Buffers中,默认保留1小时。通过V$ACTIVE_SESSION_HISTORY视图查询,结合ashrpt.sql脚本可生成ASH报告,精准分析特定时段的性能问题。
- AWR(Automatic Workload Repository):自动捕获数据库负载数据,每小时生成一次快照,默认保留7天。通过awrrpt.sql生成报告,或awrddrpt.sql生成时段对比报告,支持历史性能趋势分析与瓶颈溯源。
2. Oracle 11g的功能升级
- 实时SQL监控:新增V$SQL_MONITOR视图,自动监控执行时间超过5秒(单进程)或并行执行的SQL,记录CPU消耗、I/O等待等关键指标,支持通过DBMS_SQLTUNE.REPORT_SQL_MONITOR生成可视化报告。
- 自适应直接读:对于大型表的全表扫描,自动选择Direct Path Read绕过SGA,减少Buffer Cache竞争,可通过10949事件禁用该特性。
- Mutex机制:引入互斥锁(Mutex)替代传统Latch机制,降低CPU消耗,V$MUTEX_SLEEP和V$MUTEX_SLEEP_HISTORY视图可查询Mutex竞争情况。
四、关键等待事件解析与优化建议
1. I/O相关等待事件
- db file sequential read:单块顺序读取,常见于索引扫描,参数file#(文件号)、block#(数据块号)、blocks(读取块数)可定位具体文件。优化方向:检查索引有效性、调整表连接顺序、整理存储碎片。
- db file scattered read:多块离散读取,常见于全表扫描,数据块分散写入Buffer Cache。若等待显著,可能是缺少索引或SQL优化不足,需通过创建索引、调整DB_FILE_MULTIBLOCK_READ_COUNT参数优化。
- direct path read/write:直接路径读写,绕过SGA直接访问PGA或磁盘,常见于磁盘排序、并行查询。OLTP系统中频繁出现可能意味着排序过度,需增大PGA_AGGREGATE_TARGET或优化SQL减少排序。
2. 日志相关等待事件
- log file sync:用户提交时等待LGWR将日志缓冲区数据写入重做日志,等待过长可能是提交过于频繁或LGWR写入效率低。优化建议:批量提交、使用快速存储存放重做日志、避免RAID5存储日志文件。
- log file switch:日志切换等待,分为“归档未完成”和“检查点未完成”子类。优化方向:增大日志文件大小、增加日志组、提升归档进程效率。
3. 锁与闩锁等待事件
- Enqueue:队列锁等待,用于保护共享资源(如表、行数据),常见类型包括TX(行级锁)、TM(表级锁)、ST(空间事务锁)。TX锁等待多由并发更新冲突导致,TM锁等待可能是DDL与DML并行执行引发。
- Latch Free:闩锁释放等待,闩锁是保护SGA共享内存结构的轻量级锁,常见于Buffer Cache竞争(cache buffers chains)和Shared Pool竞争(library cache latch)。优化建议:减少硬解析、调整_SPIN_COUNT参数、优化热点数据访问。
五、实践案例:从等待事件定位到优化落地
某Solaris 8环境下的Oracle 9.1.7.4数据库出现性能缓慢,业务反馈系统响应延迟。诊断步骤如下:
- 查询等待事件:通过V$SESSION_WAIT发现大量db file scattered read和db file sequential read等待,且集中在文件号17的数据文件,提示全表扫描过量。
- 捕获问题SQL:结合V$SESSION和V$SQLTEXT,通过会话SID追踪到核心SQL,执行计划显示对HS_INFO表的查询使用全表扫描,该表含22万条数据但未在过滤条件NUMCATALOGGUID字段创建索引。
- 执行优化:创建索引hs_info_NUMCATALOGGUID后,SQL执行计划切换为索引范围扫描,再次查询V$SESSION_WAIT,原大量I/O等待消失,系统响应速度恢复正常。
四、Oracle等待事件诊断速查表
核心诊断视图
视图名称核心作用关键字段/查询示例V$EVENT_NAME查询所有等待事件定义、参数、分类select name,parameter1,parameter2,parameter3,wait_class from v$event_name where name like '%db file%';V$SESSION_WAIT实时查看活动会话的等待状态select sid,event,p1,p1text,seconds_in_wait from v$session_wait where event not like 'SQL%';V$SYSTEM_EVENT汇总数据库全局等待统计(自启动以来)select event,total_waits,time_waited,average_wait from v$system_event order by time_waited desc;V$SESSION_EVENT单个会话的累积等待事件select sid,event,time_waited from v$session_event where sid=123 order by time_waited desc;V$EVENT_HISTOGRAM等待事件的时间分布柱状图select event,wait_time_milli,wait_count from v$event_histogram where event='latch: shared pool';V$ACTIVE_SESSION_HISTORYASH核心视图,记录活动会话历史等待(10g+)select sid,event,sql_id,wait_time from v$active_session_history where sample_time>sysdate-1/24;高频等待事件分类诊断
1. I/O类等待(最常见)
等待事件参数含义(P1/P2/P3)可能原因优化建议db file sequential readfile#(文件号)/block#(块号)/blocks(块数)索引扫描低效、表连接顺序不合理检查索引有效性、调整连接驱动表、整理存储碎片db file scattered readfile#/block#/blocks全表扫描过多、缺少索引为过滤字段建索引、调整DB_FILE_MULTIBLOCK_READ_COUNT、优化SQL避免全表扫描direct path read/writefile#/first block#/block数磁盘排序、并行查询、大表全扫(11g+)增大PGA_AGGREGATE_TARGET、禁用不必要的并行查询、为大表建索引direct path read tempfile number/first dba/block cnt临时表空间磁盘排序拆分临时表空间、使用多个临时文件、优化SQL减少排序操作2. 日志类等待
等待事件参数含义可能原因优化建议log file syncbuffer#/sync SCN/NOT DEFINED提交过于频繁、LGWR写入缓慢批量提交、将 redo 日志移至RAID10磁盘、避免RAID5存储日志log file switch无固定参数(子事件区分)日志组过小、归档缓慢、检查点未完成增大日志文件大小、增加日志组、调整log_archive_max_processes参数log buffer space无关键参数redo log buffer过小、I/O瓶颈增大LOG_BUFFER、使用高速磁盘存储日志、分离日志文件与数据文件log file parallel writefiles/blocks/requests日志组成员过多、磁盘I/O竞争减少日志组成员、优化磁盘I/O分布、启用异步I/O3. 锁与闩锁类等待
等待事件参数含义可能原因优化建议enq: TX - row lock contention无固定参数并发更新冲突、长事务未提交缩短事务时长、避免同一行数据并发更新、使用FOR UPDATE SKIP LOCKEDenq: TM - contention无固定参数DML与DDL并行执行、表级锁竞争避免DDL在业务高峰期执行、优化DML语句减少锁持有时间latch freeaddress/number/process#闩锁竞争(Shared Pool/Library Cache)减少硬解析、绑定变量、增大SHARED_POOL_SIZE、优化SQL执行计划latch: cache buffers chainsaddress/number/try#热点块竞争、Buffer Cache低效拆分热点表、使用分区表、调整BUFFER_CACHE_SIZE4. 空闲类等待(无需优化)
等待事件说明SQL*Net message from client客户端未发送请求rdbms ipc message后台进程等待消息pmon timer/smon timer监控进程定时等待idle event会话空闲状态快速诊断流程(3步定位)
- 定位Top等待事件
select event,time_waited from (select event,sum(time_waited) as time_waited from v$system_event group by event) order by time_waited desc fetch first 5 rows only;
- 关联会话与SQL
先找等待会话:select sid from v$session_wait where event='db file scattered read';
再抓SQL语句:@getsqlbysid.sql(脚本内容:select sql_text from v$sqltext a where a.hash_value=(select sql_hash_value from v$session b where b.sid='&sid') order by piece asc;)
- 分析执行计划与优化
set autotrace trace explain; 执行问题SQL,查看是否全表扫描,按需创建索引或调整SQL。
版本特性差异
版本关键诊断特性核心工具/视图Oracle 9i基础等待事件、StatspackV$SESSION_WAIT、V$SYSTEM_EVENT、statspack.sqlOracle 10gASH/AWR、V$SESSION_WAIT_HISTORYashrpt.sql、awrrpt.sql、v$active_session_historyOracle 11g实时SQL监控、自适应直接读V$SQL_MONITOR、DBMS_SQLTUNE.REPORT_SQL_MONITOR常用诊断工具脚本
- ASH报告:@?/rdbms/admin/ashrpt.sql(支持TEXT/HTML格式)
- AWR报告:@?/rdbms/admin/awrrpt.sql(需指定快照ID)
- AWR比较报告:@?/rdbms/admin/awrddrpt.sql(对比两个时段性能)
- 实时SQL监控报告:select dbms_sqltune.report_sql_monitor(sql_id='xxx',type='HTML') from dual;
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |