在实际的数据库应用中,我们经常遇到这样一个问题,连接到Oracle数据库的用户在作了一次操作后,再也没有后续操作,但却长时间没有和数据库断开连接。最近在研究一个中间件到数据库中的长连接异常问题,查询到v$session中LAST_CALL_ET参数,觉得这个参数很有用,下面是自己的一点理解:
1. 参数定义
LOGON_TIME 是一个日期型(Date)字段,为用户登陆时间;
LAST_CALL_ET是一个数字型(Number)字段,其含义是用户最后一条语句执行完毕后到sysdate的时间,单位为秒。每次用户执行一个新的语句后,该字段复位为0,重新开始记数。我们可以通过该字段来获得一个连接用户最后一次操作数据库后的空闲时间。
针对这两个参数定义的测试:
SQL> conn system/oracle@devdb2;
已连接。
SQL> select ses.SID,ses.username,ses.machine,ses.program,ses.last_call_et,sql.hash_value,sql.sql_text
from v$session ses, v$sql sql
where ses.sql_hash_value = sql.hash_value(+)
and ses.PROGRAM = 'sqlplus.exe'
SID | USERNAME | MACHINE | PROGRAM | LAST_CALL_ET | HASH_VALUE | SQL_TEXT |
132 | SYSTEM | ZDC\BEILEI | sqlplus.exe | 3(登陆后的时间) |
SQL> select count(*) from user_object_size;
SID | USERNAME | MACHINE | PROGRAM | LAST_CALL_ET | HASH_VALUE | SQL_TEXT |
132 | SYSTEM | ZDC\BEILEI | sqlplus.exe | 24(sql执行的时间) | 178228611 | select count(*) from user_object_size |
SQL> select count(*) from user_object_size;
COUNT(*)
----------
20
SID | USERNAME | MACHINE | PROGRAM | LAST_CALL_ET | HASH_VALUE | SQL_TEXT |
132 | SYSTEM | ZDC\BEILEI | sqlplus.exe | 1(sql执行完,参数复位0,重新开始计算到sysdate的时间/s) |
2. 识别超过一定空闲时间的连接
select username,logon_time,last_call_et,
to_char(sysdate-(last_call_et/(60*60*24)),'hh24:mi:ss') last_work_time
from v$session
where username is not null;
select ses.username,ses.machine,ses.program,ses.last_call_et,sql.hash_value,sql.sql_text
from v$session ses, v$sql sql
where ses.sql_hash_value = sql.hash_value
and ses.last_call_et > 600
and ses.type = 'USER'
SELECT s.username 用户名称, s.status 状态,s.machine 机器名称,
osuser 操作系统用户名称,spid UNIX进程号,
'kill -9 '||spid UNIX级断开连接,
'alter system kill session ' ||''''||s.sid||',
'||s.serial# || ''';' Oracle级断开连接,
TO_CHAR (logon_time, 'dd/mm/yyyy hh24:mi:ss') 登陆时间,
last_call_et 空闲时间秒,
TO_CHAR (TRUNC (last_call_et / 3600, 0))||' '||' HRS '||
TO_CHAR (TRUNC ((last_call_et - TRUNC(last_call_et / 3600, 0) * 3600) / 60, 0) ) ||' MINS' 空闲时间小时分钟,
module 模块
FROM v$session s, v$process p
WHERE TYPE = 'USER'
AND p.addr = s.paddr
AND status != 'KILLED'
-- AND SUBSTR (machine, 1, 19) NOT IN ('机器名')
AND last_call_et > 60 * 60 * 1-- 空闲时间超过1小时的连接
ORDER BY last_call_et desc;
select sid,username,status,
to_char(logon_time,'dd-mm-yy hh:mi:ss') "LOGON",
floor(last_call_et/3600)||':'||
floor(mod(last_call_et,3600)/60)||':'||
mod(mod(last_call_et,3600),60) "IDLE",
program
from v_$session
where type='USER'
order by last_call_et;
select s.process, s.sid, t.sql_text
from gv$session s, gv$sql t
where s.sql_address =t.address
and s.sql_hash_value =t.hash_value
--and s.program like '%JDBC%'
and s.last_call_et > 600
and s.status = 'ACTIVE'
个人认为还是查清楚这些异常连接的原因,不要轻易的kill掉这些会话。
参考文献:http://www.weste.net/2006/8-7/11352794038.html
Subject: | Removing Sessions in Killed Status on Unix | |||
Doc ID: | 274216.1 | Type: | BULLETIN | |
Modified Date : | 11-NOV-2008 | Status: | PUBLISHED |
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9252210/viewspace-594290/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/9252210/viewspace-594290/