TRUNCATE 应该很快,除非它无法获取对象上的 AccessExclusiveLock,在这种情况下它可以无限期地等待。
上面提到的应该显示阻塞会话的查询没有识别对象级锁,这是 TRUNCATE 获取的那种锁。
这里提到过,我假设这个查询是从哪里获取的:
https://wiki.postgresql.org/wiki/Lock_Monitoring
以下查询可能有助于查看哪些进程正在阻塞
SQL 语句(这些只查找行级锁,而不是对象级锁)
锁)。
这是 PG 9.1 问题的演示:
第 1 场会议:
test=> create table footable(id int);
CREATE TABLE
test=> begin;
BEGIN
test=> insert into footable values(1);
INSERT 0 1
test=>
(未提交)
第 2 场会议
test=> truncate table footable;
(被会话 #1 阻止)
第 3 场会议
test=> SELECT bl.pid AS blocked_pid,
a.usename AS blocked_user,
kl.pid AS blocking_pid,
ka.usename AS blocking_user,
a.current_query AS blocked_statement
FROM pg_catalog.pg_locks bl
JOIN pg_catalog.pg_stat_activity a ON a.procpid = bl.pid
JOIN pg_catalog.pg_locks kl ON kl.transactionid = bl.transactionid AND kl.pid != bl.pid
JOIN pg_catalog.pg_stat_activity ka ON ka.procpid = kl.pid
WHERE NOT bl.GRANTED;
blocked_pid | blocked_user | blocking_pid | blocking_user | blocked_statement
-------------+--------------+--------------+---------------+-------------------
(0 rows)
根据这个查询,没有会话被阻塞,所以显然是错误的。
我建议您在此处尝试其他查询:
https://wiki.postgresql.org/wiki/Find_Locks
在这个例子中,产生这个输出:
-[ RECORD 1 ]------+--------------------
locktype | relation
database | 113270
relation | 2660062
page |
tuple |
virtualxid |
transactionid |
classid |
objid |
objsubid |
virtualtransaction | 5/2548
pid | 4419
mode | AccessExclusiveLock
granted | f
virtualtransaction | 4/2031
pid | 31775
mode | RowExclusiveLock
granted | t