AWR报告中最该先看Top 5 Timed Events,它按消耗数据库时间最多排序前5等待事件,重点看%DB time、total waits和Avg wait (ms)三列,结合后续SQL、对象及RAC特性定位根因。
怎么看Top 5 Timed Events里的等待事件
awr报告里最该先看的,就是 top 5 timed events 这一节。它不是罗列所有等待,而是按“消耗数据库时间最多”排序的前5个事件——直接告诉你瓶颈在哪。
重点看三列:%DB time(占比)、total waits(总次数)、Avg wait (ms)(平均单次等待时长)。比如 db file sequential read 占比35%,但平均只有4ms,说明是高频小IO;而 log file sync 占比8%但平均896μs且总次数超140万,说明提交太密集,得查应用是否频繁 COMMIT。
- 若
direct path read排前三,别急着调磁盘,先查是不是SQL在大量排序或Hash Join——看SQL ordered by Gets和SQL ordered by Reads对应的语句 -
row cache lock高通常指向序列争用,尤其在RAC环境;立刻查dba_sequences里CACHE值是否为1(即无缓存) -
enq: TX - row lock contention出现,说明有行级锁阻塞,结合Segments by Row Lock Waits定位具体表和索引
如何定位等待事件发生的对象和SQL
光知道事件名没用,得知道“谁在等、等什么、为什么等”。AWR本身不带实时会话堆栈,但提供了两层下钻路径:
第一层:看 Foreground Wait Events 下的子节,比如 Wait Event Histogram 会分档显示等待时长分布(64ms~2s、4s~2min),帮你判断是偶发抖动还是持续卡顿;Service Statistics 能看出哪个服务名(如 APPS 或 OLTP)贡献了主要等待。
第二层:跳转到 SQL ordered by Elapsed Time 或 SQL ordered by CPU Time,把高耗时SQL的 SQL_ID 拿出来,用 SELECT * FROM dba_hist_sqltext WHERE sql_id = 'xxx'; 查原始语句;再用 SELECT * FROM dba_hist_active_sess_history WHERE sql_id = 'xxx' AND event IS NOT NULL; 看它实际触发了哪些等待事件。
- 注意:AWR默认只保留8天数据,如果问题发生在9天前,
dba_hist_active_sess_history可能已清理,优先用最近的快照对比 - 如果SQL_ID在AWR里查不到文本,可能是被设置了
optimizer_capture_sql_plan_baselines=FALSE或语句被自动重写,此时要查v$sql实时视图补位
row cache lock为什么总在RAC里爆发
这不是磁盘或内存问题,是RAC节点间争用 SEQ$ 表导致的典型现象。每次调用无缓存序列(CACHE 1),Oracle必须更新数据字典基表 seq$ 并加 row cache lock,而该锁在RAC中需跨节点协调,延迟陡增。
验证方式很简单:SELECT sequence_name, cache_size, order_flag FROM dba_sequences WHERE sequence_name = 'XXX'; 如果 cache_size = 1 且业务并发高,基本就是它。
- 修复命令:
ALTER SEQUENCE xxx CACHE 100 NOORDER;——NOORDER是关键,避免RAC节点间序列号排序同步开销 - 不要设
ORDER,除非业务真需要严格递增(比如发票号),否则性能损失可达30%以上 - 缓存值不是越大越好:
CACHE 1000在单节点没问题,但在RAC里可能造成某节点重启后序列号跳变过大,建议从100起步,观察dba_hist_sysstat中sequences requested的每秒速率再调整
log file sync 等待高,真的是磁盘慢吗
不一定。这个事件本质是“用户进程在等LGWR把redo buffer刷到磁盘”,但瓶颈可能在三个地方:存储写入慢、redo buffer太小导致LGWR频繁唤醒、或者应用提交太碎。
先看 Instance Efficiency Percentages 里的 Redo log space requests,如果非零,说明 log_buffer 不够用;再看 Load Profile 的 Logons per sec 和 Executes per sec,如果后者远高于前者,大概率是应用在循环里反复 INSERT + COMMIT。
- 紧急缓解:临时增大
log_buffer(需重启实例),或用COMMIT WRITE BATCH NOWAIT降低提交同步等待 - 长期方案:让应用批量提交(比如每100条
INSERT后一次COMMIT),比调存储更有效 - 注意:如果存储确实慢,
log file parallel write的平均等待时长也会同步升高,这时才需要查ASM磁盘组I/O或存储队列深度
AWR报告里真正难的是把孤立指标串成因果链:一个 direct path read 高,可能源于执行计划退化;一个 gc cr block lost 高,未必是网络问题,可能是某个节点CPU满载导致GC响应延迟。别只盯着数字大小,先问“这个值为什么变,变之前发生了什么”。


















