使用 pgadmin 检查 Postgres 咨询锁的状态

Ram*_*hum 4 django postgresql pgadmin

我正在尝试在我的 Django 应用程序中使用 Postgres 咨询锁,但似乎获取已被冻结。

我想使用pgadminGUI 来查看获取了哪些锁,哪些没有。我尝试使用它,然后导航到pg_locks并在那里环顾了一会儿,但我找不到在哪里可以看到获取了哪些锁。我怎么能看到呢?

Cra*_*ger 5

咨询锁中列出pg_locks,以locktype = advisoryobjid含有该锁定的值:

regress=> SELECT pg_advisory_lock(12345);
 pg_advisory_lock 
------------------

(1 row)

regress=> SELECT * FROM pg_locks;
  locktype  | database | relation | page | tuple | virtualxid | transactionid | classid | objid | objsubid | virtualtransaction |  pid  |      mode       | granted | fastpath 
------------+----------+----------+------+-------+------------+---------------+---------+-------+----------+--------------------+-------+-----------------+---------+----------
 relation   |   144654 |    11090 |      |       |            |               |         |       |          | 2/24979            | 22097 | AccessShareLock | t       | t
 virtualxid |          |          |      |       | 2/24979    |               |         |       |          | 2/24979            | 22097 | ExclusiveLock   | t       | t
 advisory   |   144654 |          |      |       |            |               |       0 | 12345 |        1 | 2/24979            | 22097 | ExclusiveLock   | t       | f
(3 rows)

regress=> SELECT objid, mode, granted FROM pg_locks WHERE locktype = 'advisory';
 objid |     mode      | granted 
-------+---------------+---------
   456 | ExclusiveLock | t
 12345 | ExclusiveLock | t
(2 rows)
Run Code Online (Sandbox Code Playgroud)

对于二值锁,第一部分是 inclassidobjsubidis 2(而不是1单参数锁):

regress=> SELECT pg_advisory_lock(123, 456);
 pg_advisory_lock 
------------------

(1 row)

regress=> SELECT classid, objid, mode, granted, objsubid FROM pg_locks WHERE locktype = 'advisory';
 classid | objid |     mode      | granted | objsubid
---------+-------+---------------+--------------------
     123 |   456 | ExclusiveLock | t       | 2
(1 row)
Run Code Online (Sandbox Code Playgroud)

更新

mode字段是锁定模式。

regress=> SELECT pg_advisory_lock_shared(1234);
 pg_advisory_lock_shared 
-------------------------

(1 row)

regress=> SELECT classid, objid, objsubid, mode, granted FROM pg_locks WHERE locktype = 'advisory';
 classid | objid | objsubid |   mode    | granted 
---------+-------+----------+-----------+---------
       0 |  1234 |        1 | ShareLock | t
(1 row)
Run Code Online (Sandbox Code Playgroud)

如果根本没有获取给定的锁,那么它就没有行。

regress=> SELECT classid, objid, objsubid, mode, granted 
          FROM pg_locks 
          WHERE locktype = 'advisory' 
            AND objsubid = 1  /* One-argument form lock */
            AND objid = 1235; /* argument = 1235 */

 classid | objid | objsubid | mode | granted 
---------+-------+----------+------+---------
(0 rows)
Run Code Online (Sandbox Code Playgroud)

如果一个锁被阻塞等待另一个会话,它会有granted = 'f'.

您可以使用该pid字段查看哪个进程 ID 持有/正在尝试获取锁。加入pg_stat_activity可能很有用,自加入也pg_locks可以查看哪个会话阻止了给定的锁。

有关详细信息,请参阅用户手册pg_locks