ash比v$transaction更适合判断长事务影响,因其每秒采样活动会话,可捕获等待事件、阻塞链及sql执行上下文,而v$transaction仅提供静态事务信息且可能残留误判。
查长事务不能只看 v$transaction,它只告诉你“有事务”,但看不出它是否正在阻塞别人、有没有在等锁、是否已卡死。真正要评估影响,得靠 v$active_session_history(ash)——它能告诉你这个事务在过去几十秒内“干了什么”“等了什么”“被谁挡了路”。
为什么ASH比V$TRANSACTION更适合判断长事务影响
V$TRANSACTION 只存事务起始时间、回滚段使用量、状态等静态信息;而长事务的破坏力往往体现在运行中的行为:比如持续持有行锁、反复争抢 library cache、或卡在某个等待事件上不动。ASH每秒采样一次活动会话,天然适合捕捉这类动态阻塞链。
- 事务可能已提交,但
V$TRANSACTION还没清理干净(尤其 RAC 环境),导致误判 -
V$TRANSACTION不包含等待事件、blocking_session、SQL 执行计划等上下文,无法定位阻塞源头 - ASH 中若连续多条记录显示同一
session_id处于enq: TX - row lock contention或cursor: pin S wait on X,基本可断定该事务正在引发连锁阻塞
用ASH查长事务活跃度:必须加时间过滤和关键字段
直接 SELECT * FROM v$active_session_history 基本没用——默认保留约1小时数据,且混杂大量短会话噪音。重点不是“有没有长事务”,而是“有没有长事务正在造成活跃影响”。
- 立即排查时,强制加
WHERE sample_time > SYSDATE - 1/1440(过去1分钟),避免查到已被覆盖或过期的样本 - 必须同时查
session_id、blocking_session、final_blocking_session,三者缺一不可:前者是当前会话,后两者才能暴露级联阻塞(如 A → B → C) - 关注
event字段值,但别只筛enq: TX - row lock contention;SQL*Net message from client持续出现,说明应用端没发 commit,事务空挂;library cache lock则暗示 DDL 正在阻塞大量查询
结合V$SESSION和V$TRANSACTION交叉验证阻塞源头
ASH 能告诉你“谁在等”,但不保证“谁在持”。如果 blocking_session 为空,或 final_blocking_session 对应会话在 V$SESSION 中已为 INACTIVE,说明持锁者可能已退出,或根本没被采样到(比如锁持有时间
- 对 ASH 中高频出现的
session_id,执行:SELECT sid, serial#, username, status, sql_id, event, blocking_session FROM v$session WHERE sid = &sid - 查该会话关联的事务:
SELECT start_date, used_ublk, logon_time FROM v$transaction t JOIN v$session s ON t.ses_addr = s.saddr WHERE s.sid = &sid - 若
sql_id为空但program是oracle@host (J000),大概率是 job 在跑未提交的 PL/SQL;若machine是应用服务器名,就得立刻联系开发确认业务逻辑是否漏了 commit
容易被忽略的两个关键点
一是 V$ACTIVE_SESSION_HISTORY 默认不采集 ON CPU 状态为 WAITING 但 event 为 NULL 的会话——这类往往是硬解析卡住或递归调用陷入死循环,得靠 V$SESSION 的 state 和 sql_id 结合 V$SQL 的 parse_calls 和 executions 比值来识别;二是 final_blocking_session 在 Oracle 12c 之前不可靠,低版本必须手动顺着 blocking_session 逐层查,否则会漏掉中间阻塞节点。











