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基础篇--逻辑结构管理(锁机制)的主要内容,如果未能解决你的问题,请参考以下文章

PG基础篇--逻辑结构管理(表继承分区表)

PG基础篇--逻辑结构管理(用户及权限管理)

PG基础篇--逻辑结构管理(库模式表约束)

MySQL基础篇(06):事务管理,锁机制案例详解

Liunx系统下进行LVM的创建以及相关磁盘配额——实战篇

linux磁盘篇——lvm