【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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 關於oracle死鎖的模擬Oracle
- ORA-00060: Deadlock detected 模擬死鎖產生與解決方案
- 死鎖_DeadLock_示例
- oracle deadlock死鎖trace file分析之一Oracle
- oracle lock轉換及oracle deadlock死鎖系列一Oracle
- 模擬SQLserver死鎖現象SQLServer
- oracle deadlock死鎖trace file分析之一增補Oracle
- [Java]一個DeadLock(死鎖)的例子Java
- RDSSQLServer死鎖(Deadlock)系列之三自動部署Profiler捕獲死鎖SQLServer
- 使用oracle 10704 event分析獲取鎖lock及死鎖deadlock系列九Oracle
- 面試官:請用SQL模擬一個死鎖面試SQL
- oracle 死鎖Oracle
- 殺死Oracle死鎖程式Oracle
- PostgreSQL模擬兩個update語句死鎖-利用掃描方法SQL
- 關於 SAP HANA 資料庫的死鎖問題(deadlock)資料庫
- 【死鎖】ORA-00060: deadlock detected while waiting for resourceWhileAI
- 測試庫死鎖診斷DEADLOCK DETECTED ( ORA-00060 )
- ORA-00060: Deadlock detected(場景模擬)
- 檢視oracle死鎖程式並結束死鎖Oracle
- Oracle 死鎖處理Oracle
- Oracle死鎖處理Oracle
- ORACLE死鎖檢測Oracle
- 使用jstack檢測Java應用的死鎖(deadlock)狀態JSJava
- Java 死鎖(DeadLock)例項分析和預防[base jdk8]JavaJDK
- 基於10.2.0.1 rac deadlock死鎖 trace file分析_增補二
- oracle deadlock 之(一)--鎖機制介紹Oracle
- MySQL在RR隔離級別下的unique失效和死鎖模擬MySql
- ORACLE 死鎖分析過程Oracle
- oracle 死鎖表解決方法Oracle
- oracle-tom死鎖演示Oracle
- deadlock引起資料庫掛死資料庫
- ABAP面試題系列:寫一組會出現死鎖(Deadlock)的ABAP程式面試題
- select for update語句造成ORA-00060 deadlock死鎖問題分析
- ORACLE死鎖及處理方式Oracle
- oracle 死鎖查詢處理Oracle
- Oracle死鎖原因產生分析Oracle
- oracle 檢視死鎖語句Oracle
- 完全乾掉Oracle死鎖程式Oracle