You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL中执行TRUNCATE大表时无法看到对应表的锁信息

问题描述

我正在对一个容量达数TB的大表执行TRUNCATE操作,为确认不存在锁问题,我在另一个窗口执行了如下查询,但结果中未显示被截断表的锁信息,请问这是为什么?

查询语句:

select  c.relname,
l.locktype,
l.pid,
l.mode,
l.granted   FROM pg_locks l
 JOIN pg_class c ON l.relation = c.oid;

查询结果:

relname              | locktype | pid  |      mode       | granted 
-----------------------------------+----------+------+-----------------+---------
 pg_class_tblspc_relfilenode_index | relation | 6931 | AccessShareLock | t
 pg_class_relname_nsp_index        | relation | 6931 | AccessShareLock | t
 pg_class_oid_index                | relation | 6931 | AccessShareLock | t
 pg_class                          | relation | 6931 | AccessShareLock | t
 pg_locks                          | relation | 6931 | AccessShareLock | t
原因分析
  • TRUNCATE锁持有时间极短:PostgreSQL中TRUNCATE属于DDL操作,它会先获取目标表的ACCESS EXCLUSIVE锁,但这个锁仅在修改表元数据、清理目录项的阶段持有。对于大表,实际的磁盘文件清理是后台异步执行的,锁会在这一步开始前就被释放。如果你的查询是在锁释放后执行的,自然看不到目标表的锁记录。

  • 查询未覆盖完整命名空间:你的查询通过JOIN pg_class关联表名,但如果目标表不在当前search_path指定的模式下,或者未显式匹配表所在的命名空间,可能无法通过relname匹配到目标表。可以修改查询,显示完整的表名(含模式)来排查:

    select  n.nspname || '.' || c.relname as full_relname,
            l.locktype,
            l.pid,
            l.mode,
            l.granted,
            l.relation
    FROM pg_locks l
    LEFT JOIN pg_class c ON l.relation = c.oid
    LEFT JOIN pg_namespace n ON c.relnamespace = n.oid;
    
  • TRUNCATE操作已完成:如果TRUNCATE已经执行完毕(包括后台清理流程),锁会被彻底释放,查询结果中不会留存相关记录。可以通过查询目标表的行数、磁盘占用量来确认操作是否结束。

内容的提问来源于stack exchange,提问作者Jayadevan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 23:49:59