选择 打开 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0
历史版本PostgreSQL 9.0 已于 2015 年 10 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本

45.50. pg_locks #

视图pg_locks提供了对数据库服务器中打开的事务持有的锁的信息的访问。有关锁定的更多讨论,请参见第 13 章

pg_locks包含每个活动的可锁定对象、请求的锁模式和相关事务的一行。 因此,如果多个事务正在持有或等待锁定它,同一可锁定对象可能会出现多次。 但是,当前没有任何锁定的对象将不会出现。

有几种不同类型的可锁定对象:整个关系(例如,表)、关系的单个页面、关系的单个元组、事务 ID(虚拟和永久 ID 均包括),以及一般的数据库对象(由类 OID 和对象 OID 标识,与pg_descriptionpg_depend中的方式相同)。此外,扩展一个关系的权限被表示为一个单独的可锁定对象。

表 45.51. pg_locks Columns

名称 类型 引用 描述
locktype text   可锁定对象的类型:relationextendpagetupletransactionidvirtualxidobjectuserlockadvisory
database oid pg_database.oid 锁目标存在的数据库的OID,如果目标是一个共享对象则为0,如果目标是一个事务ID则为 NULL
relation oid pg_class.oid 作为锁目标的关系的OID,如果目标既不是关系,也不是关系的一部分则此列为 NULL
page integer   作为锁目标的页在关系中的页号,如果目标不是一个关系页或元组则此列为 NULL
tuple smallint   作为锁目标的元组在页中的元组号,如果目标不是一个元组则此列为 NULL
virtualxid text   锁定目标事务的虚拟 ID,如果目标不是虚拟事务 ID,则为 NULL
transactionid xid   锁定目标事务的标识,如果目标不是事务 ID,则为 NULL
classid oid pg_class.oid 包含锁目标的系统目录的OID,如果目标不是一个普通数据库对象则此列为 NULL
objid oid 任意 OID 列 锁目标在它的系统目录中的OID,如果目标不是一个普通数据库对象则为 NULL
objsubid smallint   对于一个表列,这里是列号(objidclassid指表本身)。对于所有其他对象类型,此列为0。
virtualtransaction text   保持这个锁或者正在等待这个锁的事务的虚拟ID
pid integer   保持这个锁或者正在等待这个锁的服务器进程的PID,如果此锁被一个预备事务所持有则此列为 NULL
mode text   此进程已持有或者希望持有的锁模式的名称(参见第 13.3.1 节
granted boolean   如果锁已授予则为真,如果锁被等待则为假

在表示由指定事务持有的锁的行中,granted 为真。为假表示该事务当前正在等待获取此锁, 这意味着某个其他事务正在同一可锁定对象上持有冲突的锁模式。等待的事务会休眠,直到另一个锁被释放 (或检测到死锁情况)。单个事务一次最多只能等待获取一个锁。

每个事务在其整个持续期内都对其虚拟事务ID持有独占锁。如果为事务分配了永久ID (通常仅在事务改变数据库状态时才会发生),它还会对其永久事务ID持有独占锁直到事务结束。 当一个事务发现有必要专门等待另一个事务时,它会尝试获取另一个事务ID(根据情况是虚拟ID还是永久ID) 的共享锁。只有当另一个事务终止并释放其锁时,这才会成功。

虽然元组是一种可锁定的对象类型,但关于行级锁的信息存储在磁盘上,而不是内存中,因此行级锁通常不会出现在此视图中。 如果一个事务正在等待行级锁,它通常会出现在视图中,等待当前持有该行锁的永久事务ID。

咨询锁可以在由单个bigint值或两个整数值组成的键上获取。一个bigint键在classid列中显示其高位半部分,在objid列中显示其低位半部分,并且objsubid等于 1。整数键在classid列中显示第一个键,在objid列中显示第二个键,并且objsubid等于 2。键的实际含义由用户自行决定。咨询锁在每个数据库内都是本地的,因此database列对于咨询锁是有意义的。

当访问pg_locks视图时,内部锁管理器数据结构会被短暂锁定,并为该视图制作一份要显示的拷贝。这确保该视图产生一致的结果集,同时不会在不必要的时间内阻塞正常的锁管理器操作。尽管如此,如果频繁访问这个视图,可能会对数据库性能产生一些影响。

pg_locks提供了集簇中所有锁的全局视图,不仅包括与当前数据库相关的锁。 虽然它的relation列可以与pg_class.oid 连接来识别被锁定的关系,但这仅对当前数据库中的关系有效(即 database 列为当前数据库的 OID 或零的那些关系)。

pid列可以与pg_stat_activity视图的procpid列进行连接,以获取有关持有锁或等待持有每个锁的会话的更多信息,例如

SELECT * FROM pg_locks pl LEFT JOIN pg_stat_activity psa
    ON pl.pid = psa.procpid;

另外,如果您正在使用预备事务,virtualtransaction列可以与pg_prepared_xacts视图的transaction列进行连接,以获取有关持有锁的预备事务的更多信息。(预备事务永远不会等待锁,但它继续持有其在运行时获取的锁。)例如:

SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
    ON pl.virtualtransaction = '-1/' || ppx.transaction;

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。