PG基础篇--逻辑结构管理(锁机制)
Posted 进击的CJR
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PG基础篇--逻辑结构管理(锁机制)相关的知识,希望对你有一定的参考价值。
行锁分类
行锁只有共享锁和排它锁,pg不称读锁的原因是由于有多版本的实现,实际读取数据时,并不会在行上执行任何锁
死锁
死锁发生的四个必要条件
(1)互斥条件:指事务对所分配到的资源加了排它锁,即在一段时间内只能由一个事务加锁占用,如果此时还有其他进程进行排它锁,则请求者只能等待,直至持有排它锁的事务释放排它锁。
(2)请求和保持条件:指事务已经至少持有了一把排它锁,但又提出了新的排它锁请求,而该资源上的排它锁已被其他事务占有,此时请求被阻塞,但同时它对自己已获得的排它锁又持有不放。
(3)不剥夺条件:指事务已获得在未使用完之前不能被其他进程剥夺,只能在使用完时由自己释放。
(4)环路等待条件:指发生死锁时,必然存在一个事务--资源的环形链。
表级锁命令LOCK TABLE
LOCK [ TABLE ] [ ONLY ] name [ * ] [, ...] [ IN lockmode MODE ] [ NOWAIT ]
name:表名
lockmode:表级锁级别,共8种
nowait:如果没有该关键字,无法获得锁时会一直等待。而如果加入了nowait关键字,在无法立即获取该锁时,此命令会立即退出并报错。
在PG中自己持有的锁是从不冲突的。
行级锁命令
select for update|share [of table_name,[],.....] [nowait]
nowait和表级锁使用含义相同
锁查看
查看一个事务产生了哪些锁,哪个事务被哪个事务阻塞了,通过查询系统视图pg_locks来得到。
Column | Type | Collation | Nullable | Default
--------------------+----------+-----------+----------+---------
locktype | text | | |
database | oid | | |
relation | oid | | |
page | integer | | |
tuple | smallint | | |
virtualxid | text | | |
transactionid | xid | | |
classid | oid | | |
objid | oid | | |
objsubid | smallint | | |
virtualtransaction | text | | |
pid | integer | | |
mode | text | | |
granted | boolean | | |
fastpath | boolean | | |
transactionid代表事务ID,简写XID,virtualxid代表虚拟事务ID VXID。对于只读事务,分配VXID,不需要实际分配一个真实的事务ID。
virtualtransaction之前的字段(不包含virtualtransaction)用于描述锁定对象信息,之后的部分用于描述持有锁或等待锁session信息。
postgres=# select * from pg_locks where pid in (27089,28137);
locktype | database | relation | page | tuple | virtualxid | transactionid | classid | objid | objsubid | virtualtransaction | pid | mode | granted | fastpath
---------------+----------+----------+------+-------+------------+---------------+---------+-------+----------+--------------------+-------+---------------------+---------+----------
relation | 13593 | 12143 | | | | | | | | 3/131409 | 27089 | AccessShareLock | t | t
virtualxid | | | | | 3/131409 | | | | | 3/131409 | 27089 | ExclusiveLock | t | t
virtualxid | | | | | 4/4750 | | | | | 4/4750 | 28137 | ExclusiveLock | t | t
relation | 13593 | 16526 | | | | | | | | 3/131409 | 27089 | AccessExclusiveLock | t | f
transactionid | | | | | | 6546 | | | | 4/4750 | 28137 | ExclusiveLock | t | f
transactionid | | | | | | 6544 | | | | 3/131409 | 27089 | ExclusiveLock | t | f
relation | 13593 | 16526 | | | | | | | | 4/4750 | 28137 | AccessExclusiveLock | f | f
(7 rows)
granted为t表示持有该锁,为f表示没有获得这把锁,从而被阻塞。
所有,如果需要查看被阻塞的进程,只需要查询视图pg_locks中granted为f的进程就可以了。
同样行锁查询该视图通过pg_locks中的transactionid的锁信息就可以了。
查行锁
select locktype,
relation::reglcass as rel,
page||,||tuple as ctid,
virtualxid as vxid,
transactionid as xid,
virtualtransaction as vxid2,
pid,mode,granted from pg_locks where pid in (8453,8764);
select * from testtab-1 where ctid=(0,1);
以上是关于PG基础篇--逻辑结构管理(锁机制)的主要内容,如果未能解决你的问题,请参考以下文章