【DEADLOCK】Oracle“死鎖”模擬
本著實驗優先的原則,先模擬死鎖的發生,然後在列一下死鎖產生的四個必要條件和處理死鎖的一般策略。
1.建立兩個簡單的表t1_deadlock和t2_deadlock,每個表中僅僅包含一個欄位a
sys@ora10g> conn sec/sec
Connected.
sec@ora10g> create table t1_deadlock (a int);
Table created.
sec@ora10g> create table t2_deadlock (a int);
Table created.
2.每張表中僅初始化一條資料
sec@ora10g> insert into t1_deadlock values (1);
1 row created.
sec@ora10g> insert into t2_deadlock values (2);
1 row created.
sec@ora10g> commit;
Commit complete.
3.在第一個會話session1中更新表t1_deadlock中的記錄“1”為“1000”,不進行提交
sec@ora10g> update t1_deadlock set a = 1000 where a = 1;
1 row updated.
4.在第二個會話session2中更新表t2_deadlock中的記錄“2”為“2000”,不進行提交
sec@ora10g> update t2_deadlock set a = 2000 where a = 2;
1 row updated.
5.此時,沒有任何問題發生。OK,現在注意一下下面的現象,我們再回到會話session1中,更新t2_deadlock的記錄
sec@ora10g> update t2_deadlock set a = 2000 where a = 2;
這裡出現了“鎖等待”(“阻塞”)的現象,原因很簡單,因為在session2中已經對這條資料執行過這個操作,在session2中已經對該行加了行級鎖。
注意,這裡是“鎖等待”,不是“死鎖”,注意這兩個概念的區別!
檢測“鎖等待”的方法曾經提到過,請參考《【實驗】【LOCK】“鎖等待”模擬、診斷及處理方法》http://space.itpub.net/519536/viewspace-605526
sec@ora10g> @lock
lock lock
holder holder lock lock request blocked
username sessid SERIAL# type id1 id2 mode mode BLOCK sessid
-------- ------ ------- ------ ------ ---- ---- ------- ----- -------
SEC 141 6921 TM 15160 0 3 0 0
SEC 141 6921 TX 393231 1672 6 0 1 145
SEC 145 7402 TM 15159 0 3 0 0
SEC 145 7402 TM 15160 0 3 0 0
SEC 145 7402 TX 131077 1675 6 0 0
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
11 rows selected.
6.我們關注的“死鎖”馬上就要隆重出場了:在會話session2中,更新t1_deadlock的記錄(滿足了死鎖產生的四個條件了,請慢慢體會)
sec@ora10g> update t1_deadlock set a = 1000 where a = 1;
這裡還是長時間等待的現象,但是這裡發生了“死鎖”!!
細心的您再去第一個會話session1中看一下,原先一直在等待的SQL語句出現如下的現象:
sec@ora10g> update t2_deadlock set a = 2000 where a = 2;
update t2_deadlock set a = 2000 where a = 2
*
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource
更進一步:檢視一下alert警告日誌檔案發現有如下的記錄
Mon Aug 10 11:24:29 2009
ORA-00060: Deadlock detected. More info in file /oracle/app/oracle/admin/ora10g/udump/ora10g_ora_25466.trc.
再進一步:看看系統自動生成的trace檔案中記錄了什麼
這個檔案包含了5721行的記錄資訊,擷取其中我們關心的前面N多行的內容(結合剛才檢測“鎖等待”指令碼產生的結果分析一下,看看有沒有收穫):
/oracle/app/oracle/admin/ora10g/udump/ora10g_ora_25466.trc
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP and Data Mining Scoring Engine options
ORACLE_HOME = /oracle/app/oracle/product/10.2.0/db_1
System name: Linux
Node name: testdb
Release: 2.6.18-53.el5xen
Version: #1 SMP Wed Oct 10 16:48:44 EDT 2007
Machine: x86_64
Instance name: ora10g
Redo thread mounted by this instance: 1
Oracle process number: 14
Unix process pid: 25466, image: oracle@testdb (TNS V1-V3)
*** 2009-08-10 11:24:29.541
*** ACTION NAME:() 2009-08-10 11:24:29.540
*** MODULE NAME:(SQL*Plus) 2009-08-10 11:24:29.540
*** SERVICE NAME:(SYS$USERS) 2009-08-10 11:24:29.540
*** SESSION ID:(145.7402) 2009-08-10 11:24:29.540
DEADLOCK DETECTED
[Transaction Deadlock]
Current SQL statement for this session:
update t2_deadlock set a = 2000 where a = 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
TX-00020005-0000068b 14 145 X 15 141 X
TX-0006000f-00000688 15 141 X 14 145 X
session 145: DID 0001-000E-0000037D session 141: DID 0001-000F-0000013D
session 141: DID 0001-000F-0000013D session 145: DID 0001-000E-0000037D
Rows waited on:
7.以上種種現象說明什麼?
說明:Oracle對於“死鎖”是要做處理的,而不是採用下面提到的“鴕鳥演算法”不聞不問。
注意trace檔案中的一行如下提示資訊,說明一般情況下都是應用和人為的,和Oracle同學沒有關係:
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.
8.以上演示了一種“死鎖”現象的發生,當然導致死鎖發生的情況遠遠不僅如此。所以在程式設計時一定要好好的進行思考
9.【擴充】
死鎖產生的四個必要條件
1)Mutual exclusion(互斥):資源不能被共享,只能由一個程式使用。
2)Hold and wait(請求並保持):已經得到資源的程式可以再次申請新的資源。
3)No pre-emption(不可剝奪):已經分配的資源不能從相應的程式中被強制地剝奪。
4)Circular wait(迴圈等待條件):系統中若干程式組成環路,該環路中每個程式都在等待相鄰程式正佔用的資源。
處理死鎖的一般策略
1)鴕鳥演算法忽略該問題
2)檢測死鎖並且恢復
3)仔細地對資源進行動態分配,以避免死鎖
4)透過破壞死鎖產生呢過的四個必要條件之一,來防止死鎖產生
10.總結
死鎖對於資料庫來說是非常要命的,請多多注意!
對於上面的演示處理的方式:在會話session1中執行rollback進行回滾,會釋放導致session2鎖等待的鎖資源(死鎖Oracle已經處理了)。
Good luck.
secooler
11.10.22
-- The End --
1.建立兩個簡單的表t1_deadlock和t2_deadlock,每個表中僅僅包含一個欄位a
sys@ora10g> conn sec/sec
Connected.
sec@ora10g> create table t1_deadlock (a int);
Table created.
sec@ora10g> create table t2_deadlock (a int);
Table created.
2.每張表中僅初始化一條資料
sec@ora10g> insert into t1_deadlock values (1);
1 row created.
sec@ora10g> insert into t2_deadlock values (2);
1 row created.
sec@ora10g> commit;
Commit complete.
3.在第一個會話session1中更新表t1_deadlock中的記錄“1”為“1000”,不進行提交
sec@ora10g> update t1_deadlock set a = 1000 where a = 1;
1 row updated.
4.在第二個會話session2中更新表t2_deadlock中的記錄“2”為“2000”,不進行提交
sec@ora10g> update t2_deadlock set a = 2000 where a = 2;
1 row updated.
5.此時,沒有任何問題發生。OK,現在注意一下下面的現象,我們再回到會話session1中,更新t2_deadlock的記錄
sec@ora10g> update t2_deadlock set a = 2000 where a = 2;
這裡出現了“鎖等待”(“阻塞”)的現象,原因很簡單,因為在session2中已經對這條資料執行過這個操作,在session2中已經對該行加了行級鎖。
注意,這裡是“鎖等待”,不是“死鎖”,注意這兩個概念的區別!
檢測“鎖等待”的方法曾經提到過,請參考《【實驗】【LOCK】“鎖等待”模擬、診斷及處理方法》http://space.itpub.net/519536/viewspace-605526
sec@ora10g> @lock
lock lock
holder holder lock lock request blocked
username sessid SERIAL# type id1 id2 mode mode BLOCK sessid
-------- ------ ------- ------ ------ ---- ---- ------- ----- -------
SEC 141 6921 TM 15160 0 3 0 0
SEC 141 6921 TX 393231 1672 6 0 1 145
SEC 145 7402 TM 15159 0 3 0 0
SEC 145 7402 TM 15160 0 3 0 0
SEC 145 7402 TX 131077 1675 6 0 0
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
11 rows selected.
6.我們關注的“死鎖”馬上就要隆重出場了:在會話session2中,更新t1_deadlock的記錄(滿足了死鎖產生的四個條件了,請慢慢體會)
sec@ora10g> update t1_deadlock set a = 1000 where a = 1;
這裡還是長時間等待的現象,但是這裡發生了“死鎖”!!
細心的您再去第一個會話session1中看一下,原先一直在等待的SQL語句出現如下的現象:
sec@ora10g> update t2_deadlock set a = 2000 where a = 2;
update t2_deadlock set a = 2000 where a = 2
*
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource
更進一步:檢視一下alert警告日誌檔案發現有如下的記錄
Mon Aug 10 11:24:29 2009
ORA-00060: Deadlock detected. More info in file /oracle/app/oracle/admin/ora10g/udump/ora10g_ora_25466.trc.
再進一步:看看系統自動生成的trace檔案中記錄了什麼
這個檔案包含了5721行的記錄資訊,擷取其中我們關心的前面N多行的內容(結合剛才檢測“鎖等待”指令碼產生的結果分析一下,看看有沒有收穫):
/oracle/app/oracle/admin/ora10g/udump/ora10g_ora_25466.trc
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP and Data Mining Scoring Engine options
ORACLE_HOME = /oracle/app/oracle/product/10.2.0/db_1
System name: Linux
Node name: testdb
Release: 2.6.18-53.el5xen
Version: #1 SMP Wed Oct 10 16:48:44 EDT 2007
Machine: x86_64
Instance name: ora10g
Redo thread mounted by this instance: 1
Oracle process number: 14
Unix process pid: 25466, image: oracle@testdb (TNS V1-V3)
*** 2009-08-10 11:24:29.541
*** ACTION NAME:() 2009-08-10 11:24:29.540
*** MODULE NAME:(SQL*Plus) 2009-08-10 11:24:29.540
*** SERVICE NAME:(SYS$USERS) 2009-08-10 11:24:29.540
*** SESSION ID:(145.7402) 2009-08-10 11:24:29.540
DEADLOCK DETECTED
[Transaction Deadlock]
Current SQL statement for this session:
update t2_deadlock set a = 2000 where a = 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
TX-00020005-0000068b 14 145 X 15 141 X
TX-0006000f-00000688 15 141 X 14 145 X
session 145: DID 0001-000E-0000037D session 141: DID 0001-000F-0000013D
session 141: DID 0001-000F-0000013D session 145: DID 0001-000E-0000037D
Rows waited on:
7.以上種種現象說明什麼?
說明:Oracle對於“死鎖”是要做處理的,而不是採用下面提到的“鴕鳥演算法”不聞不問。
注意trace檔案中的一行如下提示資訊,說明一般情況下都是應用和人為的,和Oracle同學沒有關係:
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.
8.以上演示了一種“死鎖”現象的發生,當然導致死鎖發生的情況遠遠不僅如此。所以在程式設計時一定要好好的進行思考
9.【擴充】
死鎖產生的四個必要條件
1)Mutual exclusion(互斥):資源不能被共享,只能由一個程式使用。
2)Hold and wait(請求並保持):已經得到資源的程式可以再次申請新的資源。
3)No pre-emption(不可剝奪):已經分配的資源不能從相應的程式中被強制地剝奪。
4)Circular wait(迴圈等待條件):系統中若干程式組成環路,該環路中每個程式都在等待相鄰程式正佔用的資源。
處理死鎖的一般策略
1)鴕鳥演算法忽略該問題
2)檢測死鎖並且恢復
3)仔細地對資源進行動態分配,以避免死鎖
4)透過破壞死鎖產生呢過的四個必要條件之一,來防止死鎖產生
10.總結
死鎖對於資料庫來說是非常要命的,請多多注意!
對於上面的演示處理的方式:在會話session1中執行rollback進行回滾,會釋放導致session2鎖等待的鎖資源(死鎖Oracle已經處理了)。
Good luck.
secooler
11.10.22
-- The End --
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/519536/viewspace-611729/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- ORA-00060: Deadlock detected 模擬死鎖產生與解決方案
- 簡單模擬死鎖
- 模擬SQLserver死鎖現象SQLServer
- 關於 SAP HANA 資料庫的死鎖問題(deadlock)資料庫
- 使用jstack檢測Java應用的死鎖(deadlock)狀態JSJava
- 檢視oracle死鎖程式並結束死鎖Oracle
- 面試官:請用SQL模擬一個死鎖面試SQL
- PostgreSQL模擬兩個update語句死鎖-利用掃描方法SQL
- mysql死鎖deadlock相關幾個系統變數innodb_lock_wait_timeoutMySql變數AI
- ABAP面試題系列:寫一組會出現死鎖(Deadlock)的ABAP程式面試題
- Oracle死鎖一例(ORA-00060),鎖表導致的業務死鎖問題Oracle
- 記一次Oracle死鎖/阻塞排查Oracle
- 解決Oracle死鎖問題步驟Oracle
- 【Oracle】死鎖的產生與處理Oracle
- 死鎖
- 什麼是死鎖?如何解決死鎖?
- 面試官:什麼是死鎖?怎麼排查死鎖?怎麼避免死鎖?面試
- 死鎖概述
- 作業系統(5) 死鎖的概念 死鎖產生的必要條件 死鎖的處理策略 預防死鎖 避免死鎖 死鎖的檢測和解除 銀行家演算法作業系統演算法
- 例項詳解 Java 死鎖與破解死鎖Java
- ORACLE透明加密場景模擬Oracle加密
- Oracle磁帶備份模擬Oracle
- MySQL 死鎖和鎖等待MySql
- 死鎖和可重入鎖
- 面試:什麼是死鎖,如何避免或解決死鎖;MySQL中的死鎖現象,MySQL死鎖如何解決面試MySql
- 基於simulink的模擬鎖相環和數字鎖相環建模與對比模擬
- SQL SERVER死鎖查詢,死鎖分析,解鎖,查詢佔用SQLServer
- 死鎖是什麼?如何預防和避免死鎖?
- MySQL死鎖系列-線上死鎖問題排查思路MySql
- 死鎖-舉例
- 併發:死鎖
- 遭遇ITL死鎖
- 死鎖案例分析
- GCD 死鎖原因GC
- 死鎖案例二
- 死鎖案例三
- MySQL:一個死鎖分析 (未分析出來的死鎖)MySql
- Mysql 兩階段鎖和死鎖MySql
- 鎖的使用與死鎖的避免