PostgreSQL-锁机制详解

news/2024/7/7 20:21:30

PG数据库中由两类锁:

  • 表级锁
  • 行级锁

当要查询、插入、更新、删除表中的数据时,首先会获得表上的锁,然后再获得行上的锁

表级锁模式

锁模式解释
ACCESS SHARE只与ACCESS EXCLUSIVE模式冲突。SELECT命令将在所引用的表上加此类型的锁。通常情况下,任何只读取表而不修改表的查询都会请求这种锁模式
ROW SHARE与EXCLUSIVE和ACCESS EXCLUSIVE锁模式冲突。SELECT FOR UPDATE和SELECT FOR SHARE命令会在目标表上加此类型的锁
ROW EXCLUSIVE与SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE、ACCESS EXCLUSIVE锁模式冲突。UPDATE、DELETE、INSERT命令自动在所修改的表上请求加此类型的锁。通常情况下,修改表中数据的命令都是在表上加上此类型的锁
SHARE UPDATE EXCLUSIVE与SHARE UPDATE EXCLUSIVE、SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE、ACCESS EXCLUSIVE锁模式冲突。模式改变和运行VACUUM并发的情况下,这种锁模式可以保护表。VACUUM(不带FULL选项)、ANALYZE、CREATE INDEX CONCURRENTLY命令请求此类型的锁
SHARE与ROW EXCLUSIVE、SHARE UPDATE EXCLUSIVE、SHARE ROW EXCLUSIVE、EXCLUSIVE、ACCESS EXCLUSIVE锁模式冲突。这种锁模式避免表的并发数据修改。CREATE INDEX(不带CONCURRENTLY选项)语句要求这种锁模式
SHARE ROW EXCLUSIVE与ROW EXCLUSIVE、SHARE UPDATE EXCLUSIVE、SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE、ACCESS EXCLUSIVE锁模式冲突。任何PG命令都不会自动请求这种锁模式
EXCLUSIVE与ROW SHARE、ROW EXCLUSIVE、SHARE UPDATE EXCLUSIVE、SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE、ACCESS EXCLUSIVE锁模式冲突。这种锁模式只允许并发ACCESS SHARE锁,也就是说,只有对表的读操作可以和持有这个锁的事务并发执行。任何PG命令都不会在用户表上自动请求这种锁模式。不过,在执行某些操作时,会在某些系统表上请求这种锁模式
ACCESS EXCLUSIVE与所有的锁模式冲突(包括ACCESS SHARE、ROW SHARE、ROW EXCLUSIVE、SHARE UPDATE EXCLUSIVE、SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE)。这种锁模式保证只能有一个用户访问此表。ALTER TABLE、DROP TABLE、TRUNCATE、REINDEX、CLUSTER、VACUUM FULL命令要求此类型的锁。在LOCK TABLE命令中没有明确声明需要的锁模式时,它是默认锁模式

表级锁冲突矩阵

水平代表已申请到的锁模式竖直代表请求的锁模式ACCESS SHAREROW SHAREROW EXCLUSIVESHARE UPDATE EXCLUSIVESHARESHARE ROW EXCLUSIVEEXCLUSIVEACCESS EXCLUSIVE
ACCESS SHAREYYYYYYYN
ROW SHAREYYYYYYNN
ROW EXCLUSIVEYYYYNNNN
SHARE UPDATE EXCLUSIVEYYYNNNNN
SHAREYYNNYNNN
SHARE ROW EXCLUSIVEYYNNNNNN
EXCLUSIVEYNNNNNNN
ACCESS EXCLUSIVENNNNNNNN
  1. “N”表示这两种锁冲突,也就是说,同一用户不能同时持有这两种锁,“Y”表示两种锁可以兼容。
  2. 表级锁只有SHARE和EXCLUSIVE这两种,这两种锁基本上就是读写锁的意思。
  3. 加上SHARE锁后相当于加了读锁,表中的内容就不能变化了。可以为多个事务加上此锁,只要任意一个用户不释放此读锁,其他用户就不能修改这个表。(注意这里的维度是表)。
  4. 多版本功能下,如果改某一行的数据,实际上并没有改变原先那行数据,而是另复制出一个新行,修改都在新行上进行,事务进行不提交,别人是看不到这条数据的;由于原先那行数据没有变化,在修改过程中,读数据的人仍然可以读到原有数据,这样就没有必要阻塞其他用户读数据了。
  5. 多版本功能下,除了SHARE和EXCLUSIVE两个锁,还需要增加两个锁,一个叫作“ACCESS SHARE”,表明加上这个锁,即使是正在修改数据的情况下也允许读数据;另一个锁是“ACCESS EXCLUSION”,意思是即使有多版本的功能,也不允许访问数据。

表级锁加锁的对象是表,由于加锁的范围太大而导致并发不高,于是人们提出了行级锁的概念,但是行级锁与表级锁之间会产生冲突,这时就需要有一种机制来描述行级锁与表级锁之间的关系。在MySQL中是使用“意向锁”的概念来解决这一问题的,方法就是当我们要修改表中的某一行数据时,需要先在表上加一种锁,表示即将在表的部分行上加共享锁或排它锁


PG中也是这样实现的,如ROW SHARE、ROW EXCLUSIVE这两个锁,这两个锁实际上就对应MySQL中的共享意向锁(IS)和排它意向锁(IX)。从“意向锁”的概念出发,我们可以得到意向锁如下两个特点:

  1. 意向锁之间是不会发生冲突的,即使是ROW EXCLUSIVE之间也不会发生冲突,因为它们都只是“有意”做什么但还没有真做,所以是可以兼容的。
  2. 意向锁与其他非意向锁之间的关系和普通锁与普通锁之间的关系是相同的。例如:
    • “X”与“X”锁是冲突的,所以“IX”锁与“X”是冲突的
    • “X”与“S”锁是冲突的,所以“IX”锁与“S”是冲突的
    • “S”与“S”锁是不冲突的,所以“IS”锁与“S”是不冲突的

如果把共享锁“SHARE”简写为“S”,把排它锁“EXCLUSIVE”简写为“X”;把“ROW SHARE”简写为“IS”;把“ROW EXCLUSIVE”锁简写为“IX”;这4种锁的关系(意向锁与非意向之间的冲突矩阵)如下表所示:

| X | S| IX| IS
—|----|----|----|—
X | N | N | N | N
S | N | Y | N | Y
IX | N | N | Y | Y
IS | N | Y | Y | Y

表级锁总计

  1. 共享锁“SHARE”
  2. 排它锁“EXCLUSIVE”
  3. ACCESS SHARE
  4. ACCESS EXCLUSIVE
  5. 意向共享锁“ROW SHARE”
  6. 意向排它锁“ROW EXCLUSIVE”
  7. SHARE UPDATE EXCLUSIVE
  8. SHARE ROW EXCLUSIVE

多版本原因,修改一条数据的同时允许读数据,所以为了处理这种情况,增加了“ACCESS”相关的两种锁;为了处理表锁和行锁之间的关系,于是有了意向锁的概念,增加了意向共享锁和意向排它锁;由于意向锁之间不会产生冲突,而且意向排它锁互相之间也不会产生冲突,于是又需要更严格一些的锁,这样就产生了SHARE UPDATE EXCLUSIVE和SHARE ROW EXCLUSIVE锁。

行级锁模式

行级锁模式比较简单,只有两种,即“共享锁”“排它锁”,或者可以说是“读锁”或“写锁”。

在PG中不称其为“读锁”的原因是,由于有多版本的实现,所以实际读取行数据时,并不会在行上执行任何锁(包括“读锁”)。


http://lihuaxi.xjx100.cn/news/1205474.html

相关文章

冈萨雷斯DIP第2章知识点

文章目录 2.1 视觉感知要素2.2 光和电磁波谱2.3 图像感知与获取2.4 图像取样和量化2.4.1 取样和量化的基本概念2.4.2 数字图像表示2.4.4 空间分辨率和灰度分辨率2.4.5 图像内插 (image interpolation)2.5 像素间的一些基本关系 2.6 数字图像处理所用的基本数学工具介绍2.6.3 算…

多传感器融合SLAM --- 11.LIO-SAM提取特征点代码分析 featureExtraction.cpp

目录 0 流程图 1 遮挡点判断的数学原理 2 代码解析 2.1 计算曲率 2.2 移除遮挡点

【性能测试】辅助命令10连击

性能测试过程中需要用到的命令 1、查看cpu的核数2、查看内存的占用情况3、上传服务器的文件赋权4、查看nmon的进程5、杀死进程6、查看对应进程中哪个线程比较消耗cpu7、查看进程的回收处理情况8、整体资源得数据分析9、查看日志10、查看日志怎么退出 1、查看cpu的核数 方法a、…

ubantu换配置源

文章目录 1.配置镜像源位置2.进入终端,切换到/home/user/etc/apt/3.默认这个文件是只读的,我们修改一下权限4.修改之前,我们先备份一下系统原来配置的源5.开始修改,打开/etc/apt/sources.list文件,将原来的内容删除&am…

LeetCode_双指针_中等_82.删除排序链表中的重复元素 II

目录 1.题目2.思路3.代码实现(Java) 1.题目 给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回已排序的链表。 示例 1: 输入:head [1,2,3,3,4,4,5] 输出&…

遇到了一个跨域问题

我的前端运行时 所在的端口是 localhost:7000, 后端所在的端口是 localhost:8080 我想 在前端像后端发送请求,获取数据。但是浏览器报错,因为不同源。 因此,解决方案如下: 在 Vue.js 应用程序中,你可以…

横岗茂盛村旧改,已立项,一期已拆平。

项目位于龙岗区横岗街道红棉路与茂盛路交汇处,距离轨道3号线横岗站约700米。 茂盛片区城市更新单元规划(草案)已经在近日公示,该旧改被纳入《2012年深圳市城市更新单元计划第五批计划》,2019年曾被暂停,20…

2022年,Rust与Go哪一个更好?

这是每一个程序员和开发人员都问过的问题,还有很多人仍然在问,即使他们已经做出了自己的决定。Rust vs. Go。2022年,我应该选择哪一个?或选择哪种语言--Golang或Rust。 Golang和Rust是目前使用的最年轻的编程语言。Go于2009年在谷…