关于kill session的分析
有朋友聊到了关于kill session时会话长时间没有释放,而这个小鱼一般是通过os级别的kill spid来释放session和process的,如果用oracle的kill session可能会遇见进程和会话长时间不释放,下面来做一点简单的剖析。 Session A环境: SQL> conn test/test Conn
有朋友聊到了关于kill session时会话长时间没有释放,而这个小鱼一般是通过os级别的kill spid来释放session和process的,如果用oracle的kill session可能会遇见进程和会话长时间不释放,下面来做一点简单的剖析。
Session A环境:
SQL> conn test/test
Connected.
SQL> select sid,serial#,paddr,status from v$session where sid=userenv('sid');
SID SERIAL# PADDR STATUS
---------- ---------- ---------------- --------
1147 6874 000000021A0D0A70 ACTIVE
Session B环境:
SQL> alter system kill session '1147,6874';
System altered.
SQL> select sid,serial#,paddr,status from v$session where sid=1147;
SID SERIAL# PADDR STATUS
---------- ---------- ---------------- --------
1147 6874 000000021A6A9020 KILLED
此时我们查看这个被killed的session只是将session的状态标记为killed,然后将paddr(session对应的服务器进程的地址)标记为一个虚拟的地址。
过了一段时间,我们还是在Session B环境查询被kill掉的会话,发觉这个会话依然是存在的。
SQL> select sid,serial#,paddr,status from v$session where sid=1147;
SID SERIAL# PADDR STATUS
---------- ---------- ---------------- --------
1147 6874 000000021A6A9020 KILLED
而如果我们重新在原来的session A环境做一些命令查询,此时会报出session被killed的提示
SQL> select sid,serial#,paddr,status from v$session where sid=userenv('sid');
select sid,serial#,paddr,status from v$session where sid=userenv('sid')
*
ERROR at line 1:
ORA-00028: your session has been killed
再次回到session B环境查询这个被killed的会话
SQL> select sid,serial#,paddr,status from v$session where sid=1147;
no rows selected
发现已经没有任何数据了,此时这个session对应的process也已经被pmon进程释放了。
记得小鱼处理过一个win的库,有好几百的session在报出相应的热点块现象,通过kill session后,过了很长时间所有的被killed掉session都没有释放掉,而这个可能出现的原因数据库负载太高了,pmon进程并没有去释放掉这些session,再就是在pmon进程释放之前,需要touch该session才会被pmon进程清除(这个touch的含义是必须有对该session做查询等请求递交给server端),一般建议还是通过os级别的kill来释放session和process。
那么如果我们已经在用kill session的方式killed session,但是进程依然不释放,此时我们想通过kill spid的方式来释放session和process。
SQL> select program,spid from v$process where addr in
2 (select p.addr from v$process p where p.pid
1
3 minus
4 select s.paddr from v$session s);
PROGRAM SPID
------------------------------------------------ ------------------------
oracle@dbserver (D000) 26520
oracle@dbserver (S000) 26522
oracle@dbserver (TNS V1-V3) 27932
可以通过上面的查询先查出两个视图中地址不一致的进程,这里需要注意不要kill掉系统的进程,比如这里我们就可以通过上面的查询手动kill -9 27932来释放这个session和对应的process。
SQL> !kill -9 27932
SQL> select sid,serial#,paddr,status from v$session where sid=1147;
no rows selected
此时即使我们不touch原来那个session,通过os kill的方式,sesison和process都已经马上释放了,个人也建议在维护生产环境中尽量通过os的方式来kill掉需要的session和process。
原文地址:关于kill session的分析, 感谢原作者分享。