“檢測到死鎖”真的是一個錯誤嗎?我應該在處理它們後壓制它們嗎?
不久前,我花了數週的噩夢來處理“檢測到死鎖”並試圖弄清楚如何處理它。我最終以這樣一種方式處理它,即我的程式碼能夠檢測到它何時發生,然後在每次重試之間以 50000 微秒無限期地重試相同的查詢,直到它起作用。
也許這是不好的做法,但到目前為止(幾個月),除了記錄“檢測到的死鎖”所謂的“錯誤”之外,它沒有引起任何問題。
我現在是否可以通過將“檢測到死鎖”錯誤標記為“不重要”來抑制“檢測到死鎖”錯誤,因此即使它們仍然登錄到我的錯誤日誌表中也不會顯示給我?
請不要告訴我“首先避免它們”。這根本不可能。如果您在同一個表/事物上進行並發(多個程序/腳本實例),它們顯然*會發生。*我一直在嘗試“將它們編碼”,但這似乎是不可能的。
顯然,由於我問的是這個而不是僅僅添加忽略規則並完成它,我確實關心答案/響應。儘管如此,我認為目前我不能確信它們可以完全避免。我並不是說我每小時記錄數千個或其他任何內容,而是每天記錄一些,似乎總是在開始時我確實有很多並發程序在同一個表/查詢上工作。
死鎖是一種序列化錯誤:您沒有做任何禁止的事情,只是碰巧與其他活動事務的互動阻止了您的事務完成。你的反應是正確的:重試交易。在重試之前絕對不需要等待。
我同意,對於較大事務的足夠複雜的工作負載,幾乎不可能完全排除死鎖。只要它們很少發生,如果您正確處理它們,它們就不是真正的問題。
如果死鎖發生得太頻繁,它們就會開始成為一個問題:這意味著您必須重做大量工作,這對性能不利並且會給您的數據庫帶來額外的負載。此外,在解決死鎖之前等待一秒鍾意味著鎖被持有很長時間(一秒鐘很長),這對於並發性來說並不是很好。
即使不能完全擺脫死鎖,也可以採取措施減少死鎖:
- 看到你的交易很短
- 嘗試減少每個事務的數據修改次數
兩者都將減少陷入僵局的可能性。
忽略日誌文件中的死鎖錯誤是安全的,但是您應該監控
pg_stat_database.deadlocks
每小時死鎖計數增加超過可接受的數量並採取措施。您看到反對將死鎖稱為錯誤。根據定義,錯誤是中止 SQL 語句執行的條件。所以死鎖顯然是一個錯誤。