确认连接数是否过高应先查V$SESSION和V$PROCESS实时快照,对比PROCESSES参数上限;活跃会话长期超70%才需深入,否则可能是短连接激增;ASH用于定位资源争用,非统计连接数。
如何确认当前连接数是否真的过高
别急着查ash,先看 v$session 和 v$process 的实时快照。连接数“多”是相对的——和 processes 参数上限比,而不是和昨天比。执行:
select count(*) from v$session where status = 'active';<br>select value from v$parameter where name = 'processes';如果活跃会话长期超过上限的 70%,才值得深入;否则可能是短连接激增(如应用未复用连接),这时查ash反而干扰判断。
ASH里该查哪些字段定位并发瓶颈
ASH(V$ACTIVE_SESSION_HISTORY)不是用来数连接数的,而是看“谁在抢资源”。重点盯三个字段:
-
SESSION_ID+SESSION_SERIAL#:组合唯一标识会话,避免把同一会话的多次采样当多个连接 -
EVENT:比如大量出现enq: TX - row lock contention或db file sequential read,说明是锁或IO拖慢了会话响应,导致连接堆积 -
SQL_ID:关联V$SQL查具体语句,注意ELAPSED_TIME和EXECUTIONS比值——高耗时低执行频次的SQL容易卡住连接
COUNT(*) GROUP BY SAMPLE_TIME,那只是画了个“连接数曲线”,没解决任何问题。为什么直接查ASH可能漏掉关键会话
ASH每秒采样一次,且只保留最近 1 小时(默认),两个硬限制导致它天然丢失信息:
- 持续时间
- 已断开但未清理的会话(
STATUS = 'INACTIVE'且LOGON_TIME很老)不会进ASH,却仍占着PROCESSES配额 - 如果数据库启用了
_ash_sampling_mode=0(罕见但存在),ASH会退化为仅采样前台会话,后台进程类连接完全不可见
V$SESSION 看全量状态、V$SESSION_CONNECT_INFO 看协议和客户端IP、操作系统级 netstat -an | grep :1521 | wc -l 看真实TCP连接数。怎样用ASH识别连接泄漏而非临时高峰
连接泄漏的核心特征是:会话存活时间长 + 活动度低 + 客户端不变。在ASH中这样筛:
SELECT SESSION_ID, SESSION_SERIAL#, MAX(SAMPLE_TIME) - MIN(SAMPLE_TIME) AS DURATION,<br> COUNT(*) AS SAMPLES, MAX(SQL_ID) AS LAST_SQL<br>FROM V$ACTIVE_SESSION_HISTORY<br>WHERE SESSION_ID IN (<br> SELECT SID FROM V$SESSION<br> WHERE STATUS = 'INACTIVE' AND LAST_CALL_ET > 3600<br>)<br>GROUP BY SESSION_ID, SESSION_SERIAL#<br>HAVING COUNT(*) < 5 AND MAX(SAMPLE_TIME) - MIN(SAMPLE_TIME) > INTERVAL '30' MINUTE;这个查询找的是“挂了1小时以上、但过去30分钟只被采到不到5次”的会话——典型泄漏迹象。再结合
V$SESSION.CLIENT_IDENTIFIER 或 PROGRAM 字段,基本能定位到哪个应用模块没关连接。
ASH是显微镜,不是温度计。它擅长看“正在发生什么”,但看不出“为什么连不上”或“连接为何不释放”。真要诊断连接数问题,得从网络层、应用连接池配置、Oracle服务端参数三层往下挖,ASH只是中间那一层的放大细节。


















