不能——ASH报告(ashrpt.sql)默认最小粒度为5分钟,强制向上取整,无法查到1分钟内的性能抖动;需直接查询v$active_session_history视图,按秒或半分钟分组定位瞬时热点。
ASH报告能查到1分钟内的性能抖动吗?
不能直接查到——ashrpt.sql 默认最小粒度是 5 分钟,哪怕你只选 2 分钟窗口,它也强制向上取整到最近的 5 分钟边界。这是 oracle 内部采样机制和报告聚合逻辑决定的,不是参数能绕过的。
真正能定位分钟级抖动的,是原始 v$active_session_history 视图本身,而不是报告脚本。
-
ashrpt.sql是汇总工具,不是实时探针;它把每秒采样一次的 ASH 数据按 5 分钟分桶统计,丢失了亚分钟级细节 - 如果你看到某分钟 CPU 突增,但在
ashrpt.sql报告里只显示“过去 5 分钟平均 CPU=15%”,那很可能抖动被平滑掉了 - 真实抖动常发生在几十秒内(比如大批量 INSERT 触发临时表空间争用),这种必须下钻到秒级原始记录
怎么从 v$active_session_history 查 1–2 分钟内的抖动?
绕过 ashrpt.sql,直接查视图,用时间范围 + 事件聚合定位热点:
- 确保
DBA_HIST_ACTIVE_SESS_HISTORY或实时v$active_session_history有足够保留(默认只保留 1 小时左右,可能已被覆盖) - 用
sample_time精确过滤,例如:SELECT TRUNC(sample_time, 'MI') ts_min, event, COUNT(*) cnt FROM v$active_session_history WHERE sample_time BETWEEN SYSDATE - 1/1440 AND SYSDATE -- 过去 1 分钟 GROUP BY TRUNC(sample_time, 'MI'), event ORDER BY cnt DESC;
- 注意
TRUNC(sample_time, 'MI')按分钟对齐,避免跨分钟聚合掩盖峰值;如果要查 30 秒级,改用TRUNC(sample_time, 'SS') + FLOOR(TO_NUMBER(TO_CHAR(sample_time, 'SS'))/30)*30/86400 - 别只看
event,加sql_id和session_state联合过滤,快速锁定是否是某个 SQL 的硬解析或 latch 争用
ashrpt.sql 为什么不能调小时间粒度?
因为它的底层逻辑依赖 DBMS_WORKLOAD_REPOSITORY.ASH_REPORT_TEXT,而这个包在构造时间桶时硬编码了最小粒度:5 分钟(即 300 秒)。传入更小的 duration 会被自动 round up。
- 尝试传入
duration => 60,实际执行时日志里会显示 “Duration adjusted to 300 seconds” - 即使你手动修改
ashrpt.sql中的参数,Oracle 11g+ 之后该函数已不接受小于 300 的值,会报错ORA-13773: duration must be at least 300 seconds - 这不是 bug,是设计取舍:ASH 报告面向容量规划与趋势分析,不是故障实时诊断
什么情况下必须放弃 ashrpt.sql 直接查 ASH?
当抖动持续时间短、影响范围小、但业务感知强时——比如支付接口偶发 2 秒超时,数据库端却没留下明显慢 SQL 或等待事件峰值。
- 典型场景:瞬时 log file sync 延迟飙升(
log file sync等待时间单次 > 500ms)、大量enq: TX - row lock contention在 30 秒内密集出现 - 关键动作:用
MIN(sample_time)和MAX(sample_time)定位抖动起止秒级时间点,再以该窗口为中心前后各扩 30 秒查原始记录 - 容易漏掉的点:
v$active_session_history默认只保留内存中最近 1 小时数据,若抖动发生在 1 小时前且未生成 AWR 快照,就彻底不可追溯——所以高敏系统建议配合自定义 ASH 归档脚本
事情说清了就结束。


















