Oracle死锁的模拟和处理

一,什么是死锁
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 --




你可能感兴趣的:(oracle,Lock,死锁)