Oracle死結產生的原因和解決辦法

來源:互聯網
上載者:User

標籤:

如果有兩個會話,每個會話都持有另一個會話想要的資源,此時就會發生死結。
用下面實驗來說明死結的產生原因和解決辦法。
SESSION1:
SQL> create table t2 as select * from emp;
SQL> select * from t2 where empno=7369;

     EMPNO ENAME      JOB              MGR HIREDATE                 SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ----------------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 19801217 00:00:00        800                    20

SQL> update t2 set sal=sal+200 where empno=7369;

SQL> select * from t2 where empno=7369;

     EMPNO ENAME      JOB              MGR HIREDATE                 SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ----------------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 19801217 00:00:00       1000                    20

SESSION2:

SQL> select * from t2 where empno=7900;

     EMPNO ENAME      JOB              MGR HIREDATE                 SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ----------------- ---------- ---------- ----------
      7900 JAMES      CLERK           7698 19811203 00:00:00        950                    30

SQL> update t2 set sal=sal+200 where empno=7900;

1 row updated.

SQL> select * from t2 where empno=7900;

     EMPNO ENAME      JOB              MGR HIREDATE                 SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ----------------- ---------- ---------- ----------
      7900 JAMES      CLERK           7698 19811203 00:00:00       1150                    30

SESSION1:
SQL> select * from t2 where empno=7900;

     EMPNO ENAME      JOB              MGR HIREDATE                 SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ----------------- ---------- ---------- ----------
      7900 JAMES      CLERK           7698 19811203 00:00:00        950                    30

SESSION2:
SQL> select * from t2 where empno=7369;

     EMPNO ENAME      JOB              MGR HIREDATE                 SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ----------------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 19801217 00:00:00        800                    20

SESSION1:
SQL> update t2 set sal=sal-200 where empno=7900; 
出現等待

SESSION2:
SQL> update t2 set sal=sal-200 where empno=7369;
死結發生,session2被阻塞
系統復原session1跟死結有關的sql。
update t2 set sal=sal-200 where empno=7900
       *
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource

SESSION1:
SQL> select * from t2 where empno in (7369,7900);

     EMPNO ENAME      JOB              MGR HIREDATE                 SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ----------------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 19801217 00:00:00       1000                    20
      7900 JAMES      CLERK           7698 19811203 00:00:00        950                    30
看到系統只復原了對empno=7900的修改。
而此時SESSION2的update t2 set sal=sal-200 where empno=7369;依然被SESSION1的第一條語句所阻塞。


我們現在查看產生鎖的情況
開啟第三個會話以DBA身份登入
SQL> select * from v$lock;

ADDR     KADDR           SID TY        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
29434224 29434238        165 XR          4          0          1          0       2998          0
29434280 29434294        165 CF          0          0          2          0       2988          0
294342DC 294342F0        167 PW          1          0          3          0       2980          0
29434338 2943434C        165 RS         25          1          2          0       2983          0
294343F0 29434404        166 RT          1          0          6          0       2983          0
2943444C 29434460        153 TX     589868        325          0          4         24          0
29434560 29434574        167 MR          1          0          4          0       2983          0
294345BC 294345D0        167 MR          2          0          4          0       2983          0
29434618 2943462C        167 MR          3          0          4          0       2983          0
29434674 29434688        167 MR          4          0          4          0       2983          0
294346D0 294346E4        167 MR          5          0          4          0       2983          0
2943472C 29434740        167 MR          6          0          4          0       2983          0
29434788 2943479C        167 MR          7          0          4          0       2983          0
294347E4 294347F8        167 MR        201          0          4          0       2983          0
2943489C 294348B0        164 TS          3          1          3          0       2979          0
288F6030 288F6048        144 TM      53257          0          3          0         51          0
288F60DC 288F60F4        153 TM      53257          0          3          0         24          0
28934170 28934194        153 TX     655363        241          6          0         24          0
28969404 28969428        144 TX     589868        325          6          0         51          1

19 rows selected.

用下面的SQL語句可以直接得出誰阻塞誰
SQL> select ( select username from v$session where sid=a.sid) blocker, a.sid,
        ‘ is blocking ‘,
        (select username from v$session where sid=b.sid) blockee, b.sid
from v$lock a, v$lock b
where a.block=1 and b.request>0 and a.id1=b.id1 and a.id2=b.id2;


BLOCKER                               SID ‘ISBLOCKING‘  BLOCKEE                               SID
------------------------------ ---------- ------------- ------------------------------ ----------
STONE                                 144  is blocking  STONE                                 153


發生死結的時候會在alert檔案裡記錄下資訊。
--查看作業系統下$ORACLE_BASE/admin/orcl/bdump/alert_orcl.log檔案,會找到如下資訊
Thu Sep  2 20:41:25 2010
ORA-00060: Deadlock detected. More info in file /u01/app/oracle/admin/orcl/udump/orcl_ora_4945.trc.

再查看追蹤檔案詳細資料
*** 2010-09-02 20:41:25.700
*** ACTION NAME () 2010-09-02 20:41:25.699
*** MODULE NAME (SQL*Plus) 2010-09-02 20:41:25.699
*** SERVICE NAME (SYS$USERS) 2010-09-02 20:41:25.699
*** SESSION ID (144.3) 2010-09-02 20:41:25.699
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
TX-00090015-00000146        19     144     X             23     148           X
.......

SESSION2還在被SESSION1阻塞,只有在SESSION1執行提交或回退才能讓SESSION2繼續下去。
SESSION1:
commit; --將提交update t2 set sal=sal+200 where empno=7369的修改

rollback;--將取消update t2 set sal=sal+200 where empno=7369的修改

隨即SESSION2得到1 row updated.的資訊。

我們也可以用管理員帳號執行kill命令殺死導致阻塞的會話SESSION1來解決死結。
sqlplus / as sysdba
從上面查過的資訊可以知道產生阻塞的sid=144
通過查v$session視圖可以得出serial#

SADDR           SID    SERIAL#     AUDSID PADDR         USER# USERNAME       COMMAND    OWNERID TADDR
-------- ---------- ---------- ---------- -------- ---------- ----------- ---------- ---------- -----
29F0BED4        144          3     210009 29E24174         64 STONE                0 2147483644

殺死這個會話用下面的命令
alter system kill session ‘144,3‘;

總結:
    Oralce認為死結是應用導致的錯誤,Oracle中很少出現死結。導致死結的的頭號殺手是外鍵沒有加索引,第二號殺手則是位元影像索引遭到並發更新。
    如果外鍵沒有索引,我們更新了父表的主鍵時將會鎖住整個子表。如果外鍵沒有索引,刪除了父表中的一行,整個子表也會被鎖住。這樣就很容易產生很多問題,如果其中任何阻塞的會話鎖住了某一會話需要的資源就會出現一個死結。至於位元影像索引的並發更新,是會鎖住所有相關聯的行,也會導致問題的發生。
    在Oracle9i及以上版本中,這些全表鎖都是短期的,也就是僅在DML操作期間存在,而不是存在於整個事務期間。

本文轉自:http://www.itpub.net/thread-1347577-1-1.html

Oracle死結產生的原因和解決辦法

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.