Oracle

Oracle 11g 尋找死鎖,也許是外鍵?

  • January 20, 2012

我試圖了解為什麼我的數據庫會出現死鎖。跟踪告訴我同一張表上的兩個更新正在鎖定。In table 是事務中要寫入的第一個表,之前只發生了一些讀取。更新/插入以批處理方式完成。也用於標識要更新的行的鍵使用 b+-tree 進行索引。該鍵在其他表中也充當外鍵。在這些其他表中,外鍵允許為空。

應用程序不允許包含可能衝突的並行事務。

這是跟踪文件的頭:

Deadlock graph:
   ---------Blocker(s)--------  ---------Waiter(s)---------
Resource Name          process session holds waits  process session holds waits
TX-134b0012-3201376f        65     185     X             33     392           S
TX-13495007-50f092d1        33     392     X             65     185           S

session 185: DID 0001-0012-04533045 session 392: DID 0001-0023-03401G5A 
session 392: DID 0001-0023-03401G5A session 185: DID 0001-0012-04533045 

Rows waited on:
Session 588: no row
Session 497: no row

在將鍵作為外鍵引用的表中插入空值會導致某種表掃描(不這麼認為)嗎?批量插入/更新可能會導致索引的更大分支被鎖定嗎?也許 T1 得到了樹的一些左分支,而 T2 得到了右分支,現在 T1 想要在右分支中插入/更新一個值,但右分支仍然被 T2 鎖定,T" 然後從左側請求一些東西? 我不知道Oracle 中是否以及如何實現多粒度鎖定,但如果有人能排除這一點,那就太好了。

即使事務在邏輯上是 100% 分離的,Oracle 是否有可能允許死鎖?

我可以尋找什麼?訪問索引有問題嗎?

PS:已設置讀取已送出。

Oracle 中具有邏輯不相交事務的死鎖通常涉及未索引的外鍵

未索引的外鍵有兩個問題。第一個事實是,如果您更新父記錄的主鍵(非常非常不尋常),或者如果您刪除了父記錄並且子記錄的外鍵未編入索引,則會導致表鎖定。

Oracle 中的鎖在行級別進行管理。並發的不相交事務不應相互干擾。未索引的外鍵是一個例外,因為它可能導致完整的 TABLE LOCK。

您應該在死鎖的跟踪文件中獲取 SQL,這應該可以幫助您縮小對鎖定負責的表/外鍵。一旦您知道哪個表受死鎖影響,請確保對該表的所有外鍵引用都已正確索引。如果您的範例中的 EGT2.t1_id指向T1.t1_id.

或者,您可以使用上面連結中的 Tom Kyte 腳本來確定您是否有任何未索引的外鍵。


如果您鎖定了插入,通常意味著您正在嘗試為一組唯一的列插入具有相同值的行,例如:

CREATE TABLE T1 (col1 NUMBER NOT NULL, col2 NUMBER);
ALTER TABLE T1 ADD CONSTRAINT T1_UNIQUE UNIQUE (col1, col2);

session1> INSERT INTO T1 VALUES (1, NULL);
session2> INSERT INTO T1 VALUES (2, NULL);
session2> INSERT INTO T1 VALUES (1, NULL); -- <= this will wait on session1
session1> INSERT INTO T1 VALUES (2, NULL); -- <= Deadlock !

引用自:https://dba.stackexchange.com/questions/11010