deadlock_timeout 配置參數在 Postgresql 中檢測到什麼樣的死鎖?
我的總體目標是在
40P01/ERRCODE_T_R_DEADLOCK_DETECTED
檢測到死鎖時從 postgres 獲取一個。(更準確地說,我想在 Hibernate 中獲取 LockAcquisitionException,這是40P01/ERRCODE_T_R_DEADLOCK_DETECTED
錯誤程式碼在PostgreSQL81Dialect.java中翻譯的異常)我使用 Postgresql 9.6。為此,我認為我應該按照19.12
deadlock_timeout
的建議設置和log_lock_waits
配置變數。鎖管理
deadlock_timeout
(整數)這是在檢查是否存在死鎖條件之前等待鎖定的時間量,以毫秒為單位。$$ … $$ 設置時
log_lock_waits
,此參數還確定在發出有關鎖定等待的日誌消息之前等待的時間長度。如果您正在嘗試調查鎖定延遲,您可能需要設置比正常更短的deadlock_timeout
.我在 postgresql.conf 中設置了以下值
log_lock_waits = on # log lock waits >= deadlock_timeout deadlock_timeout = 5s
現在,當我創建一個死鎖情況(從 Java 使用 Hibernate)時,我在 postgresql.log 中找到以下內容
LOG: process 17493 still waiting for ShareLock on transaction 322815 after 5000.464 ms DETAIL: Process holding the lock: 17495. Wait queue: 17493. CONTEXT: while updating tuple (132,35) in relation "publication"
但是不會
40P01/ERRCODE_T_R_DEADLOCK_DETECTED
產生錯誤(並發送到 JDBC 驅動程序)。我深入研究了 postgres 原始碼,發現通過設置完成的死鎖檢測
deadlock_timeout/log_lock_waits
與生成的機制不同40P01/ERRCODE_T_R_DEADLOCK_DETECTED
。deadlock_timeout
案例在 backend/storage/lmgr/proc.c中處理 ,而案例40P01/ERRCODE_T_R_DEADLOCK_DETECTED
在backend/storage/lmgr/deadlock.c所以,我的問題是:
- 這實際上是檢測到的兩種不同類型的死鎖嗎?
deadlock_timeout
當基於死鎖檢測發生時,有沒有辦法得到錯誤?- 實際上如何才能
ERRCODE_T_R_DEADLOCK_DETECTED
強制發生錯誤?更新:我用來進入死鎖情況的程式碼是這樣的(Spring/Java):
// This is in a Transaction managed by spring Publication p = em.find(Publication.class, id); p.setComment("Outer "+new Date()); em.flush(); // This utility method runs the lambda expression in a new Transaction // using Spring's TransactionTemplate and tries to update // the same Publication that is about to be updated by the // "outer" transaction Utils.runInSeparateTransaction(status -> { Publication p2 = em.find(p.getClass(), p.getMtid()); p2.setComment("Inner "+new Date()); return p2; // Would flush/commit after the return, but will "hang" instead. // Here I would expect the deadlock error but only get the // deadlock log. }; // Outer transaction would commit at this point but will
死鎖是指多個事務在它們交叉獲取的鎖中相互衝突的情況。如果不中止其中一項交易,就不可能解決這種情況。引擎中止這樣的事務並
ERRCODE_T_R_DEADLOCK_DETECTED
出現錯誤。這
log_lock_waits
主要與死鎖無關,它旨在提醒某些查詢卡在等待鎖定的情況,這意味著其他事務保持鎖定的時間過長。這實際上是檢測到的兩種不同類型的死鎖嗎?
不,您似乎在這裡混淆了鎖和死鎖。
當基於 deadlock_timeout 的死鎖檢測發生時,有沒有辦法得到錯誤?
它是自動的。如果沒有出現該錯誤,那是因為沒有死鎖。
實際上如何強制發生 ERRCODE_T_R_DEADLOCK_DETECTED 錯誤?
通過創建一個至少有兩個事務衝突的實際死鎖。有關簡單範例,請參見postgres deadlock without explicit lock on SO。