ASH查不到最近等待事件因采样非实时且内存视图V$ASH保留约1小时、重启清空,长期趋势才用DBA_HIST_ASH;db file scattered read高多因执行计划退化致全表扫描;enq: TX高说明正发生行锁等待,需查V$SESSION定位持锁者;ASH报告默认无SQL文本,需设sql_detail=>TRUE或立即查V$SQL。
ASH里查不到最近的等待事件?检查采样间隔和保留时间
oracle ash(active session history)不是实时日志,而是每秒从sga中采样一次活跃会话快照,且只保留有限时间(默认约1小时,受 _ash_size 和 db_keep_cache_size 等隐含参数影响)。如果响应慢的问题发生在5分钟前,但当前查 dba_hist_active_sess_history 却没数据,大概率是采样已老化被覆盖;此时应优先查 v$active_session_history(内存视图),它更及时,但重启实例即清空。
- 确认是否在查错视图:短时问题用
V$ACTIVE_SESSION_HISTORY,长期趋势才用DBA_HIST_ACTIVE_SESS_HISTORY - 检查保留时间:
SELECT trunc(sysdate - min(sample_time)), count(*) FROM v$active_session_history;可粗略估算内存中还剩多少分钟的数据 - 若经常“查不到”,考虑调大
MEMORY_TARGET或显式设置SGA_TARGET,避免 ASH buffer 被过度挤压
Top Wait Events 里 db file scattered read 高,真就是磁盘慢?
这个事件常被误读为“IO性能差”,但实际多由执行计划退化导致:比如本该走索引却走了全表扫描,或并行度失控引发大量物理读。尤其当 SQL 的 OBJECT_NAME 指向大表、且 SQL_ID 对应的执行计划中 ACCESS_PREDICATES 为空时,基本可判定是缺少有效过滤条件的全扫。
- 先关联
V$ACTIVE_SESSION_HISTORY和DBA_HIST_SQL_PLAN,看高等待 SQL 的实际访问路径 - 注意
db file scattered read的P1(file#)和P2(block#):若集中在少数几个数据文件,可能是这些文件所在磁盘组负载不均,而非整体IO瓶颈 - 对比
buffer_gets和disk_reads:若两者比值接近1,说明几乎没走缓存——不是IO慢,是SQL根本没设计好缓存友好性
为什么 enq: TX - row lock contention 在ASH里占比突增?
这不是锁等待的“结果”,而是阻塞发生的“现场”。ASH只记录正在等待的会话,所以看到这个事件高,说明有事务在等行锁,且等待时间已超过1秒(ASH采样阈值)。关键要定位谁在持锁、谁在等锁,而不是优化锁本身。
- 查持锁者:
SELECT blocking_session, blocking_session_serial#, event, sql_id FROM v$session WHERE blocking_session IS NOT NULL; - ASH里
SESSION_ID和BLOCKING_SESSION字段可能为空,因采样瞬时性;必须结合V$SESSION实时查 - 常见诱因:应用未提交/回滚的长事务、基于非唯一键的并发 UPDATE、触发器里隐式开启新事务
用 ASH_REPORT_TEXT 生成报告却看不到 SQL Text?
默认的 DBMS_WORKLOAD_REPOSITORY.ASH_REPORT_TEXT 不包含完整 SQL 文本,只显示 SQL_ID 和摘要。想看到真实语句,必须确保对应 SQL 还在共享池中,且调用时传入 sql_detail => TRUE 参数。否则即使报告里列出了 SQL_ID,你也只能靠 V$SQL 手动查——而很多问题 SQL 可能已老化出库。
- 安全做法:出问题时立即运行
SELECT sql_text FROM v$sql WHERE sql_id = 'xxx';,别等生成ASH报告再找 - 生成报告时加参数:
DBMS_WORKLOAD_REPOSITORY.ASH_REPORT_TEXT(..., sql_detail => TRUE) - 若
V$SQL查不到,检查是否启用了RESULT_CACHE或绑定变量窥探导致文本被截断;这时得靠V$SQL_BIND_CAPTURE拼凑逻辑
ASH分析本质是“抓现场”,不是“查日志”。所有结论都依赖采样时刻的会话状态,错过那个1秒,线索就断了。真正难的从来不是看懂 enq: TX 是什么,而是怎么在响应变慢的30秒内,把 V$ACTIVE_SESSION_HISTORY、V$SESSION、V$SQL 三张表连起来,压住那条正在拖垮系统的 SQL。


















