Oracle 11g 尋找死鎖,也許是外鍵?
我試圖了解為什麼我的數據庫會出現死鎖。跟踪告訴我同一張表上的兩個更新正在鎖定。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,這應該可以幫助您縮小對鎖定負責的表/外鍵。一旦您知道哪個表受死鎖影響,請確保對該表的所有外鍵引用都已正確索引。如果您的範例中的 EG
T2.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 !