我正在尝试获取pg_locks
与当前交易相关的列表
例如
> BEGIN;
BEGIN
> ALTER TABLE ... ;
ALTER TABLE
> select locktype,virtualxid,transactionid,mode,relation from pg_locks;
locktype | virtualxid | transactionid | mode | relation
------------+------------+---------------+---------------------+----------
relation | [NULL] | [NULL] | AccessShareLock | 11695
virtualxid | 2/24699 | [NULL] | ExclusiveLock | [NULL]
relation | [NULL] | [NULL] | AccessExclusiveLock | 801091
(3 rows)
好吧,我认为这里的“我的”锁是最后一个,AccessExclusiveLock
但它没有transactionid
或virtualxid
。
如果数据库中有其他活动,我也会在此列表中看到其他锁。
如果它们的事务 ID 为空,我如何过滤掉属于我当前事务的锁?
我找到了答案。
这有两个部分。
首先,重要的是
virtualtransaction
而不是virtualxid
。尽管virtualxid
和transactionid
对于我关心的所有内容都是空的,但它们都共享一个virtualtransaction
ID。其次,尽管
txid_current()
返回 atransactionid
,这似乎无济于事,因为我的锁都为空,但我们仍然可以使用它来获得我们想要的东西。发生的事情是当你调用
txid_current()
postgres 为该函数返回的锁分配一个锁时transactionid
,如果我们查询pg_locks
. 此锁将virtualtransaction
与当前事务中的所有其他内容共享一个 id。例如:
所以现在我们可以从中获取
virtualtransaction
当前事务中所有内容共享的 id,并对其进行过滤。换句话说:
...将只返回与当前事务相关的锁。
这个怎么样:
看看这是否有帮助:
它将显示表名,而where granted = false显示未授予访问权限的位置(即存在锁)。
此外,您还可以在 BASH 中获取当前的 PID:
$(回声$$;回声$BASHPID)
在 shell (bash) 中获取 pid
这里有一些用于监控锁的有用查询: Lock Monitoring