来自不直接相关表的 Postgresql 死锁
Postgresql deadlock from not directly related tables
运行 postgresql 11.2
我有 3 个表,Table1、Table2 和 Table3。
表 2 和表 3 link编辑到表 1。
所以,两者都有一个外键和一个字段:
"fk38dc51d86836z0e5" FOREIGN KEY (table1_id) REFERENCES table1(id)
我最近在这 2 个表上遇到了死锁,尽管涉及的查询没有使用外键字段。
Process 19819 waits for ShareLock on transaction 254244062; blocked by process 19930.
Process 19930 waits for ShareLock on transaction 254244063; blocked by process 19819.
Process 19819: update Table1 set lastUpdated=, user_id= where id=
Process 19930: update Table2 set lastUpdated=, version=, content=, extra= where id= and version=
这 2 个表之间唯一的 link 是它们对表 1 的 link。他们没有直接 link 相互联系。
但这两个查询都没有将 Table1 的外键用作查询的一部分。
这是怎么回事?为什么会出现僵局?
如果没有外键,可能会发生死锁:最可能的原因是 2 个并发事务在相同的行上以不同的顺序获取相同的锁。
例如在会话 1 中:
postgres=# begin;
BEGIN
postgres=# update t1 set x=1 where x=0;
UPDATE 1
postgres=# update t2 set x=1 where x=0;
UPDATE 1
postgres=#
在第 2 节中:
postgres=# begin;
BEGIN
postgres=# update t2 set x=2 where x=0;
UPDATE 1
postgres=# update t1 set x=2 where x=0;
ERROR: deadlock detected
DETAIL: Process 26871 waits for ShareLock on transaction 191533; blocked by process 26777.
Process 26777 waits for ShareLock on transaction 191534; blocked by process 26871.
HINT: See server log for query details.
CONTEXT: while updating tuple (0,3) in relation "t1"
postgres=#
运行 postgresql 11.2
我有 3 个表,Table1、Table2 和 Table3。
表 2 和表 3 link编辑到表 1。
所以,两者都有一个外键和一个字段:
"fk38dc51d86836z0e5" FOREIGN KEY (table1_id) REFERENCES table1(id)
我最近在这 2 个表上遇到了死锁,尽管涉及的查询没有使用外键字段。
Process 19819 waits for ShareLock on transaction 254244062; blocked by process 19930.
Process 19930 waits for ShareLock on transaction 254244063; blocked by process 19819.
Process 19819: update Table1 set lastUpdated=, user_id= where id=
Process 19930: update Table2 set lastUpdated=, version=, content=, extra= where id= and version=
这 2 个表之间唯一的 link 是它们对表 1 的 link。他们没有直接 link 相互联系。
但这两个查询都没有将 Table1 的外键用作查询的一部分。
这是怎么回事?为什么会出现僵局?
如果没有外键,可能会发生死锁:最可能的原因是 2 个并发事务在相同的行上以不同的顺序获取相同的锁。
例如在会话 1 中:
postgres=# begin;
BEGIN
postgres=# update t1 set x=1 where x=0;
UPDATE 1
postgres=# update t2 set x=1 where x=0;
UPDATE 1
postgres=#
在第 2 节中:
postgres=# begin;
BEGIN
postgres=# update t2 set x=2 where x=0;
UPDATE 1
postgres=# update t1 set x=2 where x=0;
ERROR: deadlock detected
DETAIL: Process 26871 waits for ShareLock on transaction 191533; blocked by process 26777.
Process 26777 waits for ShareLock on transaction 191534; blocked by process 26871.
HINT: See server log for query details.
CONTEXT: while updating tuple (0,3) in relation "t1"
postgres=#