阻塞会话处理和死锁
程序员文章站
2022-03-03 20:03:31
...
阻塞会话处理和死锁
模拟实验:
模拟故障--会话被级联阻塞
准备工作:
我这里在每个实例开两个会话来模拟RAC在负载均衡模式下的业务会话:
实例1:会话1,会话2;
实例2:会话3,会话4;
在 时间点1 -> 时间点2 -> 时间点3 -> 时间点4 的这个时间轴上分别执行以下操作:
时间点1:
在实例1的会话1(INS1-session1)执行语句未提交或回滚:
select * from v$mystat where rownum = 1;update emp set sal = 8000 where empno = 7788;
时间点2:
在实例2的会话3(INS2-session3)执行语句:
select * from v$mystat where rownum = 1;
delete from emp where empno = 7839;
update emp set job = 'MANAGER' where empno = 7788;
rollback;
时间点3:
在实例2的会话4(INS2-session4)执行语句:
select * from v$mystat where rownum = 1;
update emp set sal = 15000 where empno = 7839;
rollback;
时间点4:
在实例1的会话2(INS1-session2)执行语句:
select * from v$mystat where rownum = 1;
update emp set job = 'CEO' where empno = 7839;
rollback;
处理方法:
立即找出最终阻塞会话
select *
from (select a.inst_id,
a.sid,
a.serial#,
a.sql_id,
a.event,
a.status,
connect_by_isleaf as isleaf,
sys_connect_by_path(a.SID || '@' || a.inst_id, ' <- ') tree,
level as tree_level
from gv$session a
start with a.blocking_session is not null
connect by (a.sid || '@' || a.inst_id) = prior
(a.blocking_session || '@' || a.blocking_instance))
where isleaf = 1
order by tree_level asc;
然后经过确认在对应节点杀掉此会话:
alter system kill session '68,313' immediate;
==================================================================================================================================
死锁
定义:当两个用户希望持有对方的资源时就会发生死锁,即两个用户互相等待对方释放时,oracle认定为产生了死锁。
在这种情况下,将以牺牲一个用户作为代价,另一个用户继续执行,牺牲的用户的事务将回滚。
起因:oracle死锁问题实际很少见,如有发生,基本都是不正确的程序设计造成的
oracle会自动发现死锁,选择代价最小的给予撤销
若死锁不能自动释放,需要手工kill session,步骤如下:
1、查看有没有死锁对象:
select 'alter system kill session ''' || sid || ',' || serial# || ''';' "Deadlock"
from v$session
where sid in (select sid from v$lock where block = 1);
2、查看导致死锁的sql
select s.sid, q.sql_text
from v$sql_text q, v$session s
where q.address = s.sql_address
and s.sid = &sid
order by piece;
3、查看谁锁了谁
select s1.username || '@' || s1.machine || ' ( SID=' || s1.sid ||
' ) is blocking ' || s2.username || ' ( SID=' || s2.sid || ' )' as blocking_status
from v$lock l1, v$session s1, v$lock l2, v$session s2
where s1.sid = l1.sid
and s2.sid = l2.sid
and l1.BLOCK = 1
and l2.request > 0
and l1.id1 = l2.id1
and l2.id2 = l2.id2;
或者还是用上面的脚本:
select *
from (select a.inst_id,
a.sid,
a.serial#,
a.sql_id,
a.event,
a.status,
connect_by_isleaf as isleaf,
sys_connect_by_path(a.SID || '@' || a.inst_id, ' <- ') tree,
level as tree_level
from gv$session a
start with a.blocking_session is not null
connect by (a.sid || '@' || a.inst_id) = prior
(a.blocking_session || '@' || a.blocking_instance))
where isleaf = 1
order by tree_level asc;
上一篇: 数据库SQL优化大总结
下一篇: 数据库查询优化总结
推荐阅读
-
利用sys.sysprocesses检查SqlServer的阻塞和死锁
-
利用sys.sysprocesses检查SqlServer的阻塞和死锁
-
sql server 2000阻塞和死锁问题的查看与解决方法
-
笔记-13-多线程 Thread方法 线程安全 生产者和消费者 死锁和阻塞 练习
-
处理java异步事件的阻塞和非阻塞方法分析
-
笔记-13-多线程 Thread方法 线程安全 生产者和消费者 死锁和阻塞 练习
-
查看、列-EBS后台取消死锁检查代码和取消死锁会话步骤---经验-by小雨
-
查看sql server 2000阻塞死锁并处理 转
-
EBS后台取消死锁检查代码和取消死锁会话步骤---经验
-
MSSQL 死锁和阻塞 查看事务