CMU 15-445 -- Two Phase Locking - 14

news2024/11/25 10:59:39

CMU 15-445 -- Two Phase Locking - 14

  • 引言
  • Lock Types
  • Two-Phase Locking
  • Deadlock Detection & Prevention
    • Deadlock Detection
    • Deadlock Prevention
    • Hierarchical Locking
      • intention locks
      • 加锁协议
  • 锁升级
  • 最佳实践
  • 显式加锁的相关SQL语句
  • 小结


引言

本系列为 CMU 15-445 Fall 2022 Database Systems 数据库系统 [卡内基梅隆] 课程重点知识点摘录,附加个人拙见,同样借助CMU 15-445课程内容来完成MIT 6.830 lab内容。


上节课介绍了通过 WW、WR、RW conflicts 来判断一个 schedule 是否是 serializable 的方法,但使用该方法的前提是预先知道所有事务的执行流程,这与真实的数据库使用场景并不符合,主要原因在于:

  1. 请求连续不断。时时刻刻都有事务在开启、中止和提交
  2. 显式事务中,客户端不会一次性告诉数据库所有执行流程

因此我们需要一种方式来保证数据库最终使用的 schedule 是正确的 (serializable)。不难想到,保证 schedule 正确性的方法就是合理的加锁 (locks) 策略,2PL 就是其中之一。


Lock Types

DBMS 中锁通常被分为两种,Locks 和 Latches,二者的主要区别如下:

LocksLatches
SeparateUser transactionsThreads
ProtectDatabase ContentsIn-Memory Data Structures
DuringEntire TransactionsCritical Sections
ModesShared, Exclusive, Update, IntentionRead, Write
Handle deadlock byDetection & Resolution Waits-for, Timeout, AbortsAvoidance Coding Discipline
Kept inLock ManagerProtected Data Structure

本节关注的是事务级别的锁,即 Locks。Locks 有两种基本类型:

  • S-LOCK:共享锁 (读锁)
  • X-LOCK:互斥锁 (写锁)

二者的兼容矩阵如下表所示:

S-LOCK (shared)X-LOCK (exclusive)
S-LOCK (shared)
X-LOCK (exclusive)

如下图所示:DBMS 中有个专门的模块,lock manager,负责管理系统中的 locks,每当事务需要加锁或者升级锁的时候,都需要向它发出请求,lock manager 内部维护着一个 lock table,上面记录着当前的所有分配信息,lock manager 需要根据这些来决定赋予锁还是拒绝请求,以保证事务操作重排的正确性和并发度。

在这里插入图片描述
一个典型的 schedule 执行过程如下所示:
在这里插入图片描述
但仅仅在需要访问或写入数据时获取锁无法保证 schedule 的正确性,举例如下:
在这里插入图片描述
事务 T1 前后两次读到的数据不一致,出现了幻读,这与顺序执行的结果并不一致。于是我们需要更强的加锁策略,来保证 schedule 的正确性。


Two-Phase Locking

2PL 是一种并发控制协议,它帮助数据库在运行过程中决定某个事务是否可以访问某条数据,并且 2PL 的正常工作并不需要提前知道所有事务的执行内容,仅仅依靠已知的信息即可。

2PL,顾名思义,有两个阶段:growing 和 shrinking:
在这里插入图片描述
在 growing 阶段中,事务可以按需获取某条数据的锁,lock manager 决定同意或者拒绝;在 shringking 阶段中,事务只能释放之前获取的锁,不能获得新锁,即一旦开始释放锁,之后就只能释放锁。下图就违背了 2PL 的协议:

在这里插入图片描述
2PL 本身已经足够保证 schedule 是 serializable,通过 2PL 产生的 schedule 中,各个 txn 之间的依赖关系能构成有向无环图。但 2PL 可能导致级联中止 (cascading aborts),举例如下:

在这里插入图片描述
由于 T1 中止了,T2 在之前读到 T1 写入的数据,就是所谓的 “脏读”。为了保证整个 schedule 是 serializable,DBMS 需要在 T1 中止后将曾经读取过 T1 写入数据的其它事务中止,而这些中止可能进而使得其它正在进行的事务级联地中止,这个过程就是所谓的级联中止。

事实上 2PL 还有一个增强版变种,Rigorous 2PL,后者每个事务在结束之前,其写过的数据不能被其它事务读取或者重写,如下图所示:

在这里插入图片描述
Rigorous 2PL 可以避免级联中止,而且回滚操作很简单。

下面我们以转账为例,对 Non-2PL、2PL 和 Rigorous 2PL 分别举例:

在这里插入图片描述

  • T1:从 A 向 B 转账 100 美元
  • T2:计算并输出 A、B 账户的总和

Non-2PL 举例:

在这里插入图片描述

由于 T2 读到了 T1 写到一半的数据,结果不正确,输出的是 1900。可以看到它的并发程度很高。

2PL 举例:

在这里插入图片描述
2PL 输出的结果正确,为 2000,同时可以看到它的并发程度比 Non-2PL 的差一些,但看着还算不错。

Rigorous 2PL 举例:

在这里插入图片描述
Rigorous 2PL 输出的结果同样是正确的,可以看到它的并发程度比 2PL 更差一些。

回到 universe of schedules,cascading aborts 也是 schedule 的一个特性,它与 serializable 并无直接关系,因此将 cascading aborts schedule 考虑进来,可以得到下图:

在这里插入图片描述


Deadlock Detection & Prevention

2PL 无法避免的一个问题就是死锁:
在这里插入图片描述
死锁其实就是事务之间互相等待对方释放自己想要的锁。解决死锁的办法也很常规:

  • Detection:事后检测
  • Prevention:事前阻止

Deadlock Detection

死锁检测是一种事后行为。为了检测死锁,DBMS 会维护一张 waits-for graph,来跟踪每个事务正在等待 (释放锁) 的其它事务,然后系统会定期地检查 waits-for graph,看其中是否有成环,如果成环了就要决定如何打破这个环。

waits-for graph 中的节点是事务,从 Ti 到 Tj 的边就表示 Ti 正在等待 Tj 释放锁,举例如下:

在这里插入图片描述
当 DBMS 检测到死锁时,它会选择一个 “受害者” (事务),将该事务回滚,打破环形依赖,而这个 “受害者” 将依靠配置或者应用层逻辑重试或中止。这里有两个设计决定:

  1. 检测死锁的频率
  2. 如何选择合适的 “受害者”

检测死锁的频率越高,陷入死锁的事务等待的时间越短,但消耗的 cpu 也就越多。所以这是个典型的 trade-off,通常有一个调优的参数供用户配置。

选择 “受害者” 的指标可能有很多:事务持续时间、事务的进度、事务锁住的数据数量、级联事务的数量、事务曾经重启的次数等等。在选择完 “受害者” 后,DBMS 还有一个设计决定需要做:完全回滚还是回滚到足够消除环形依赖即可。


Deadlock Prevention

Deadlock prevention 是一种事前行为,采用这种方案的 DBMS 无需维护 waits-for graph,也不需要实现 detection 算法,而是在事务尝试获取其它事务持有的锁时直接决定是否需要将其中一个事务中止。

通常 prevention 会按照事务的年龄来赋予优先级,事务的时间戳越老,优先级越高。有两种 prevention 的策略:

  • Old Waits for Young:如果 requesting txn 优先级比 holding txn 更高则等待后者释放锁;更低则自行中止
  • Young Waits for Old:如果 requesting txn 优先级比 holding txn 更高则后者自行中止释放锁,让前者获取锁,否则 requesting txn 等待 holding txn 释放锁

举例如下:

在这里插入图片描述
无论是 Old Waits for Young 还是 Young Waits for Old,只要保证 prevention 的方向是一致的,就能阻止死锁发生,其原理类似哲学家就餐设定顺序的解决方案:先给哲学家排个序,遇到获取刀叉冲突时,顺序高的优先。


Hierarchical Locking

上面的例子中所有的锁都是针对单条数据 (database object),如果一个事务需要更新十亿条数据,那么 lock manager 中的 lock table 就要撑爆了。因此需要有一些手段能够将锁组织成树状/层级结构,减少一个事务运行过程中需要记录的锁的数量。

当我们说一个事务获取了“锁”时,意味着该事务对数据库中的某些资源获得了特定类型的访问控制。锁用于确保事务能够有序地访问共享资源,防止冲突并维护数据一致性。

锁的范围取决于被锁定的资源的粒度:

  1. 在属性级别:对属性进行锁定意味着事务限制了对表中某个特定数据属性(列)的访问。这种类型的锁是最细粒度的,它仅影响一个元组(行)中的单个属性。

  2. 在元组级别:对元组进行锁定意味着事务限制了对整个表中某个特定行的访问。这确保了在锁定保持期间其他事务不能修改或读取该特定元组。

  3. 在页面级别:对页面进行锁定意味着事务限制了对包含多个元组的数据块的访问。锁覆盖了页面中的所有元组。

  4. 在表级别:对表进行锁定意味着事务限制了对整个表的访问。这确保了对整个表的独占访问,防止其他事务在锁定期间访问任何部分。

高效的锁管理目标是让事务获得所需的最少数量的锁,同时仍然保持数据完整性和防止冲突。锁管理是数据库管理系统中非常重要的部分,它确保了并发操作的正确性和数据的一致性。

在这里插入图片描述
对于复杂的操作和多个资源的情况,可能涉及到多个锁的获取。在数据库管理系统中,通常会使用锁树(Lock Tree)来管理这些锁。对于叶节点(即最终的资源),可能需要获取 Exclusive Lock 和 Shared Lock,具体取决于具体操作。对于较高层级的节点,可以使用特殊的意向锁(Intention Lock)来表示事务对子节点的意图。


intention locks

意向锁是一种在数据库管理系统中用于优化锁管理的机制。当事务需要在树状结构中的某个节点上获取共享锁或独占锁时,可以首先尝试获取该节点上的意向锁。意向锁表示了在该节点下可能存在其他子节点上已经获得的共享或独占锁。

通过使用意向锁,事务可以避免在整个子树上逐一检查是否已经获得了相关的锁,从而减少锁管理的开销,提高并发控制的效率。如果某个节点上已经存在意向锁,那么数据库系统可以推断出在该节点的子节点上已经有相应的锁,而无需进一步检查。

意向锁本身不直接影响数据的读写,它只是用于提供关于锁状态的信息,以优化锁的获取和释放过程。通过这种优化,数据库系统可以更高效地处理并发操作,确保事务的正确执行和数据的一致性。

意向-共享锁(Intention-Shared,IS):

  • 意向-共享锁表示在较低级别节点上已经显式获取了共享锁。如果一个事务获取了意向-共享锁,那么说明在该节点的子节点上已经获得了共享锁。其他事务可以获取该节点的共享锁,但不能获取独占锁。

意向-独占锁(Intention-Exclusive,IX):

  • 意向-独占锁表示在较低级别节点上已经获取了独占锁或共享锁。如果一个事务获取了意向-独占锁,那么说明在该节点的子节点上已经获得了独占锁或共享锁。其他事务可以获取该节点的共享锁,但不能获取独占锁。

Shared + 意向-独占锁(Shared+Intention-Exclusive,SIX):

  • SIX 锁 = S 锁 + IX 锁。对目标表加上 SIX 锁后,S 锁这一属性保证了别的事务能知道我们要读取目标表的所有 record,它们就不会去并发地更新任意的 record;
  • IX 锁这一属性保证了别的事务能知道我们要更新目标表的一部分 record,它们就不会去并发地读取所有的 record。

这里是引用

意向锁的兼容性:
在这里插入图片描述


加锁协议

在数据库管理系统中,每个事务都会在数据库层次结构的最高级别上获取适当的锁:

  • 要在节点上获取 S(共享锁)或 IS(意向-共享锁),事务必须至少持有其父节点上的 IS(意向-共享锁)。
  • 要在节点上获取 X(独占锁)、IX(意向-独占锁)或 SIX(共享+意向-独占锁),事务必须至少持有其父节点上的 IX(意向-独占锁)。

这些规则确保了并发事务在数据库层次结构中获取适当的锁来保持数据的一致性和正确性。通过在最高级别上获取适当的锁,数据库系统可以避免冲突和数据不一致的问题,并保证事务能够正确地执行。同时,意向锁(IS 和 IX)的使用可以优化锁管理,减少不必要的锁检查,提高并发控制的效率。

两级继承体系加锁示例:
在这里插入图片描述
在这里插入图片描述
示例二: 存在多个事务同时操作时

  • T1 : Scan R and update a few tuples.
  • T2 : Read a single tuple in R.
  • T3 : Scan all tuples in R.

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述


锁升级

当获取太多低级锁时,锁升级动态请求粗粒度锁。这可以减少Lock Manager需要处理的锁请求数量。


最佳实践

我们通常无需在事务中手动设置锁,有时候我们需要给DBMS一些提示,让他来帮助我们提升并发度。

当需要对数据库执行一些较大改动时,显式指定锁或许是个不错的选择。


显式加锁的相关SQL语句

如果我们需要显示对某个表加锁,可以使用如下这些方式,这部分实现并不属于SQL标准一部分:

  • Postgres/DB2/Oracle Modes: SHARE, EXCLUSIVE
  • MySQL Modes: READ, WRITE

在这里插入图片描述
如何我们想在查询的时候,对满足要求的元组加上互斥锁,可以采用如下方式:
在这里插入图片描述
当然,也可以设置加上共享锁:

  • Postgres: FOR SHARE
  • MySQL: LOCK IN SHARE MODE

小结

2PL封锁协议用在大部分的DBMS中。

能够自动在多个事务中协调,并为每个事务生成一个正确的执行序列,可以通过如下方式:

  • Locks + protocol(2PL,SS2PL,…)
  • Deadlock detection + handling
  • Deadlock prevention

本节对应教材PDF

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/786179.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

剑指offer(C++)-JZ15:二进制中1的个数(算法-位运算)

作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 输入一个整数 n ,输出该数32位二进制表示中1的个数。其中负数用补码表示。 数据范围&#xf…

【运维】DevOps全流程笔记(未完成)

运维笔记 DevOps基本流程Code阶段工具(gitlab安装)Build阶段工具(Maven安装)Integrate阶段工具JenkinsJenkins介绍Jenkins安装Jenkins入门配置 CI/CD操作集成Sonar Qube集成HarborJenkins流水线Kubernetes编排工具 DevOps全流程笔…

OJ练习第144题——将数组和减半的最少操作次数

将数组和减半的最少操作次数 力扣链接:2208. 将数组和减半的最少操作次数 题目描述 给你一个正整数数组 nums 。每一次操作中,你可以从 nums 中选择 任意 一个数并将它减小到 恰好 一半。(注意,在后续操作中你可以对减半过的数…

基于YOLOv5的WiderFace人脸检测检测系统(PyTorch+Pyside6+YOLOv5模型)

摘要:基于YOLOv5的WiderFace人脸检测系统可用于日常生活中检测与定位人脸目标,利用深度学习算法可实现图片、视频、摄像头等方式的人脸目标检测识别,另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目标检测模型训练数据集&…

ffplay播放器剖析(6)----音视频同步分析

文章目录 1. 音视频同步基础1.1 音视频同步策略1.2 音视频同步概念1.3 FFmpeg中的时间单位1.4 不同结构体的time_base/duration分析1.5 不同结构体的pts/dts分析1.6 ffplay中Frame结构体分析1.7 Vidoe Frame PTS获取及矫正1.8 Audio Frame PTS的获取 2.以音频为基准3.以视频为基…

了解Unity编辑器之组件篇Tilemap(五)

Tilemap:用于创建和编辑2D网格地图的工具。Tilemap的主要作用是简化2D游戏中地图的创建、编辑和渲染过程。以下是一些Tilemap的主要用途: 2D地图绘制:Tilemap提供了一个可视化的编辑器界面,可以快速绘制2D地图,例如迷…

jlink RTT调试 NRF52840

打开 J-Link RTT Viewer 搜索&#xff1a;**J-Link RTT Viewer ** 软件部分 代码部分 #include <stdbool.h> #include <stdint.h> #include "nrf_delay.h" #include "boards.h" //Log需要引用的头文件 #include "nrf_log.h"…

音频转换工具有很多,但是找到好用的还是得看这篇

在日常生活中&#xff0c;我们常常会遇到需要将音频文件转换成不同格式的情况。不过&#xff0c;有些音频转换软件可能需要安装繁琐的插件&#xff0c;这对于一些小伙伴来说可能不太方便。幸运的是&#xff0c;如今有许多免费的音频转换格式软件可供选择&#xff0c;让我们能够…

K3S 安装部署

一、方法1&#xff1a;利用官方源&#xff08;国外源&#xff09;直接一键安装 因 K3s 的核心组件镜像需从 gcr.io 拉取&#xff08;国内网络不通&#xff09;&#xff0c;所以需具备外网访问的环境&#xff0c;适用于服务器均在国外的环境选用&#xff0c;简单粗暴一键安装。…

mysql进阶1——proxysql中间件

文章目录 一、基本了解二、安装部署三、proxysql管理配置3.1 内置库3.1.1 main库表3.1.2 stats库表3.1.3 monitor库 3.2 常用管理变量3.2.1 添加管理用户3.2.2 添加普通用户3.2.3 修改监听套接字 四、多层配置系统4.1 系统结构4.2 修改变量加载配置4.3 启动加载流程 一、基本了…

聊一聊什么是JNDI数据源

大家好&#xff0c;我是G探险者。 我们平时开发项目&#xff0c;连接数据库那块&#xff0c;会采用连接池的方式连进行连接数据库&#xff0c;比如常见的durid,dbcp&#xff0c;c3p0等。那你有没有听过还有一个JNDI数据源呢&#xff0c;反正我以前是很少听说过。可能就是因为自…

梅尔频谱(Mel spectrum)简介及Python实现

梅尔频谱&#xff08;Mel spectrum&#xff09;简介及Python实现 1. 梅尔频谱&#xff08;Mel spectrum&#xff09;简介2. Python可视化测试3.频谱可视化3.1 Mel 频谱可视化3.2 STFT spectrum 参考文献资料 1. 梅尔频谱&#xff08;Mel spectrum&#xff09;简介 在信号处理上…

wordpress框架自定义添加page分页功能

先来看效果图&#xff1a; 一、在主题目录下的functions.php文件里&#xff0c;添加如下分页函数&#xff1a; /** * 数字分页函数 * 说明&#xff1a;因为wordpress默认仅仅提供简单分页&#xff0c;所以要实现数字分页&#xff0c;需要自定义函数 * Param bool $isHome 是…

工业静电监控系统的功能介绍

工业静电监控系统是一种用于监测和控制工业生产过程中静电现象的技术系统。静电是指由于物体间的电荷不平衡而产生的电场现象&#xff0c;它在工业生产中可能导致电击、火花、电磁干扰等质量问题。 工业静电监控系统主要通过使用静电传感器和控制设备来实现对静电场的监测和控…

Java反序列化(0):URLDNS的反序列化调试分析

URLDNS链子是Java反序列化分析的第0课&#xff0c;网上也有很多优质的分析文章。 笔者作为Java安全初学者&#xff0c;也从0到1调试了一遍&#xff0c;现在给出调试笔记。 一. Java反序列化前置知识 Java原生链序列化&#xff1a;利用Java.io.ObjectInputStream对象输出流的w…

中医药行业如何进行数字化转型?看天津同仁堂谈“有道有术有零代码”

张伯礼院士曾指出&#xff0c;中药制造的现代化水平&#xff0c;还停留在10%左右的阶段。中医药行业&#xff0c;老字号企业&#xff0c;该如何通过数字化焕发新活力&#xff1f; 天津同仁堂通过与伙伴云合作&#xff0c;零代码构建数字化系统&#xff0c;让技术与思维共同成长…

【Linux】Tcp协议的通讯流程,浅谈三次握手四次挥手

文章目录 Tcp协议的通讯流程一、协议定制与网络版计算器的实现二、json的使用总结 Tcp协议的通讯流程 上一篇文章我们讲解了如何实现Tcp服务器&#xff0c;Tcp的接口也用了&#xff0c;下面我们就看一下Tcp协议的通讯流程&#xff1a; 在服务端&#xff0c;我们首先要创建一个…

Django on_delete参数在sql级别操作中不生效问题

class AA(models.Model):name models.CharField(max_length128)class Meta:db_table aaclass BB(models.Model):name models.CharField(max_length128)aa models.ForeignKey(AA, nullTrue, on_deletemodels.CASCADE)class Meta:db_table bb 如上当使用ORM删除aa表中的数据…

数字孪生:未来科技的新前沿

数字孪生作为一项新兴的研究方向&#xff0c;正逐渐成为科技界的焦点。它是将现实世界中的实体、系统或过程通过数字化手段进行建模、仿真和分析&#xff0c;形成与实体相对应的数字化副本。数字孪生的发展为我们带来了无限的想象空间&#xff0c;以及解决现实问题的新途径。 在…

opencv-18 什么是色彩空间?

1.什么是色彩空间类型&#xff1f; 色彩空间类型&#xff0c;也称为颜色空间类型或色彩模型&#xff0c;是一种表示图像中颜色的方式。在计算机图形学和数字图像处理中&#xff0c;有许多种色彩空间类型&#xff0c;每种类型有不同的表达方式和特点。 常见的色彩空间类型包括&a…