一,什么是死锁
A deadlock is a situation in which two or more users are waiting for data locked by each other. Deadlocks prevent some transactions from continuing to work.
死锁描述的是两个或多个用户,由于相互等待被互相锁住的情况
二,死锁的模拟
1.
SQL> conn test/test
Connected.
SQL> create table EMPLOYEES as select * from hr.EMPLOYEES;
Table created.
SQL> desc EMPLOYEES
Name Null? Type
----------------------------------------- -------- ----------------------------
EMPLOYEE_ID NUMBER(6)
FIRST_NAME VARCHAR2(20)
LAST_NAME NOT NULL VARCHAR2(25)
EMAIL NOT NULL VARCHAR2(25)
PHONE_NUMBER VARCHAR2(20)
HIRE_DATE NOT NULL DATE
JOB_ID NOT NULL VARCHAR2(10)
SALARY NUMBER(8,2)
COMMISSION_PCT NUMBER(2,2)
MANAGER_ID NUMBER(6)
DEPARTMENT_ID NUMBER(4)
2.在t0时刻
session1
SQL> UPDATE employees
2 SET salary = salary*1.1
3 WHERE employee_id = 100;
1 row updated.
SQL>
sesson2:
SQL> conn test/test
Connected.
SQL>
SQL>
SQL> UPDATE employees
2 SET salary = salary*1.1
3 WHERE employee_id = 200;
1 row updated.
SQL> SQL>
3.在t1时刻
session1
SQL>
SQL> UPDATE employees
2 SET salary = salary*1.1
3 WHERE employee_id = 200;
没有返回值
session2
SQL>
SQL> UPDATE employees
2 SET salary = salary*1.1
3 WHERE employee_id = 100;
没有返回值
4.在t2时刻
SQL>
SQL> UPDATE employees
2 SET salary = salary*1.1
3 WHERE employee_id = 200;
UPDATE employees
*
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource
/oracle/admin/orcl/bdump/alert_orcl.log
Tue Aug 6 18:55:34 2013
ORA-00060: Deadlock detected. More info in file /oracle/admin/orcl/udump/orcl_ora_2562.trc.
5.t3时刻处理
处理过程见下面部分
三,死锁的处理
此时数据库的等待事件为
SQL> l
1 select sid,event,p1,p2,WAIT_CLASS,WAIT_TIME,SECONDS_IN_WAIT,state from v$session_wait
2* where WAIT_CLASS <> 'Idle'
SQL> /
SID EVENT P1 P2 WAIT_CLASS WAIT_TIME SECONDS_IN_WAIT STATE
---------- ------------------------------ ---------- ---------- -------------------- ---------- --------------- -------------------
146 enq: TX - row lock contention 1415053318 196612 Application 0 285 WAITING
会话2,sid为146发生行级等待
SQL> select sid,type,id1,id2,
2 decode(lmode,0,'None',1,'Null',2,'Row share',
3 3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive')
4 lock_type,request,ctime,block
5 from v$lock
6 where TYPE IN('TX','TM');
SID TY ID1 ID2 LOCK_TYPE REQUEST CTIME BLOCK
---------- -- ---------- ---------- ------------------- ---------- ---------- ----------
146 TX 196612 290 None 6 429 0
159 TM 51472 0 Row Exclusive 0 579 0
146 TM 51472 0 Row Exclusive 0 549 0
146 TX 327688 297 Exclusive 0 549 0
159 TX 196612 290 Exclusive 0 579 1
可以看到锁被sid=159的会话持有,阻塞了149
再回过头看日志的trace文件
[oracle@oradb bdump]$ more /oracle/admin/orcl/udump/orcl_ora_2562.trc
/oracle/admin/orcl/udump/orcl_ora_2562.trc
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
ORACLE_HOME = /oracle/product/10.2
System name: Linux
Node name: oradb
Release: 2.6.18-308.el5
Version: #1 SMP Tue Feb 21 20:05:41 EST 2012
Machine: i686
Instance name: orcl
Redo thread mounted by this instance: 1
Oracle process number: 15
Unix process pid: 2562, image: oracle@oradb (TNS V1-V3)
*** 2013-08-06 18:55:34.096
*** ACTION NAME:() 2013-08-06 18:55:34.095
*** MODULE NAME:(SQL*Plus) 2013-08-06 18:55:34.095
*** SERVICE NAME:(SYS$USERS) 2013-08-06 18:55:34.095
*** SESSION ID:(159.7) 2013-08-06 18:55:34.095
DEADLOCK DETECTED
[Transaction Deadlock]
Current SQL statement for this session:
UPDATE employees
SET salary = salary*1.1
WHERE employee_id = 200
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
TX-00030004-00000122 15 159 X 18 146 X
TX-00050008-00000129 18 146 X 15 159 X
session 159: DID 0001-000F-00000011 session 146: DID 0001-0012-00000013
session 146: DID 0001-0012-00000013 session 159: DID 0001-000F-00000011
Rows waited on:
Session 146: obj - rowid = 0000C910 - AAAMkQAAIAAAAA8AAA
(dictionary objn - 51472, file - 8, block - 60, slot - 0)
Session 159: obj - rowid = 0000C910 - AAAMkQAAIAAAAA9AAC
(dictionary objn - 51472, file - 8, block - 61, slot - 2)
Information on the OTHER waiting sessions:
Session 146:
pid=18 serial=31 audsid=130 user: 56/TEST
O/S info: user: oracle, term: pts/1, ospid: 2650, machine: oradb
program: sqlplus@oradb (TNS V1-V3)
application name: SQL*Plus, hash value=3669949024
Current SQL Statement:
UPDATE employees
SET salary = salary*1.1
WHERE employee_id = 100
End of information on OTHER waiting sessions.
锁等待的具体信息如下:
lock lock
holder holder lock lock request blocked
username session id SERIAL# type id1 id2 mode mode BLOCK session id
------------------ ----------- ---------- ------ ----------- ----------- --------- --------- ---------- ----------
TEST 146 31 TM 51472 0 3 0 0
TEST 146 31 TX 327688 297 6 0 0
TEST 159 7 TM 51472 0 3 0 0
TEST 159 7 TX 196612 290 6 0 1 146
164 1 TS 3 1 3 0 0
165 1 CF 0 0 2 0 0
165 1 RS 25 1 2 0 0
165 1 XR 4 0 1 0 0
166 1 RT 1 0 6 0 0
167 1 PW 1 0 3 0 0
10 rows selected.
以上可知道session id为153的会话阻塞了146
解决方法:
1.kill session 159;
2.159会话commit,或者roll back;
处理如下:
t3时刻
session 1
提交会话
SQL> COMMIT;
Commit complete.
SQL> SQL>
session 2
SQL> UPDATE employees
2 SET salary = salary*1.1
3 WHERE employee_id = 100;
1 row updated.
SQL>
四说明
1.死锁产生的四个必要条件
1)Mutual exclusion(互斥):资源不能被共享,只能由一个进程使用。
2)Hold and wait(请求并保持):已经得到资源的进程可以再次申请新的资源。
3)No pre-emption(不可剥夺):已经分配的资源不能从相应的进程中被强制地剥夺。
4)Circular wait(循环等待条件):系统中若干进程组成环路,该环路中每个进程都在等待相邻进程正占用的资源。
2.死锁通常情况下是因为应用设计不当引起的;此外键未被索引,子表上也会出现死锁。
3.oracle 10g开始处理自动侦测处理死锁的机制,但是有时候还是需要dba干预处理。
Deadlocks most often occur when transactions explicitly override the default locking of Oracle Database. Because Oracle Database does not escalate locks and does not use read locks for queries, but does use row-level (rather than page-level) locking, deadlocks occur infrequently.
By 老白菜
=========================================================================
-- The End --