# 52.74.pg_locks

The viewpg_locksprovides access to information about the locks held by active processes within the database server. SeeChapter 13for more discussion of locking.

pg_lockscontains one row per active lockable object, requested lock mode, and relevant process. Thus, the same lockable object might appear many times, if multiple processes are holding or waiting for locks on it. However, an object that currently has no locks on it will not appear at all.

There are several distinct types of lockable objects: whole relations (e.g., tables), individual pages of relations, individual tuples of relations, transaction IDs (both virtual and permanent IDs), and general database objects (identified by class OID and object OID, in the same way as inpg_descriptionorpg_depend). Also, the right to extend a relation is represented as a separate lockable object, as is the right to updatepg_database.datfrozenxid. Also, “advisory” locks can be taken on numbers that have user-defined meanings.

Table 52.75.pg_locksColumns

Column Type

Description
locktype text

Type of the lockable object:relation,延长,冻结ID,,元组,交易标识,虚拟xid,幽灵,目的,用户锁, 或者咨询.(也可以看看表 28.11.)
数据库 样的(参考pg_database.样的)

锁定目标所在的数据库的 OID,如果目标是共享对象,则为零,如果目标是事务 ID,则为 null
关系 样的(参考pg_class.样的)

锁定目标关系的 OID,如果目标不是关系或关系的一部分,则为 null
整数4

关系中锁定目标的页码,如果目标不是关系页或元组,则为 null
元组 整数2

页面内锁定目标的元组编号,如果目标不是元组,则为 null
虚拟xid 文本

锁所针对的事务的虚拟 ID,如果目标不是虚拟事务 ID,则为 null
交易标识 xid

锁所针对的事务的 ID,如果目标不是事务 ID,则为 null
班级号 样的(参考pg_class.样的)

包含锁定目标的系统目录的 OID,如果目标不是一般数据库对象,则为 null
对象 样的(引用任何 OID 列)

锁定目标在其系统目录中的 OID,如果目标不是通用数据库对象,则为 null
objsubid 整数2

锁定目标的列号(班级号对象引用表本身),如果目标是某个其他通用数据库对象,则为零,如果目标不是通用数据库对象,则为 null
虚拟交易 文本

持有或等待此锁的事务的虚拟 ID
pid 整数4

持有或等待此锁的服务器进程的进程 ID,如果锁由准备好的事务持有,则为 null
模式 文本

此进程持有或需要的锁定模式的名称(请参阅第 13.3.1 节第 13.2.3 节)
的确 布尔

True if lock is held, false if lock is awaited
fastpath bool

True if lock was taken via fast path, false if taken via main lock table
waitstart timestamptz

Time when the server process started waiting for this lock, or null if the lock is held. Note that this can be null for a very short period of time after the wait started even thoughgrantedisfalse.

grantedis true in a row representing a lock held by the indicated process. False indicates that this process is currently waiting to acquire this lock, which implies that at least one other process is holding or waiting for a conflicting lock mode on the same lockable object. The waiting process will sleep until the other lock is released (or a deadlock situation is detected). A single process can be waiting to acquire at most one lock at a time.

Throughout running a transaction, a server process holds an exclusive lock on the transaction's virtual transaction ID. If a permanent ID is assigned to the transaction (which normally happens only if the transaction changes the state of the database), it also holds an exclusive lock on the transaction's permanent transaction ID until it ends. When a process finds it necessary to wait specifically for another transaction to end, it does so by attempting to acquire share lock on the other transaction's ID (either virtual or permanent ID depending on the situation). That will succeed only when the other transaction terminates and releases its locks.

Although tuples are a lockable type of object, information about row-level locks is stored on disk, not in memory, and therefore row-level locks normally do not appear in this view. If a process is waiting for a row-level lock, it will usually appear in the view as waiting for the permanent transaction ID of the current holder of that row lock.

Advisory locks can be acquired on keys consisting of either a singlebigintvalue or two integer values. Abigintkey is displayed with its high-order half in theclassidcolumn, its low-order half in theobjidcolumn, andobjsubidequal to 1. The originalbigintvalue can be reassembled with the expression(classid::bigint << 32) |objid::bigint.整数键与第一个键一起显示班级号列中的第二个键对象列,和objsubid等于 2.键的实际含义由用户决定。咨询锁对于每个数据库都是本地的,因此数据库列对于咨询锁有意义。

pg_locks提供数据库集群中所有锁的全局视图,而不仅仅是与当前数据库相关的锁。虽然它的关系列可以加入反对pg_class.样的要识别锁定的关系,这只会对当前数据库中的关系正常工作(那些数据库列是当前数据库的 OID 或零)。

pid列可以连接到pid的列pg_stat_activity查看以获取有关会话持有或等待每个锁的更多信息,例如

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

此外,如果您使用准备好的事务,则virtualtransactioncolumn can be joined to thetransactioncolumn of thepg_prepared_xactsview to get more information on prepared transactions that hold locks. (A prepared transaction can never be waiting for a lock, but it continues to hold the locks it acquired while running.) For example:

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

While it is possible to obtain information about which processes block which other processes by joiningpg_locksagainst itself, this is very difficult to get right in detail. Such a query would have to encode knowledge about which lock modes conflict with which others. Worse, thepg_locksview does not expose information about which processes are ahead of which others in lock wait queues, nor information about which processes are parallel workers running on behalf of which other client sessions. It is better to use thepg_blocking_pids()function (seeTable 9.65) to identify which process(es) a waiting process is blocked behind.

Thepg_locksview displays data from both the regular lock manager and the predicate lock manager, which are separate systems; in addition, the regular lock manager subdivides its locks into regular andfast-pathlocks. This data is not guaranteed to be entirely consistent. When the view is queried, data on fast-path locks (withfastpath=true) is gathered from each backend one at a time, without freezing the state of the entire lock manager, so it is possible for locks to be taken or released while information is gathered. Note, however, that these locks are known not to conflict with any other lock currently in place. After all backends have been queried for fast-path locks, the remainder of the regular lock manager is locked as a unit, and a consistent snapshot of all remaining locks is collected as an atomic action. After unlocking the regular lock manager, the predicate lock manager is similarly locked and all predicate locks are collected as an atomic action. Thus, with the exception of fast-path locks, each lock manager will deliver a consistent set of results, but as we do not lock both lock managers simultaneously, it is possible for locks to be taken or released after we interrogate the regular lock manager and before we interrogate the predicate lock manager.

Locking the regular and/or predicate lock manager could have some impact on database performance if this view is very frequently accessed. The locks are held only for the minimum amount of time necessary to obtain data from the lock managers, but this does not completely eliminate the possibility of a performance impact.