查不到凌晨ASH数据主因是statistics_level设为BASIC导致未采样,需改TYPICAL/ALL并重启;ASH内存仅存约1小时样本,查凌晨卡顿须用精确时间范围过滤,避免相对时间表达式,并结合final_blocking_session等字段分析阻塞链。
查不到凌晨卡顿时的ASH数据?先确认采样是否真在运行
ash报告为空,大概率不是报告脚本问题,而是底层根本没采集到数据。oracle默认每秒采样一次,但这个行为被statistics_level参数严格控制:设为basic时,v$active_session_history完全不写入任何记录。
实操建议:
- 立即检查:
SELECT name, value FROM v$parameter WHERE name = 'statistics_level';—— 若返回BASIC,需改为TYPICAL或ALL并重启实例 - 验证最近5分钟是否有样本:
SELECT COUNT(*) FROM v$active_session_history WHERE sample_time > SYSDATE - 5/1440;—— 返回0就说明采样停摆 - 别依赖
dba_hist_active_sess_history查凌晨问题:它默认每10秒归档一次,且依赖AWR快照(通常每小时1次),凌晨若无快照,该表可能完全空白
想定位凌晨3:22那波卡顿?时间范围必须手动对齐
ASH内存只保留约1小时活跃样本(实际受_ash_size和负载影响),而磁盘上的dba_hist_active_sess_history又存在延迟和稀疏性。所以“凌晨卡顿”这种非连续、低频事件,必须靠人工缩小时间窗口,否则容易漏掉关键片段。
实操建议:
- 用
sample_time精确过滤:WHERE sample_time BETWEEN TIMESTAMP '2026-04-29 03:20:00' AND TIMESTAMP '2026-04-29 03:25:00' - 避免用
SYSDATE - 1/24这类相对表达式——凌晨时段SYSDATE是当天上午,减1小时会跨到前一天,逻辑错乱 - 如果卡顿发生在刚过整点(如3:00:03),注意AWR快照常在整点触发,
MMON进程可能正在刷库,导致ASH缓冲区短暂抖动,此时v$active_session_history行数骤降属正常现象
ASH里看到大量enq: TX - row lock contention,但blocking_session为空?
这很常见——ASH捕获的是“等待瞬间”,而持锁会话可能已在采样间隔内提交、回滚,或根本未被采样(比如锁持有仅300ms)。单看event字段会误判阻塞源。
实操建议:
- 必须连查三列:
session_id,blocking_session,final_blocking_session—— 后者在12c+才稳定可用,能穿透级联阻塞链(A→B→C) - 执行:
SELECT session_id, blocking_session, final_blocking_session, sql_id, event, p1text, p1 FROM v$active_session_history WHERE event = 'enq: TX - row lock contention' AND sample_time BETWEEN TIMESTAMP '2026-04-29 03:20:00' AND TIMESTAMP '2026-04-29 03:25:00' ORDER BY sample_time DESC; - 若
final_blocking_session有值但blocking_session为空,说明阻塞已传递多层;立刻查该final_blocking_session在v$session中的status、sql_id和last_call_et,确认是否仍在运行
@ashrpt.sql跑出空报告?别硬传参,改用PL/SQL直取
@?/rdbms/admin/ashrpt.sql是交互式脚本,不接受命令行时间参数。强行传参会导致SQL*Plus卡在第一个提示符,后续全乱,报告自然为空。
实操建议:
- 临时诊断用交互方式:启动后依次输入
text、实例号(通常1)、起止时间(格式严格为DD-MON-YYYY HH24:MI,如29-APR-2026 03:20) - 自动化需求必须用PL/SQL:
DBMS_WORKLOAD_REPOSITORY.ASH_REPORT_TEXT函数,传入l_start_time和l_end_time两个TIMESTAMP变量,绕过所有交互陷阱 - HTML报告中“Top SQL with Top Events”里SQL_ID不可点击?说明该SQL已老化出共享池,不能直接看执行计划——得结合
v$sqlarea查last_active_time和executions反推是否真在凌晨执行过
真正难的不是查ASH,而是把零散采样点串成因果链:一个TX锁可能由凌晨的批处理JOB隐式触发,而JOB又依赖前序ETL未完成,这种跨组件依赖,ASH只给切片,不给上下文。得拿module、action、client_identifier去对齐应用日志,才能闭环。


















