我正在使用 Postgresql 11。
我在日志中发现了类似于以下内容的错误:
org.postgresql.util.PSQLException: ERROR: deadlock detected
Detail: Process 332091 waits for ShareLock on transaction 99896257; blocked by process 332093.
Process 332093 waits for ShareLock on transaction 99923910; blocked by process 332091.
Hint: See server log for query details.
Where: while locking tuple (884208,33) in relation "tab_1"
SQL statement "SELECT 1 FROM ONLY "sch"."tab_1" x WHERE "tab_1_key" OPERATOR(pg_catalog.=) $1 FOR KEY SHARE OF x"
SQL statement "INSERT INTO sch.tab_2 (col1, col2, ..., coln)
SELECT
col1,
col2,
...
coln
FROM
sch.tab_3
LEFT JOIN sch.tab_4
ON tab_4.id = tab_3.id
LEFT JOIN sch.tab_5
ON tab_5.id = tab_3.id
所以基本上第一个查询看起来像一些数据库内部查询,我的代码没有。
似乎它使我的查询陷入僵局。但它们与任何表都不相关。
在这种情况下如何跟踪死锁原因的任何想法?
这些查询由实现外键约束的触发器在内部生成。
例如,在具有外键约束的表中添加一行,会在被引用表的对应行上添加这样的键共享锁,这样在插入事务完成之前,任何人都无法删除它或修改主键。
这可能会导致修改两个表的事务之间出现死锁。
在搜索有问题的语句时,不要忘记获取问题锁的不一定是事务中的最后一条语句(显示在日志消息中)。
一种方法是设置
log_min_duration_statement
为 0,当死锁再次发生时,检查受影响事务运行的所有语句。另一种方法是查看应用程序代码以找出在事务中执行了哪些语句。