ash报告最小时间粒度为5分钟,无法查1分钟内抖动,因dbms_workload_repository.ash_report_text函数硬编码duration≥300秒;需直查v$active_session_history定位瞬时热点。
ash报告查不到1分钟内的抖动,这不是配置问题,是设计限制
不能——ashrpt.sql 默认最小时间粒度就是 5 分钟,哪怕你只选 1 分钟窗口,oracle 也会自动向上取整到最近的 5 分钟边界。这不是参数没设对,也不是权限或采样关闭,而是底层 dbms_workload_repository.ash_report_text 函数硬编码了最小 duration = 300 秒。传入 60 秒,日志里会明确写 “duration adjusted to 300 seconds”;强行改小还会触发 ora-13773: duration must be at least 300 seconds。
常见错误现象:
- 你在 14:23–14:24 看到监控突增,但
ashrpt.sql报告里对应时段(14:20–14:25)显示 CPU 平均只有 12%,完全看不出峰值 - 执行
@ashrpt.sql后输入begin_time=14:23、duration=60,结果报告覆盖的是 14:20–14:25,且提示 “Time range adjusted”
根本原因:ASH 报告不是实时探针,它是把每秒一次的原始 v$active_session_history 记录按 5 分钟分桶聚合后的汇总视图,亚分钟级细节必然被平滑掉。
真要查 30 秒–2 分钟抖动,必须绕过 ashreport,直查 v$active_session_history
定位瞬时热点唯一可靠的方式,是跳过 ashrpt.sql,直接查内存视图 v$active_session_history,用 sample_time 精确过滤 + 秒级或半分钟级分组。
实操建议:
- 先确认数据存在:
SELECT COUNT(*) FROM v$active_session_history WHERE sample_time > SYSDATE - 2/1440;(查最近 2 分钟) - 查分钟级热点(对齐到整分钟,避免跨分钟平均掩盖峰值):
SELECT TRUNC(sample_time,'MI') ts_min, event, COUNT(*) cnt<br>FROM v$active_session_history<br>WHERE sample_time BETWEEN SYSDATE - 1/1440 AND SYSDATE<br>GROUP BY TRUNC(sample_time,'MI'), event<br>ORDER BY cnt DESC;
- 查 30 秒级更细粒度(需手动计算):
TRUNC(sample_time, 'SS') + FLOOR(TO_NUMBER(TO_CHAR(sample_time, 'SS'))/30)*30/86400 - 别只看
event,加sql_id和session_state联合过滤,比如:WHERE event = 'enq: TX - row lock contention' AND session_state = 'WAITING',快速锁定是否是某条 SQL 引发的锁争用
ashrpt.sql 报告为空?先检查 v$active_session_history 是否真在采样
很多人跑出空报告,第一反应是脚本坏了,其实大概率是底层没采集到数据。ASH 依赖 statistics_level 必须为 TYPICAL 或 ALL;设成 BASIC 会彻底禁用 ASH 采样。
关键检查点:
- 查当前设置:
SELECT name, value FROM v$parameter WHERE name = 'statistics_level';—— 若为BASIC,立刻改回TYPICAL - 确认最近 5 分钟有无记录:
SELECT COUNT(*) FROM v$active_session_history WHERE sample_time > SYSDATE - 5/1440;—— 返回 0 就说明没采样 - 注意:
DBA_HIST_ACTIVE_SESS_HISTORY是 AWR 快照表,延迟至少 10 分钟,不能用于“实时”抖动诊断 - 隐含参数
_ash_sampling_interval若被调大(如设为 5000 毫秒),也会显著降低采样密度,但一般不建议动
用 PL/SQL 调用 ASH_REPORT_TEXT 实现自动化,但时间粒度仍不可小于 5 分钟
如果想绕过交互式 @ashrpt.sql,用脚本批量生成报告,得用 DBMS_WORKLOAD_REPOSITORY.ASH_REPORT_TEXT 或 ASH_REPORT_HTML 函数,传入 timestamp 类型的起止时间。
示例(生成 HTML 报告):
SELECT * FROM TABLE(<br> DBMS_WORKLOAD_REPOSITORY.ASH_REPORT_HTML(<br> l_dbid => 3424884828,<br> l_inst_num => 1,<br> l_start_time => TIMESTAMP '2026-05-15 14:20:00',<br> l_end_time => TIMESTAMP '2026-05-15 14:25:00'<br> )<br>);
注意:
- 这个函数依然受 5 分钟下限约束,
l_end_time - l_start_time小于 300 秒会被自动拉长 - 时间必须用
TIMESTAMP字面量或变量,不能用字符串拼接,否则报ORA-13772 - 输出是 CLOB,需用
spool或客户端工具导出为 .html 文件才能正常打开
真正棘手的从来不是怎么生成报告,而是意识到:当抖动持续时间短于 5 分钟,ashrpt.sql 就只是个背景参考,你得切到 v$active_session_history 的原始行级视角,否则永远在平均值里找峰值。











