故障发生后应先查ASH内存数据(≤60分钟)再选AWR(>60分钟),55分钟时两者结合;ASH报告参数须注意时间格式、duration单位秒、report_type大小写;AWR重点关注DB Time、DB CPU、Physical reads三指标;故障恢复后立即备份v$active_session_history原始数据。

生产故障刚发生,别急着翻AWR报告——先确认ASH数据还在内存里,再决定用ASH还是AWR。Oracle 11g中,v$active_session_history只保留约60分钟的采样(实际取决于SGA压力),超过就只能从dba_hist_active_sess_history里捞,但后者是每10秒抽一次样,细节已丢失。
怎么判断该用ASH还是AWR
看故障发生时间距现在是否超过1小时:
- ≤60分钟:优先跑
@$ORACLE_HOME/rdbms/admin/ashrpt.sql,它能抓到每秒的会话状态、阻塞链、真实SQL执行堆栈 - >60分钟:ASH内存数据早被覆盖,必须用
@$ORACLE_HOME/rdbms/admin/awrrpt.sql,但得注意快照间隔默认是1小时——如果故障发生在9:23,而最近两个快照是9:00和10:00,那9:23的尖峰就会被平均掉 - 介于两者之间(比如故障在55分钟前):两个都跑,用ASH定位“哪几秒最卡”,再用AWR看那1小时内整体负载是否异常(比如DB Time突增但CPU没涨,大概率是I/O或锁等待)
执行ashrpt.sql时最容易填错的三个参数
ashrpt.sql交互式输入看着简单,但三个地方一错,报告就空或乱码:
-
begin_time必须是四位年份的绝对时间格式:07/27/2026 09:23:00(不是27/07/2026,也不是2026-07-27 09:23:00);相对时间如-45只在该字段留空时才生效 -
duration单位是秒,不是分钟——填300才是5分钟,填5只会输出5秒的采样,基本没信息 -
report_type输html后回车即可,但别输HTML或Html,大小写敏感,输错会静默回退到text模式且不提示
AWR报告里真正要盯住的三行数字
别一上来就翻TOP SQL。先看报告头部的Load Profile节里这三行:
-
DB Time(s):—— 整个时间段内所有会话“感觉”花了多少秒。如果远高于Elapsed Time(报告跨度秒数 × 实例数),说明严重排队,比如大量会话在等enq: TX - row lock contention -
DB CPU(s):—— 真正用在CPU上的时间。如果DB Time高但DB CPU低,问题一定出在等待事件(I/O、锁、网络) -
Physical reads:—— 每秒物理读次数。突然飙升且伴随db file sequential read等待,基本就是索引失效或执行计划走错导致全表扫
故障刚恢复,立刻备份ASH原始数据
内存里的v$active_session_history随时可能被新采样冲掉。只要故障结束,马上执行:
CREATE TABLE ash_backup_20260728 AS SELECT * FROM v$active_session_history WHERE sample_time >= SYSTIMESTAMP - INTERVAL '60' MINUTE;
然后导出:exp user/passwd tables=(ash_backup_20260728) file=ash_bak.dmp。这比生成HTML报告更可靠——HTML只是聚合视图,原始表里还能查blocking_session、sql_exec_start这些关键字段,后续做根因回溯时缺一不可。


















