Oracle无统一查询超时配置,超时定位依赖ASH及历史视图;查v$active_session_history可捕获实时超时会话,但内存仅保留约1小时数据,需用dba_hist_active_sess_history查历史,注意采样粒度与AWR快照有效性。
oracle 应用层没有统一的“查询超时”配置,超时行为实际由客户端驱动、网络层、数据库资源管理器(dbrm)或应用代码自身控制;直接查 v$active_session_history 是定位“已发生超时”的最可靠方式——因为超时本质是会话在等待或执行中被中断,而 ash 恰好记录了每秒的活动快照。
查不到超时会话?先确认 ASH 数据是否覆盖目标时段
ASH 内存缓冲区默认只保留约 1 小时活跃数据(受 SGA 分配和系统负载影响),高负载下可能仅剩几分钟。若你查的是昨天下午 3 点的慢查询,v$active_session_history 几乎肯定已覆盖,必须切到磁盘历史视图:
-
dba_hist_active_sess_history是唯一可查过去数天/周的来源,但采样粒度为 10 秒(v$active_session_history是 1 秒),丢失细节 - 执行前务必确认 AWR 快照已生成:运行
SELECT MIN(snap_id), MAX(snap_id) FROM dba_hist_snapshot WHERE end_interval_time > SYSDATE - 1; - 若目标时段无快照,
dba_hist_active_sess_history对应数据也为空——此时只能靠应用日志或数据库审计(unified_audit_trail)反推
识别“疑似超时”的会话行为特征
Oracle 不记录“超时”标记,但超时前常伴随特定等待模式。重点看 event 和持续时间组合:
-
SQL*Net message from client持续超 30 秒:客户端已断开,但会话未清理,常见于 JDBCsocketTimeout触发后服务端残留 -
enq: TX - row lock contention+sql_exec_start超 60 秒:事务卡在锁等待,应用层 timeout(如 Spring@Transactional(timeout=60))很可能已生效 -
library cache lock或row cache lock占比突增:硬解析风暴导致单条 SQL 执行延迟飙升,触发上层超时 - 同一
sql_id在v$active_session_history中连续出现多行,sample_time - sql_exec_start逐次增大:说明执行未完成且未被 cancel,极可能是客户端超时后重试或连接池未 close
关联 SQL 文本与执行堆栈要绕过权限和缓存陷阱
直接 join v$sqlarea 查 sql_text 常失败,原因很实际:
-
v$sqlarea只保留共享池中当前存在的 SQL,超时 SQL 若已被 aged out,sql_id对应行为空 - 普通用户默认无权查
v$sqlarea,但可查dba_hist_sqltext(需SELECT_CATALOG_ROLE) - 更稳的方式是用
dba_hist_active_sess_history关联dba_hist_sqltext,且加WHERE sql_id IS NOT NULL AND sql_id != '0000000000000000'过滤无效值 - 若需完整 SQL(含绑定变量值),必须启用 SQL Trace 或
DBMS_MONITOR.SESSION_TRACE_ENABLE,ASH 本身不存 bind values
别忽略 blocking_session 链式阻塞的隐性超时
一个会话超时,往往不是它自己慢,而是被上游阻塞。ASH 的 blocking_session 和 blocking_inst_id 是关键线索:
- 执行
SELECT * FROM v$active_session_history WHERE blocking_session IS NOT NULL AND sample_time > SYSTIMESTAMP - INTERVAL '5' MINUTE;快速抓出正在传播阻塞的源头 - 注意
blocking_session可能指向另一个已超时/僵死的会话,形成环状依赖(尤其在 PL/SQL 批处理中) -
blocking_hangchain_info字段(Oracle 12c+)能直接输出阻塞链路,比手工递归查v$session更准 - 如果阻塞源头是
enq: US - contention,说明 UNDO 不足,此时即使应用设了 30 秒 timeout,所有并发事务都会排队等 rollback segment,超时会集中爆发
真正难的不是查出哪条 SQL 超时,而是判断“超时”到底是客户端主动切断、数据库资源耗尽被动挂起、还是中间件连接池误判空闲连接——这三者在 ASH 里表现相似,但根因和修复路径完全不同。盯住 sample_time 与 sql_exec_start 的差值变化节奏,再结合应用侧的 error log 时间戳,才能把“超时”从现象锚定到具体环节。


















