查不到DBA_HIST_ACTIVE_SESS_HISTORY数据主因是AWR保留期限制(7–30天)和仅采样活跃会话(排除空闲等待),需先确认时间范围、权限、AWR启用状态及STATISTICS_LEVEL设置。

查不到数据?先确认时间范围和权限
直接 SELECT * FROM DBA_HIST_ACTIVE_SESS_HISTORY 很可能返回空或极少量记录,不是语句错,而是两个硬限制卡住了:一是默认只保留最近 7–30 天(取决于 AWR 保留策略),二是该视图只包含“活跃会话”采样——即正在 CPU 上执行或等待非空闲事件(Idle 类等待如 SQL*Net message from client 不计入)。你得先确认目标时段有无采样存档:
- 用
SELECT MIN(SAMPLE_TIME), MAX(SAMPLE_TIME) FROM DBA_HIST_ACTIVE_SESS_HISTORY看当前历史表覆盖的时间边界 - 检查是否具备
SELECT_CATALOG_ROLE或直接授予的SELECT权限——普通用户默认无权访问DBA_*视图 - 若连
MIN/MAX都查不出,说明 AWR 没启用,或STATISTICS_LEVEL被设为BASIC(必须为TYPICAL或ALL)
查特定用户的历史 SQL,别漏掉 JOIN 和 NULL 安全
想查 SCOTT 用户过去一小时干了什么?不能只靠 WHERE USERNAME = 'SCOTT',因为 DBA_HIST_ACTIVE_SESS_HISTORY 里压根没有 USERNAME 字段——只有 USER_ID。常见错误是写 SELECT USERNAME, SQL_ID FROM DBA_HIST_ACTIVE_SESS_HISTORY,立刻报 ORA-00904: "USERNAME": invalid identifier。
- 必须显式
JOIN dba_users:例如ON a.USER_ID = c.USER_ID,其中c.username = 'SCOTT' -
dba_users只含当前存在的用户;若目标用户已被删,JOIN结果为空,此时需改用DBA_HIST_USER(需额外诊断包许可) -
SQL_ID可能为NULL(如解析失败、递归调用、PL/SQL 匿名块),加AND a.SQL_ID IS NOT NULL可过滤掉噪声
死锁或高负载回溯?别直接查历史表,先锁住内存窗口
DBA_HIST_ACTIVE_SESS_HISTORY 的采样粒度是 10 秒(由 _ash_disk_filter_ratio 控制),而真实死锁常在 1 秒内发生并自动回滚。你查历史表大概率看到的是“单边等待”快照,互指关系已断裂。
- 第一步永远是查内存视图:
SELECT * FROM v$active_session_history WHERE sample_time > SYSDATE - 5/1440 AND event LIKE 'enq: TX%' - 重点看
blocking_session和session_id是否在相邻行形成闭环(A → B 且 B → A),这才是死锁铁证 - 拿到精确到秒的
SAMPLE_TIME和一对SESSION_ID后,再用它们作为条件去DBA_HIST_ACTIVE_SESS_HISTORY查上下文(比如执行了什么 SQL、在哪台机器、用了哪个模块)
导出分析?别用 exp 导视图,建表再导
exp 工具对视图无效——它只会导出视图定义,不是数据。生产库上想把某段时间的 ASH 数据搬去测试机分析,必须走中间表:
- 先创建实体表:
CREATE TABLE t_ash AS SELECT * FROM DBA_HIST_ACTIVE_SESS_HISTORY WHERE SAMPLE_TIME BETWEEN TO_TIMESTAMP('2026-10-25 10:00:00', 'YYYY-MM-DD HH24:MI:SS') AND TO_TIMESTAMP('2026-10-25 12:00:00', 'YYYY-MM-DD HH24:MI:SS') - 再用
exp导出该表:exp user/passwd file=t_ash.dmp tables=(t_ash) - 导入测试库后,记得在
ALTER SESSION SET NLS_TIMESTAMP_FORMAT='yyyy-mm-dd hh24:mi:ss.ff'下查,否则SAMPLE_TIME显示不全
真正容易被忽略的点是:历史表里的 blocking_session 在 Oracle 19c 以前版本不稳定,大量为 NULL 或 0;哪怕查到了值,也得交叉验证 blocking_session_serial# 和 event 是否匹配,否则可能是误报。


















