当前位置:   article > 正文

1.5 观察死锁_deadlock detected detail: process 2863228 waits fo

deadlock detected detail: process 2863228 waits for sharelock

如果两个事务不得不相互等待,就将会发生一次死锁

首先创建一个测试表:

CREATE TABLE t_deadlock (
    id int
);


INSERT INTO t_deadlock
VALUES
    (1),
    (2);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
事务1事务 2
BEGIN;BEGIN;
SELECT * FROM t_deadlock WHERE id = 1 FOR UPDATE;
SELECT * FROM t_deadlock WHERE id = 2 FOR UPDATE;
SELECT * FROM t_deadlock WHERE id = 2 FOR UPDATE;
等待事务2SELECT * FROM t_deadlock WHERE id = 1 FOR UPDATE;
等待事务2等待事务1
1秒(deadlock_timeout)以后死锁解除
【注1】
COMMIT;ROLLBACK;

一旦检测到死锁,将会报错如下:

ERROR:  deadlock detected
DETAIL:  Process 6864 waits for ShareLock on transaction 669; blocked by process 6830.
Process 6830 waits for ShareLock on transaction 670; blocked by process 6864.
HINT:  See server log for query details.
CONTEXT:  while updating tuple (0,1) in relation "t_deadlock"
  • 1
  • 2
  • 3
  • 4
  • 5

PostgreSQL会告诉我们哪一行导致了冲突。在本例中,根源是元组(0, 1),这里能看到的是一个ctid,它告诉我们一行在表中的物理位置,在这里是第一块(0)中的第一行。

【注1】:如果在此处执行如下查询,可得:

SELECT 
    pid, 
    state, 
    query 
FROM 
    pg_stat_activity 
WHERE pid in (6830, 6864);

 pid  |             state             |                       query
------+-------------------------------+---------------------------------------------------
 6830 | active                        | SELECT                                           +
      |                               |     pid,                                         +
      |                               |     state,                                       +
      |                               |     query                                        +
      |                               | FROM                                             +
      |                               |     pg_stat_activity                             +
      |                               | WHERE pid in (6830, 6864);
 6864 | idle in transaction (aborted) | SELECT
      |                               |     *                                            +
      |                               | FROM                                             +
      |                               |     t_deadlock                                   +
      |                               | WHERE id = 1 FOR UPDATE;                         +
(2 rows)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

如果这一行对用户的事务还可见,甚至可以查询到这一行:

SELECT
    ctid,
    *
FROM
    t_deadlock
WHERE ctid = '(0, 1)';

  ctid  | id
--------+----
 (0,1) |  1
(1 row)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

如果这一行已经被删除或者修改,这个查询是不会返回该行的。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/511842
推荐阅读
相关标签
  

闽ICP备14008679号