直接用alter system set events触发ash dump最可靠,执行alter system set events 'immediate trace name ashdump level 10'可冻结内存中最近10分钟ash样本,再通过sed提取trace文件中的纯数据段,用sqlldr导入临时表进行深度分析。
直接用 alter system set events 触发 ash dump 最可靠
想把某个故障时刻(比如刚发生的 2 分钟卡顿)的 ash 样本完整保下来,不能只靠 ashrpt.sql 生成报告——它只输出聚合视图,原始采样点会丢。真正能“冻结”内存中 ash 缓冲区快照的,是 oracle 内部事件机制。
执行这条命令即可立即 dump 当前 ASH buffer 中最近 N 分钟的数据:
alter system set events 'immediate trace name ashdump level 10';
level 10 表示 dump 最近 10 分钟的样本(单位是分钟,不是秒)。注意:
– level 值不能超过 ASH 缓冲区实际保留时长(查 SELECT MIN(sample_time) FROM v$active_session_history; 可知最早时间)
– 必须用 sys 或具备 ALTER SYSTEM 权限的用户执行
– 执行后不会报错也不显式提示成功,但会在 trace 目录生成对应文件
定位并提取 dump 文件里的原始数据
dump 生成的 trace 文件默认在 v$diag_info 的 Default Trace File 路径下,但里面混着元信息、SQL*Loader 控制语句和真正的 ASH 行数据。直接读取不可靠,必须分离。
推荐做法是用 sed 提取中间的纯数据段(Linux/Unix):
sed -n '/^Step2:/,/^Step3:/p' /u01/app/oracle/diag/rdbms/ora11g/ora11g/trace/ora11g_ora_7556.trc | sed '1d;$d;/^-/d' > ash_data.raw
关键点:
– 不要用整个 trace 文件直接喂给 sqlldr,否则会因头部注释和分隔线报错
– ash_data.raw 是纯 tab 分隔的文本,每行对应一个 ASH 采样点
– Windows 下建议先用 WSL 或远程 Linux 提取,cmd/powershell 处理这种混合格式极容易乱码或截断
用 sqlldr 导入到临时表做深度分析
dump 出来的数据结构与 WRH$_ACTIVE_SESSION_HISTORY 基本一致,但字段顺序和空值表示不同。最稳妥的方式是建一个宽表接收,再清洗:
CREATE TABLE ashdump_raw ( sample_id NUMBER, sample_time DATE, session_id NUMBER, session_serial# NUMBER, sql_id VARCHAR2(13), event VARCHAR2(64), wait_class VARCHAR2(64), p1text VARCHAR2(64), p1 NUMBER, p2text VARCHAR2(64), p2 NUMBER, p3text VARCHAR2(64), p3 NUMBER, current_obj# NUMBER, sql_opname VARCHAR2(64) );
然后配 sqlldr 控制文件(.ctl),关键配置项:
– FIELDS TERMINATED BY X'09'(tab 分隔,不是空格)
– TRAILING NULLCOLS 必须启用,否则末尾空字段会导入失败
– DATE "MM/DD/YYYY HH24:MI:SS" 格式要和 trace 中的 sample_time 完全一致(例如 06/23/2026 23:45:12)
– 错误容忍设高些:errors=1000000
导出后别跳过验证和时间对齐
导入完成后,第一件事不是查 TOP SQL,而是确认数据时间范围和采样密度是否符合预期:
-
SELECT MIN(sample_time), MAX(sample_time), COUNT(*) FROM ashdump_raw;—— 看是否真覆盖了你想要的故障窗口 -
SELECT TRUNC(sample_time,'MI'), COUNT(*) FROM ashdump_raw GROUP BY TRUNC(sample_time,'MI') ORDER BY 1;—— 检查是否出现整分钟缺失(说明 ASH buffer 在那分钟被刷掉或没采到) - 对比
v$active_session_history同一时段的COUNT(*),若差异超过 20%,说明 dump 时 buffer 已被覆盖,数据不全
ASH dump 本质是内存快照的“尽力而为”拷贝,它不保证 100% 完整。真正难啃的点在于:故障时刻越短、系统越忙,ASH buffer 循环覆盖越快,dump 出来的样本越稀疏。所以 dump 动作一定要在现象发生后 30 秒内执行,拖过 2 分钟就大概率丢失关键帧。











