Oracle:彻底结束会话 ,彻底解锁
2010-03-23 23:38
351 查看
oracle会话被锁是经常的。但有时alter system kill session 'sid,serial#';并不能彻底的杀死会话。只能通过杀死Linux上对应的进程才行。 以前都是通过v$session里的logon_time,和ps -ef|grep oracle所列出的时间大约的定位进程。然后结束。本来想把这个写成日志。但有一个服务器存在了好几个前几天启动的进程(估计是我kill -9 weblogic进程产生的) ps -ef不能只能列出进程启动的日期,不能列出具体时间。 上网查到了2篇详细的解决方法。就转了过来: Oracle杀死死锁进程 先查看哪些表被锁住了:
如何杀死oracle死锁进程 1.查哪个过程被锁: 查V$DB_OBJECT_CACHE视图: SELECT * FROM V$DB_OBJECT_CACHE WHERE OWNER='过程的所属用户' AND CLOCKS!='0'; 2. 查是哪一个SID,通过SID可知道是哪个SESSION: 查V$ACCESS视图: SELECT * FROM V$ACCESS WHERE OWNER='过程的所属用户' AND NAME='刚才查到的过程名'; 3. 查出SID和SERIAL#: 查V$SESSION视图: SELECT SID,SERIAL#,PADDR FROM V$SESSION WHERE SID='刚才查到的SID'; 查V$PROCESS视图: SELECT SPID FROM V$PROCESS WHERE ADDR='刚才查到的PADDR'; 4. 杀进程: (1)先杀ORACLE进程: ALTER SYSTEM KILL SESSION '查出的SID,查出的SERIAL#'; (2)再杀操作系统进程: KILL -9 刚才查出的SPID或ORAKILL 刚才查出的SID 刚才查出的SPID。 Oracle的死锁 查询数据库死锁:
alter system kill session 'sid,serial#'; 一般情况可以解决数据库存在的死锁了,或通过session id 查到对应的操作系统进程,在Unix中杀掉操作系统的进程。
在Unix中:
1)查找死锁的进程:
alter system kill session ‘sid,serial#’; (其中sid=l.session_id) 3)如果还不能解决:
---------------------------------------------------------------------------------------------------------- 我们知道,在Oracle数据库中,可以通过kill session的方式来终止一个进程,其基本语法结构为: alter system kill session ''''sid,serial#'''' ; 被kill掉的session,状态会被标记为killed,Oracle会在该用户下一次touch时清除该进程. 我们发现当一个session被kill掉以后,lag管:/u业网育a网供M该session的paddr被修改,如果有多个session被kill,那么多个session 的paddr都被更改为相同的进程地址: SQL> select saddr,sid,serial#,paddr,username,status from v$session where username is not null; SADDR SID SERIAL# PADDR USERNAME STATUS -------- ---------- ---------- -------- ------------------------------ -------- 542E0E6C 11 314 542B70E8 EYGLE INACTIVE 542E5044 18 662 542B6D38 SYS ACTIVE SQL> alter system kill session ''''11,314''''; System altered. SQL> select saddr,sid,serial#,paddr,username,status from v$session where username is not null; SADDR SID SERIAL# PADDR USERNAME STATUS -------- ---------- ---------- -------- ------------------------------ -------- 542E0E6C 11 314 542D6BD4 EYGLE KILLED 542E5044 18 662 542B6D38 SYS ACTIVE SQL> select saddr,sid,serial#,paddr,username,status from v$session where username is not null; SADDR SID SERIAL# PADDR USERNAME STATUS -------- ---------- ---------- -------- ------------------------------ -------- 542E0E6C 11 314 542D6BD4 EYGLE KILLED 542E2AA4 14 397 542B7498 EQSP INACTIVE 542E5044 18 662 542B6D38 SYS ACTIVE SQL> alter system kill session ''''14,397''''; System altered. SQL> select saddr,sid,serial#,paddr,username,status from v$session where username is not null; SADDR SID SERIAL# PADDR USERNAME STATUS -------- ---------- ---------- -------- ------------------------------ -------- 542E0E6C 11 314 542D6BD4 EYGLE KILLED 542E2AA4 14 397 542D6BD4 EQSP KILLED 542E5044 18 662 542B6D38 SYS ACTIVE 在这种情况下,很多时候,c_件D?L~?/%j3Sd资源是无法释放的,我们需要查询spid,在操作系统级来kill这些进程. 但是由于此时v$session.paddr已经改变,我们无法通过v$session和v$process关联来获得spid 那还可以怎么办呢? 我们来看一下下面的查询: SQL> SELECT s.username,s.status, 2 x.ADDR,x.KSLLAPSC,x.KSLLAPSN,x.KSLLASPO,x.KSLLID1R,x.KSLLRTYP, 3 decode(bitand (x.ksuprflg,2),0,null,1) 4 FROM x$ksupr x,v$session s 5 WHERE s.paddr(+)=x.addr 6 and bitand(ksspaflg,1)!=0; USERNAME STATUS ADDR KSLLAPSC KSLLAPSN KSLLASPO KSLLID1R KS D ------------------------------ -------- -------- ---------- ---------- ------------ ---------- -- - 542B44A8 0 0 0 ACTIVE 542B4858 1 14 24069 0 1 ACTIVE 542B4C08 26 16 15901 0 1 ACTIVE 542B4FB8 7 46 24083 0 1 ACTIVE 542B5368 12 15 24081 0 1 ACTIVE 542B5718 15 46 24083 0 1 ACTIVE 542B5AC8 79 4 15923 0 1 ACTIVE 542B5E78 50 16 24085 0 1 ACTIVE 542B6228 754 15 24081 0 1 ACTIVE 542B65D8 1 14 24069 0 1 ACTIVE 542B6988 2 30 14571 0 1 USERNAME STATUS ADDR KSLLAPSC KSLLAPSN KSLLASPO KSLLID1R KS D ------------------------------ -------- -------- ---------- ---------- ------------ ---------- -- - SYS ACTIVE 542B6D38 2 8 24071 0 542B70E8 1 15 24081 195 EV 542B7498 1 15 24081 195 EV SYS INACTIVE 542B7848 0 0 0 SYS INACTIVE 542B7BF8 1 15 24081 195 EV 16 rows selected. 我们注意,红字标出的部分就是被Kill掉的进程的进程地址. 简化一点,其实就是如下概念:
ykGo管垠y国的n专u网k无D 现在我们获得了进程地址,就可以在v$process中找到spid,然后可以使用Kill或者orakill在系统级来杀掉这些进程. 实际上,我猜测: 当在Oracle中kill session以后, Oracle只是简单的把相关session的paddr 指向同一个虚拟地址. 此时v$process和v$session失去关联,进程就此中断. 然后Oracle就等待PMON去清除这些Session.所以通常等待一个被标记为Killed的Session退出需要花费很长的时间. 如果此时被Kill的process,重新尝试执行任务,那么马上会收到进程中断的提示,process退出,此时Oracle会立即启动PMON 来清除该session.这被作为一次异常中断处理. 本文出自 51CTO.COM技术博客 |
相关文章推荐
- Oracle:彻底结束会话 ,彻底解锁
- 【转】ORACLE快速彻底Kill掉的会话
- 【ORACLE 】查询被锁住的对象,并结束其会话
- ORACLE多会话同时锁表无法解锁解决办法
- ORACLE快速彻底Kill掉的会话,防止锁表
- oracle查询会话锁并解锁
- ORACLE快速彻底Kill掉的会话(转载)
- 如何彻底杀死Oracle会话
- ORACLE快速彻底Kill掉的会话
- ORACLE 查看用户会话,强制结束,并删除用户.
- ORACLE快速彻底Kill掉的会话
- ORACLE快速彻底Kill掉的会话
- ORACLE 查询被锁住的对象,并结束其会话的方法
- ORACLE 查询被锁住的对象,并结束其会话的方法
- Oracle的锁表与解锁
- Oracle用户密码修改及解锁
- oracle解锁scott用户
- oracle 死锁/解锁
- oracle解锁scott用户
- oracle 用户被锁定解锁方法