Oracle常见死锁发生的原因以及解决方法
来源:互联网 发布:交易软件 编辑:程序博客网 时间:2024/05/16 15:58
一.删除和更新之间引起的死锁
CREATE TABLE testLock( ID NUMBER,
test VARCHAR(100) )
COMMIT
INSERT INTO testLock VALUES(1,'test1');
INSERT INTO testLock VALUES(2,'test2');
COMMIT;
SELECT * FROM testLock
SID: session identifier, session 标示符,session 是通信双方从开始通信到通信结束期间的一个上下文。
SERIAL#: sid 会重用,但是同一个sid被重用时,serial#会增加,不会重复。
Lockwait:可以通过这个字段查询出当前正在等待的锁的相关信息。
Status:用来判断session状态。Active:正执行SQL语句。Inactive:等待操作。Killed:被标注为删除。
Machine: 死锁语句所在的机器。
Program: 产生死锁的语句主要来自哪个应用程序。
查看引起死锁的语句:
SQL> 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));
此时没有死锁的语句。2.另开一个command窗口,执行:delete from testLock WHERE ID=1;
此时发生死锁(注意此时要另开一个窗口,不然会提示:POST THE CHANGE RECORD TO THE DATABASE. 点yes 后强制commit):
死锁查看:
查看引起死锁的语句:
SQL> 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));
二.在外键上没有加索引引起的死锁
客户的10.2.0.4 RAC for AIX环境频繁出现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;
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;
Rollback complete.
将会话1操作回滚,会话2同样回滚并建立外键列上的索引:
1 row deleted.
SQL2> rollback;
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常见死锁发生的原因以及解决方法
- Oracle常见死锁发生的原因以及解决方法
- Oracle发生死锁原因分析及解决方法
- NoClassDefFoundError错误发生的原因 以及常见的解决方法
- NoClassDefFoundError错误发生的原因 以及常见的解决方法
- Oracle中发生表加锁、死锁的原因,查看,与解决方法
- 死锁产生的原因以及解决方法
- 数据库Oracle,Mysal并发时经典常见的死锁原因及解决方法
- Mysql并发时经典常见的死锁原因及解决方法
- Mysql并发时经典常见的死锁原因及解决方法
- Mysql并发时经典常见的死锁原因及解决方法
- Mysql并发时经典常见的死锁原因及解决方法
- Mysql并发时经典常见的死锁原因及解决方法
- Mysql并发时经典常见的死锁原因及解决方法
- 多线程编程:线程死锁的原因以及解决方法
- 线程发生死锁的条件与原因
- oracle死锁的解决方法
- 进程死锁的危害、导致原因、解决方法
- 解决一个八阿哥bug的方法
- 深入理解javascript的定时机制
- win10下安装和配置nodejs
- 递归(一)几个简单的递归例子
- LeetCode 3. Longest Substring Without Repeating Characters
- Oracle常见死锁发生的原因以及解决方法
- Chapter 3 ADC and DAC
- Linux的3个文件时间
- 分布式定时任务解决方案-spring boot整合JMS以及Redis实现
- 点线面的融会贯通学习方法探讨
- 小白初装SQL Server 2008遇到的问题
- 跟小博老师一起学Servlet ——Servlet之HttpServletResponse
- 使用Notepad++批量转换源代码编码方式
- Navicat for MySQL触发器更新和插入操作