oracle 死锁快速定位死锁会导致内存溢出吗

博客分类:
一,删除和更新之间引起的死锁
造成死锁的原因就是多个线程或进程对同一个资源的争抢或相互依赖。这里列举一个对同一个资源的争抢造成死锁的实例。
Oracle 10g, PL/SQL version 9.2
CREATE TABLE testLock(
ID NUMBER,
test VARCHAR(100)
INSERT INTO testLock VALUES(1,'test1');
INSERT INTO testLock VALUES(2,'test2');
SELECT * FROM testLock
死锁现象的重现:
1)在sql 窗口 执行:SELECT * FROM testLock FOR UPDATE; -- 加行级锁 并对内容进行修改,不要提交
2)另开一个command窗口,执行:delete from testLock WHERE ID=1;
此时发生死锁(注意此时要另开一个窗口,不然会提示:POST THE CHANGE RECORD TO THE DATABASE. 点yes 后强制commit):
3)死锁查看:
select s.username,l.object_id, l.session_id,s.serial#, s.lockwait,s.status,s.machine,s.program from v$session s,v$locked_object l where s.sid = l.session_&/p&&p&USERNAME
SESSION_ID
LOCKWAIT STATUS
INACTIVE WORKGROUP\J-THINK
PLSQLDev.exe
WORKGROUP\J-THINK
PLSQLDev.exe
字段说明: Username:死锁语句所用的数据库用户; SID: session identifier, session 标示符,session 是通信双方从开始通信到通信结束期间的一个上下文。 SERIAL#: sid 会重用,但是同一个sid被重用时,serial#会增加,不会重复。 Lockwait:可以通过这个字段查询出当前正在等待的锁的相关信息。 Status:用来判断session状态。Active:正执行SQL语句。Inactive:等待操作。Killed:被标注为删除。 Machine: 死锁语句所在的机器。 Program: 产生死锁的语句主要来自哪个应用程序。
4)查看引起死锁的语句:
select sql_text from v$sql where hash_value in
(select sql_hash_value from v$session where sid in
(select session_id from v$locked_object));
delete from testLock where
5)死锁的处理:
SQL& alter system kill session '144,145';
System altered
Executed in 1.061 seconds
此时在执行delete语句的窗口出现:
SQL& delete from testLock where
delete from testLock where
ORA-00028: 您的会话己被终止
再查看一下死锁,会发现已经没有stauts为active的记录了:
select s.username, l.session_id,s.serial#, s.lockwait,s.status,s.machine,s.program from v$session s,v$locked_object l where s.sid = l.session_
SESSION_ID SERIAL#
LOCKWAIT STATUS
INACTIVE WORKGROUP\J-THINK
PLSQLDev.exe
Executed in 0.032 seconds
发生死锁的语句已经被终止。
二,在外键上没有加索引引起的死锁
客户的10.2.0.4 RAC for 环境频繁出现ORA-60死锁问题,导致应用程序无法顺利执行。 经过一系列的诊断,发现最终问题是由于外键上没有建立索引所致,由于程序在主子表上删除数据,缺少索引导致行级锁升级为表级锁,最终导致大量的锁等待和死锁。 下面通过一个例子简单模拟一下问题: SQL& create table t_p (id number primary key, name varchar2(30)); Table created. SQL& create table t_f (fid number, f_name varchar2(30), foreign key (fid) references t_p); Table created. SQL& insert into t_p values (1, 'a'); 1 row created. SQL& insert into t_f values (1, 'a'); 1 row created. SQL& insert into t_p values (2, 'b'); 1 row created. SQL& insert into t_f values (2, 'c'); 1 row created. SQL& Commit complete. SQL& delete t_f where fid = 2; 1 row deleted. 这时在会话2同样对子表进行删除: SQL2& delete t_f where fid = 1; 1 row deleted. 回到会话1执行主表的删除: SQL& delete t_p where id = 2; 会话被锁,回到会话2执行主表的删除: SQL2& delete t_p where id = 1; 会话同样被锁,这时会话1的语句被回滚,出现ORA-60死锁错误: delete t_p where id = 2 * ERROR at line 1: ORA-00060: deadlock detected while waiting for resource SQL& Rollback complete. 将会话1操作回滚,会话2同样回滚并建立外键列上的索引: 1 row deleted. SQL2& Rollback complete. SQL2& create index ind_t_f_fid on t_f(fid); Index created. 重复上面的步骤会话1删除子表记录: SQL& delete t_f where fid = 2; 1 row deleted. 会话2删除子表记录: SQL2& delete t_f where fid = 1; 1 row deleted. 会话1删除主表记录: SQL& delete t_p where id = 2; 1 row deleted. 会话2删除主表记录: SQL& delete t_p where id = 1; 1 row deleted. 所有的删除操作都可以成功执行,关于两种情况下锁信息的不同这里就不深入分析了,重点就是在外键列上建立索引。 虽然有一些文章提到过,如果满足某些情况,可以不在外键列上建立的索引,但是我的观点一向是,既然创建了外键,就不要在乎再多一个索引,因为一个索引所增加的代价,与缺失这个索引所带来的问题相比,是微不足道的。
【补充】Oracle 10g和Oracle 9i trc日志内容的差别 最主要的差别是在Oracle 10g中提示了等待资源的两条sql语句,在Oracle 9i中,只显示检测到死锁的sql语句 Oracle 10g 10.2.0.3.0:
DEADLOCK DETECTED ( ORA-00060 )
[Transaction Deadlock]
The following deadlock is not an ORACLE error. It is a
deadlock due to user error in the design of an application
or from issuing incorrect ad-hoc SQL. The following
information may aid in determining the deadlock:
Deadlock graph:
---------Blocker(s)--------
---------Waiter(s)---------
Resource Name
process session holds waits
process session holds waits
session 146: DID 000008 session 148: DID 000006
session 148: DID 000006 session 146: DID 000008
Rows waited on:
Session 148: no row
Session 146: no row
Information on the OTHER waiting sessions:
Session 148:
pid=17 serial=39 audsid=540046 user: 54/SCOTT
O/S info: user: SKYHOME\sky, term: SKYHOME, ospid: , machine: WORKGROUP\SKYHOME
program: plsqldev.exe
application name: PL/SQL Developer, hash value=
action name: Command Window - New, hash value=
Current SQL Statement:
delete t_p where id = 1
End of information on OTHER waiting sessions.
Current SQL statement for this session:
delete t_p where id = 2
Oracle 9i 9.2.0.7.0:
DEADLOCK DETECTED
Current SQL statement for this session:
delete t_p where id = 2
The following deadlock is not an ORACLE error. It is a
deadlock due to user error in the design of an application
or from issuing incorrect ad-hoc SQL. The following
information may aid in determining the deadlock:
Deadlock graph:
---------Blocker(s)--------
---------Waiter(s)---------
Resource Name
process session holds waits
process session holds waits
session 51: DID 00043D session 20: DID 000397
session 20: DID 000397 session 51: DID 00043D
Rows waited on:
Session 20: no row
Session 51: no row
Information on the OTHER waiting sessions:
Session 20:
pid=23 serial=53179 audsid=197296 user: 87/scott
O/S info: user: sky, term: SKYHOME, ospid: , machine: WORKGROUP\SKYHOME
program: plsqldev.exe
client info: 127.0.0.1
application name: PL/SQL Developer, hash value=
action name: Command Window - New, hash value=
Current SQL Statement:
delete t_p where id = 1
End of information on OTHER waiting sessions.
三,两个表之前不同顺序之间的相互更新操作引起的死锁
Oracle中的死锁:
注:4个update语句的执行顺序按图中位置自上而下 图中左边会话中断(此时不回滚也不提交,等待用户决定),右边会话阻塞,等待左边会话释放a表上的锁。如图:
死锁解决方法:
修改应用!参考以下方法。 1、将死锁减至最少 虽然不能完全避免死锁,但可以使死锁的数量减至最少。将死锁减至最少可以增加事务的吞吐量并减少系统开销,因为只有很少的事务:
? 回滚,而回滚会取消事务执行的所有工作。 ? 由于死锁时回滚而由应用程序重新提交。
下列方法有助于最大限度地降低死锁:
? 按同一顺序访问对象。 ? 避免事务中的用户交互。 ? 保持事务简短并在一个批处理中。 ? 使用低隔离级别。 ? 使用绑定连接。
2、按同一顺序访问对象 如果所有并发事务按同一顺序访问对象,则发生死锁的可能性会降低。例如,如果两个并发事务获得 Supplier 表上的锁,然后获得 Part 表上的锁,则在其中一个事务完成之前,另一个事务被阻塞在 Supplier 表上。第一个事务提交或回滚后,第二个事务继续进行。不发生死锁。将存储过程用于所有的数据修改可以标准化访问对象的顺序。
3、避免事务中的用户交互 避免编写包含用户交互的事务,因为运行没有用户交互的批处理的速度要远远快于用户手动响应查询的速度,例如答复应用程序请求参数的提示。例如,如果事务正在等待用户输入,而用户去吃午餐了或者甚至回家过周末了,则用户将此事务挂起使之不能完成。这样将降低系统的吞吐量,因为事务持有的任何锁只有在事务提交或回滚时才会释放。即使不出现死锁的情况,访问同一资源的其它事务也会被阻塞,等待该事务完成。 4、保持事务简短并在一个批处理中 在同一数据库中并发执行多个需要长时间运行的事务时通常发生死锁。事务运行时间越长,其持有排它锁或更新锁的时间也就越长,从而堵塞了其它活动并可能导致死锁。 保持事务在一个批处理中,可以最小化事务的网络通信往返量,减少完成事务可能的延迟并释放锁。
原文摘自:
/blog/722712
/oracle/385142.html
/link?url=MhEcvSfC686wE-GGcSVnOf02R_6y6nsiq9pMOE2sHTlIXSAIIk89mlVm8eTBDaA8IxOAY_F_1e2U3s7jYhGlpbT5MOBwxlCyFtdNjXC0UyW
beijishiqidu
浏览: 84569 次
来自: 深圳
int temp = 0 ;
while(( ...
学习了,这块自己还得深挖下
这个写的最详细了,赞一个
hanmiao 写道http://yangguangfu.it ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'博客访问: 10820
博文数量: 8
注册时间:
鏆傛棤浠嬬粛
ITPUB论坛APP
ITPUB论坛APP
APP发帖 享双倍积分
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: Oracle
1)查找死锁的进程:sqlplus "/as sysdba"SELECT s.username,l.OBJECT_ID,l.SESSION_ID,s.SERIAL#,l.ORACLE_USERNAME,l.OS_USER_NAME,l.PROCESS FROM V$LOCKED_OBJECT l,V$SESSION S WHERE l.SESSION_ID=S.SID; [@more@]2)kill掉这个死锁的进程:alter system kill session 'sid,serial#'; (其中sid=l.session_id)3)如果还不能解决,select pro.spid from v$session ses,v$process pro where ses.sid=XX and ses.paddr=pro. 其中sid用死锁的sid替换。exitps -ef|grep spid其中spid是这个进程的进程号,kill掉这个Oracle进程。
阅读(1540) | 评论(0) | 转发(0) |
下一篇:没有了
相关热门文章
给主人留下些什么吧!~~
请登录后评论。教你一招,一分钟解决讨厌的Oracle死锁 - Oracle,数据库 - Tech - ITeye论坛
教你一招,一分钟解决讨厌的Oracle死锁
& 上一页 1
锁定老帖子
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
等级: 初级会员
来自: 广州
发表时间:&&
相关知识库:
--第一步:查看是否有死锁存在,查出有数据则代表有死锁 &
select p.spid,c.object_name,b.session_id,b.oracle_username,b.os_user_name& from v$process p,v$session a,v$locked_object b,all_objects&& c&&
where& p.addr=a.paddr&&
and&&& a.process=b.process&&
and&&& c.object_id=b.object_id
--第二步:查出死锁session的精确信息【sid 为前面语句的session_id】
SELECT sid, serial#, username, osuser FROM v$session where sid='第一步查询出来的session_id';
--第三步:删除死锁【第一个参数为sid,第二个为serial#】
alter system kill session '第一个参数,第二个参数';
一步,两步,三步轻松搞定Oracle数据库死锁,没有了Oracle死锁,好舒服啊...
zhao_chong
等级: 初级会员
来自: 贫民窟
发表时间:&&
请登录后投票
来自: 避暑天堂
发表时间:&&
表示、目前不懂~~~!!!
请登录后投票
等级: 初级会员
来自: 北京
发表时间:&&
这个视乎使用n年,很熟悉了。
请登录后投票
等级: 初级会员
来自: 北京
发表时间:&&
这个还真没用过、。。。、
请登录后投票
Storm_Four
等级: 初级会员
来自: 福州
发表时间:&&
oracle是不会产生真正的死锁的,死锁只有可能在应用程序中产生
请登录后投票
等级: 初级会员
来自: 广州
发表时间:&&
1)这是普通锁列表2)kill session 把链接会话强制结束跟死锁无关。oracle自动检测死锁,每个死锁在后台都有trace纪录。而且死锁发生后事务就结束,在上边的试视图是看不见的。lz说得是一般乐观锁的等待状态的检测
请登录后投票
等级: 初级会员
来自: 奥格瑞玛
发表时间:&&
楼主死锁 不能这样搞。死锁是因为你的应用程序对数据库操作有问题,假如你现在 kill掉了死锁,那么只能解决当时的问题,这个隐藏的死锁还是会一直出现的,劝楼主一定要找到死锁的原因所在,然后解决掉,而不是一味的kill 死锁。。。
请登录后投票
rest001555
等级: 初级会员
来自: 西安
发表时间:&&
请登录后投票
等级: 初级会员
来自: 广州
发表时间:&&
chusiyou 写道楼主死锁 不能这样搞。死锁是因为你的应用程序对数据库操作有问题,假如你现在 kill掉了死锁,那么只能解决当时的问题,这个隐藏的死锁还是会一直出现的,劝楼主一定要找到死锁的原因所在,然后解决掉,而不是一味的kill 死锁。。。
嘿嘿,你说的对,我贴这个帖子只是为了快速的解决数据库的死锁,从而不影响到程序的正常运行,不耽误任工作!
请登录后投票
& 上一页 1
跳转论坛:移动开发技术
Web前端技术
Java企业应用
编程语言技术查看: 3988|回复: 4
请问INSERT时是如何造成死锁的?
认证徽章论坛徽章:139
有两个程序(不同的机器)向一张表中插入数据,每个程序起3个进程插入数据。
突然有一天这个表中没有再进数据了,查V$LOCKED_OBJECT发现这张表被2个程序开的6个进程加锁了,而且始终不能释放,只能KILL掉进程才完事。
几个事务在insert同一张表的时候是如何造成死锁的?这张表没有P.K.,是在分配ROWID时造成死锁的吗?我只知道在UPDATE的时候,如果事务t1&&UPDATE ROW1,会在row1上加RX锁,T2 UPDATE ROW2时 会在ROW2上加RX锁,如果这时T1请求ROW2而T2请求ROW1时就会造成死锁。那么INSERT那?
t1&&在ROWID1处加所,t2 在ROWID2处加所,当T2请求ROWID1而T1请求ROWID2时就会造成死锁?
不是很清楚,请大家指点。
如果真是这种原因在程序里该如何改进?
论坛徽章:226
只是insert不会造成死锁吧!?
论坛徽章:86
1: 确保没有使用 MTS
2: 若不是ASSM表空间,给表多设置freelist,比如6
认证徽章论坛徽章:139
最初由 biti_rainy 发布
1: 确保没有使用 MTS
2: 若不是ASSM表空间,给表多设置freelist,比如6 [/B]
数据库是MTS的,不知道有什么影响?
论坛徽章:86
MTS 对大事务有影响!
参考 oracle&&document 里面有说明! MTS 有可能造成资源的死锁!
这个跟 oracle 锁的管理机制的问题,因为多个session共同使用同一个process 导致 资源问题
itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有    
 北京市公安局海淀分局网监中心备案编号:10 广播电视节目制作经营许可证:编号(京)字第1149号锁是一种机制,一直存在;死锁是一种错误,尽量避免。
首先,要理解锁和死锁的概念:
定义:简单的说,锁是数据库为了保证数据的一致性而存在的一种机制,其他数据库一样有,只不过实现机制上可能大相径庭。
那么,锁的种类有哪些?锁的种类有很多,根据保护的对象不同,Oracle数据库锁可以分为以下几大类:DML锁(data locks,数据锁),用于保护数据的完整性;DDL锁(dictionary locks,字典锁),用于保护数据库对象的结构,如表、索引等的结构定义;内部锁和闩(internal locks and latches),保护 数据库的内部结构。
在实际项目中遇到的最多的是DML锁,也可进一步说是行级锁。这些行级锁在程序并发访问的时候会造成程序很慢,或者直接访问不了的情况&这种现象称为阻塞。那么,产生阻塞的原因是什么呢?定义:当一个会话保持另一个会话正在请求的资源锁定时,就会发生阻塞。被阻塞的会话将一直挂起,直到持有锁的会话放弃锁定的资源为止。四个常见的DML语句会产生阻塞:
1)INSERT&2)UPDATE&3)DELETE&4)SELECT&FOR UPDATE
定义:当两个用户同时希望持有对方的资源时就会发生死锁。即当两个用户互相等待对方释放资源时,oracle认定产生了死锁,在这种情况下,将以牺牲一个用户为代价,另一个用户继续执行,牺牲的事物将回滚。
例子:&1:用户1对A表进行Update,没有提交。&2:用户2对B表进行Update,没有提交。&此时双反不存在资源共享的问题。&3:如果用户2此时对A表作update,则会发生阻塞,需要等到用户一的事物结束。&4:如果此时用户1又对B表作update,则产生死锁。此时Oracle会选择其中一个用户进行会滚,使另一个用户继续执行操作。
起因:&Oracle的死锁问题实际上很少见,如果发生,基本上都是不正确的程序设计造成的,经过调整后,基本上都会避免死锁的发生。
死锁产生的原因及四个必要条件:
产生死锁的原因主要是:(1) 因为系统资源不足。(2) 进程运行推进的顺序不合适。(3) 资源分配不当等。如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。
产生死锁的四个必要条件:(1)&互斥条件:一个资源每次只能被一个进程使用。(2)&请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。(3)&不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。(4)&循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。
死锁的解除与预防:理解了死锁的原因,尤其是产生死锁的四个必要条件,就可以最大可能地避免、预防和解除死锁。所以,在系统设计、进程调度等方面注意如何不让这四个必要条件成立,如何确定资源的合理分配算法,避免进程永久占据系统资源。此外,也要防止进程在处于等待状态的情况下占用资源。因此,对资源的分配要给予合理的规划。
3、锁问题的解决:
产生原因:
死锁问题,oracle默认会解决,这里的锁问题主要指的是由于数据库锁机制而导致的阻塞现象,或者是,在实际操作中,由于不正当操作或者程序中的bug,当程序卡在那里的时候造成的锁表现象,或者是,事物进行回滚或者提交时发生了异常,没有回滚成功或者提交成功,导致锁表(这是一种真正意义的死亡,虽然不是死锁,但是和死锁性质一样,甚至比死锁更可怕)。
处理方法:
1)使用工具:不管任何事情提前预防总是好的,可以用Spotlight软件对数据库的运行状态进行监控。(没用过)
2)针对本系统此问题的解决方案(类似情况都可以套用哈)
原文:.cn/s/blog_9d12d07f0102vu72.html
阅读(...) 评论()}

我要回帖

更多关于 oracle 死锁快速定位 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信