Oracle杀不掉死锁进程(ORA-00031:标记要终止的会话)

***故事背景***:前几天遇到生产环境中Oracle新建用户,现场操作不当导致锁表了,现场反馈说杀不掉死锁的进程,于是我登录现场环境进行排场问题。
***排查问题***:远程现场使用PL/SQL Developer工具查看Oracle数据库死锁的情况。

1 查看哪些对象被锁

SELECT DISTINCT t2.username,t2.sid,t2.serial#,t2.logon_time

from v$locked_object t1,v$session t2

where t1.session_id=t2.sid order by t2.logon_time;

2发现确实出现死锁的情况,执行杀死锁线程的sql(输入SID参数,就是上一步查询出来 的SID)

select sql_text from v$session a,v$sqltext_with_newlines b where DECODE(a.sql_hash_value, 0, prev_hash_value, sql_hash_value)=b.hash_value
and a.sid=&sid order by piece;

3.杀死对应的进程(上述的sid与serial#参数传入)

  alter system kill session 'sid,serial#';

4 发现该进程无法杀掉,弹出 ORA-00031:标记要终止的会话 的提示框, 于是百度查询无法杀掉的进程只能上升到OS系统级别,在OS级别中杀死该进程

a. unix系统,以root身份执行以下命令

# kill -9 &spid(即第4步查询出来的进程号spid)

b. windows系统,打开cmd窗口,用orakill命令执行

语法为:orakill sid thread

sid: oracle实例名

thread 线程号,即第4步中的spid
(备注:重新查询是否存在死锁,若仍存在再执行一次操作3,再alter system kill session ‘sid,serial#’)

总结:一开始担心执行orakill sid thread,是会把oracle的数据库实例杀掉,导致整个数据库服务关了,所以有点没胆子,后来查询了
由于Windows自己没有提过一个专门用来Kill掉单个线程的工具,因此Oracle自己提供了一个基于字符界面的用来在Windows环境下强制Kill掉一个线程的工具――Orakill。

Oracle出现死锁进程无法杀掉的部分原因:
在Windows中如果使用alter system kill session 'sid,serial#'来清除会话,在执行之后该会话的状态会变为KILLED,但是有时候这个状态会保持很长时间,直到最后被清除。如果想更快地从内存中清理这个会话,那么可以在使用了alter system之后,再在Windows中使用Orakill实用程序(该程序随Oracle数据库同时安装)直接清除该会话的线程。

本文部分参考引用:https://www.jianshu.com/p/56a0ba571d62

你可能感兴趣的:(Oracle,oracle,数据库,java)