Oracle数据库进程死锁
这两天遇到在做数据同步的时候遇到一个问题,数据表被死锁,连表都无法删除,在网上找了各种各种帖子都无法解决,加了好几个Oracle数据群,无非不下面三种情况
- 通过SQL查找死锁进程的原因,找到对应的sid和serial#,然后利用alter system kill session 'sid,serial#'; 将对应的进程kill掉(注意:此方法适用绝大多是的进程死锁,但是我今天要说的这总是无法解决的)下面贴下此方法的具体处理步骤;
- 通过SQL语句查出死锁的表
1 select object_name, 2 session_id, 3 os_user_name, 4 oracle_username, 5 process, 6 locked_mode, 7 status 8 from v$locked_object l, all_objects a 9 where l.object_id = a.object_id;
- 查出死锁的进程
1 select s.username, 2 l.object_id, 3 l.session_id as sid, 4 s.serial#, 5 s.lockwait, 6 s.status, 7 s.machine, 8 s.program 9 from v$session s, v$locked_object l 10 where s.sid = l.session_id;
- 使用SQL语句kill掉死锁的进程
或者使用SQL语句
1 alter system kill session 'sid,serial#';
它等价于从操作系统杀掉进程。它有两个选项POST_TRANSACTION和IMMEDIATE, 其中POST_TRANSACTION表示等待事务完成后断开会话,IMMEDIATE表示中断会话,立即回滚事务。1 ALTER SYSTEM DISCONNECT SESSION 'sid,serial#' POST_TRANSACTION; 2 ALTER SYSTEM DISCONNECT SESSION 'sid,serial#' IMMEDIATE;
- 通过SQL语句查出死锁的表
- 使用SQL语句找到对应的操作系统进程SPID,然后kill掉,(注意:此方法有风险,如果误操作可能会引起数据库异常,一定一定要谨慎,建议由专业的DBA来操作)下面贴下此方法的具体处理步骤;
- 通过下面的SQL语句找到系统中的spid
1 SELECT s.inst_id, s.sid, s.serial#, p.spid, s.username, s.program 2 FROM gv$session s 3 JOIN gv$process p 4 ON p.addr = s.paddr 5 AND p.inst_id = s.inst_id 6 WHERE s.type != 'BACKGROUND' 7 and s.sid = 'sid';
-
然后Oracle数据库
- 通过下面的SQL语句找到系统中的spid
在Windows下用Orakill的使用方法如下:
Dos提示符下:>orakill sid thread
说明: sid Oracle的Sid号
thread Oracle的线程id号
在Linux系统下使用kill -9 oracle进程号
3. 重启数据库,如果有什么问题是不能解决的,那么重启吧(注意:如果是在线运行的数据库,请注意避免影响用户的使用,非常不建议这个方法)下面贴下此方法的具体处理步骤;
最后一起看看我遇到的问题吧,我遇到的问题是这样,在子数据库(20个下属企业)建立视图用于总部直接监控下属企业的数据是否异常,通过dblink将视图的数据上传至总部的数据库中,其中有个下属公司数据服务器异常的慢,导致在job执行同步时锁表,造成数据表查询速度缓慢,也无法删除数据表,总部的这个数据表直接锁死,数据库又运托管,利用2、3方法需要走流程很麻烦,利用1方法执行报错【ORA-00026: 丢失或无效的会话 ID】最后我按下面步骤解决的
1)、在总部数据库查到对应数据服务器对应的地址,并查出死锁的SQL语句(用于确认是哪个dblink导致的死锁),尝试通过1方法将对应的进程kill掉(结果是没有用的)
2)、在下属企业的数据库中根据服务器地址找到对应的会话这个会话kill掉
3)、返回总部的数据库查看之前死锁的进程,发现自动消失了
以上为个人观点,如有说的不对还请大家指正,我们共同进步

浙公网安备 33010602011771号