Postgresql
Postgres 9.5死鎖,一個表上有很多更新+另一個表上有很多“選擇更新”
我有兩張桌子:“機器”和“魔法工具”。“magictools”指的是帶有外鍵的“機器”。
在執行其中許多請求時,我遇到了死鎖問題:
//this will produce an "AccessExclusiveLock" of type "tuple" on machines SELECT FROM * machines FOR UPDATE where id = :id; //this will produce a "RowExclusiveLock" on magictools and a "RowShareLock" on machines UPDATE magictools SET collections = "large-json" where id = :id
據我了解,執行其中許多請求會產生死鎖。也許只是執行此操作的更新,我不知道。在這種情況下我應該如何避免死鎖?
我在這些表上有很多索引,也許我有太多索引?
以下是問題發生時 pg_activity 的報告。我不明白不同的模式和鎖類型,只是,這裡發生了什麼?是否有可能只是沒有任何事務的更新導致死鎖?
沒有確定性
ORDER BY
:SELECT FROM * machines FOR UPDATE;
因此,多個事務可能會嘗試以不同(任意)順序和互鎖來獲取行鎖。
另外,為什麼要鎖定整個表
machines
以進行單個更新magictools
?如果它確實是每個事務的單個UPDATE
,magictools
則根本不需要machines
手動鎖定行。只需放下命令。(如果有多個,那麼你的問題是缺乏的。)如果有充分的理由將許多或所有行鎖定在 中
machines
,請以確定的順序執行,例如:SELECT FROM * machines ORDER BY id FOR UPDATE;
或者鎖定整個表,這也更便宜:
LOCK TABLE machines IN SHARE MODE;
SHARE MODE
對於您擁有的 FK 案例來說已經足夠了。手冊中甚至有一個例子也暗示了這一點。
INSERT
當然,與範例中的行級鎖不同,鎖定表也不允許。