4.1 版本管理器——2PL与MVCC

2024-09-01 06:04
文章标签 版本 管理器 mvcc 4.1 2pl

本文主要是介绍4.1 版本管理器——2PL与MVCC,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

2PL协议

2PL(Two-Phase Locking,两阶段锁协议)是数据库管理系统中用于确保事务调度正确性的常见并发控制协议。它通过锁机制来管理事务对数据库资源的访问,确保事务之间不会发生冲突。2PL协议可以分为以下两个阶段:

  1. 扩展阶段(Growing Phase):在这个阶段,事务可以请求获得锁定(如共享锁或排他锁),但不能释放任何锁。事务可以随着操作的进行逐步获取更多的锁,但一旦进入收缩阶段,便不能再获取新的锁。

  2. 收缩阶段(Shrinking Phase):在这个阶段,事务只能释放锁,不能再获得新的锁。一旦事务开始释放锁,就不能再请求新的锁。

2PL锁协议的重要特性是,事务必须在扩展阶段获取所有必要的锁,然后在收缩阶段释放这些锁。这个过程确保了在并发执行多个事务时,数据库的一致性和隔离性。 两阶段锁协议有两种变体

  • 严格两阶段锁协议(Strict 2PL):事务在提交或回滚之前不会释放任何锁,特别是排他锁。这种策略可以防止脏读的发生,确保了更高的隔离级别。

  • 严密两阶段锁协议(Rigorous 2PL):事务在整个生命周期内都不会释放任何锁,直到事务结束(提交或回滚)。这种策略比严格2PL更严格,防止了脏读、不可重复读和幻读。

2PL协议在数据库系统中广泛使用,是确保并发控制、避免死锁和保证数据一致性的重要方法之一。

以上定义来自GPT

数据库中的冲突操作

不考虑插入操作,只考虑updateread操作,这两个操作满足以下三个条件即相互冲突:

  • 两个操作由不同事务执行

  • 两个操作操作同一个数据项

  • 至少有一个update操作

那么对同一个数据项的操作发生冲突的条件其实如下:

  • 两个不同事务的update冲突

  • 两个不同事务的updateread冲突

2PL和解决冲突操作有什么关系?

2PL(两阶段锁协议)在解决数据库中的操作冲突时具有以下重要意义:

1. 确保事务的隔离性

2PL的核心目标是确保多个事务并发执行时保持隔离性,防止事务之间的操作互相干扰。隔离性是ACID(原子性、一致性、隔离性、持久性)原则的重要组成部分,特别是避免以下常见问题:

  • 脏读:一个事务读取了另一个未提交事务修改的数据,导致数据不一致。

  • 不可重复读:一个事务两次读取相同的数据,但在两次读取之间,另一个事务修改了数据。

  • 幻读:一个事务在多次查询时,发现有额外的数据行被另一个事务插入,导致查询结果不一致。

通过2PL协议,事务可以通过锁机制避免这些问题,从而保持数据的一致性和隔离性。

2. 预防操作冲突(重点在这一条)

在并发场景下,不同事务可能对同一资源(如数据库记录)进行操作。如果不加控制,事务间的冲突可能导致数据不一致或事务失败。2PL通过锁来管理资源的访问,避免以下类型的冲突:

  • 读-写冲突:一个事务正在读取数据,另一个事务想要修改该数据。

  • 写-写冲突:多个事务同时尝试修改同一数据。

2PL协议要求事务在扩展阶段获取所需的锁,并保证在释放锁前,其他事务无法访问已被锁定的资源,从而避免了操作冲突。

3. 保证调度的可串行化

串行化调度(Serializable Scheduling)是指事务的并发执行结果与按顺序执行的结果一致。2PL协议是确保调度可串行化的重要手段。根据2PL,事务的锁获取和释放顺序符合两个阶段的规则,这就保证了事务不会相互交错,导致不一致的状态。

4. 避免不安全的调度

如果不使用锁协议,事务调度可能导致不安全的执行。例如,一个事务读取了另一个事务修改的未提交数据,这可能导致数据污染。2PL通过锁定资源,确保每个事务只能在资源安全的状态下执行,从而避免出现不安全的调度情况。

5. 防止死锁(结合其他技术)

虽然2PL本身不能完全避免死锁,但它为死锁检测提供了基础。在2PL中,由于事务可能在扩展阶段请求多个锁,有可能发生死锁(即两个或多个事务相互等待彼此释放锁)。通过结合死锁检测机制或采用诸如超时机制,数据库系统可以检测并解除死锁,恢复正常执行。 上面来自GPT

在MySQL中,两阶段锁协议的含义是:当一个事务获取到了某一个数据库对象的锁之后,并不是当前事务不需要操作它了之后,这个说就会马上释放掉,这个锁会一直被这个事务持有,直到这个事务被提交或回滚后,这个锁才会被释放掉。所以,在当前事务还没有结束的时候,任何其他事务尝试获取这个锁的时候,都会被阻塞。知道当前事务提交或回滚后,前提事务才可以获取到这把锁 这就是MySQL中2PL两阶段锁协议的含义。它在事务并发的时候,为数据的一致性提供有力的保障 源自网络

MYDB中解决冲突的方法

SimpleDB采用2PL来实现调度序列的可串行化。如果某个事务i已经对x加锁,且另一个事务j也想操作x,但是这个操作与事务i之前的操作相互冲突,那么事务j会被阻塞。 使用2PL虽然保证了调度序列的可串行化,但是不可避免地导致了事务间的相互阻塞乃至死锁

MVCC

什么是MVCC

MVCC(Multiversion Concurrency Control,多版本并发控制)是一种数据库并发控制机制,用于解决数据库中多个事务并发执行时的读写冲突问题。MVCC通过维护数据的多个版本,允许并发的读操作和写操作更有效地进行,从而提高数据库的并发性能和系统吞吐量。

核心概念
  1. 版本控制:每个数据项都有多个版本,每个版本对应于数据库在某个时间点的状态。当事务对数据进行修改时,系统不会直接覆盖旧版本的数据,而是创建一个新版本。旧版本的数据仍然保留,以供其他事务读取。

  2. 事务标识:每个事务在开始时都会获得一个唯一的时间戳或事务ID。这个时间戳用于决定事务可以访问哪些数据版本,从而确保数据的一致性和隔离性。

  3. 快照隔离:MVCC提供了一个时间点的数据库“快照”,即事务在开始时看到的是数据的一个一致快照,即使其他事务在此后提交了修改。这个机制确保了读取操作的可重复性,避免了脏读和不可重复读的问题。

MVCC 的工作机制
  • 读取操作:事务在读取数据时,根据自身的时间戳,只能看到在该时间戳之前提交的版本数据。这意味着事务读取的数据版本是相对于其开始时间点的一致快照,而不是实时的最新数据。

  • 写入操作:当事务要修改数据时,系统会创建该数据项的一个新版本,并将该版本标记为该事务的写入。这个新版本在事务提交前,对其他事务是不可见的。

  • 提交和回滚:当事务提交时,系统会将新版本标记为可见,同时其他事务将能够看到这个新版本。如果事务回滚,则新版本会被丢弃,其他事务继续访问旧版本。

优点
  1. 高并发性:MVCC允许多个事务同时读取数据,而不需要加锁。这减少了读写操作之间的冲突,从而提高了并发性。

  2. 避免读写冲突:通过维护数据的多个版本,读操作不会被写操作阻塞,反之亦然。这大大减少了死锁和等待时间。

  3. 一致性保证:MVCC通过时间戳和数据版本管理,确保事务看到的是一致的数据库状态,避免了脏读、不可重复读和幻读问题。

缺点
  1. 存储开销:由于需要维护多个版本的数据,MVCC增加了存储空间的需求。过多的版本还可能需要额外的机制来清理和回收空间。

  2. 版本管理复杂性:随着时间的推移,系统可能产生大量数据版本,管理这些版本及其对应的事务状态会增加系统的复杂性。

使用场景

MVCC广泛应用于现代关系型数据库系统,如PostgreSQL、MySQL(InnoDB引擎)和Oracle,以及一些NoSQL数据库,如Cassandra。它尤其适用于读操作频繁的场景,通过减少锁冲突来提高并发性能。

所以说,MVCC其实是一种思想,在不同的数据库中有不同的具体实现方式

MYDB中的MVCC

之前的实现中,我们知道数据管理器(DM)通过操作持久化的db文件,并通过封装,向上提供的抽象数据是DataItem,也就是说,上层看到的数据都是DataItem的形式 而本章讨论的版本管理器(VM)会进一步封装,给VM之上的模块提供一种抽象数据,即“记录”(Entry)。VM之上的模块看到的数据以及操作的数据都是Entry的形式 VM在内部,为每个Entry维护了多个版本(Version)。当上层模块对某个“记录”(Entry)修改时,VM就创建一个新的版本 如上的MVCC策略能够降低不同操作之间互相阻塞的概率,例如实现可重复读等隔离级别

这篇关于4.1 版本管理器——2PL与MVCC的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1126144

相关文章

IDEA中Git版本回退的两种实现方案

《IDEA中Git版本回退的两种实现方案》作为开发者,代码版本回退是日常高频操作,IntelliJIDEA集成了强大的Git工具链,但面对reset和revert两种核心回退方案,许多开发者仍存在选择... 目录一、版本回退前置知识二、Reset方案:整体改写历史1、IDEA图形化操作(推荐)1.1、查看提

如何使用Python实现一个简单的window任务管理器

《如何使用Python实现一个简单的window任务管理器》这篇文章主要为大家详细介绍了如何使用Python实现一个简单的window任务管理器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 任务管理器效果图完整代码import tkinter as tkfrom tkinter i

JDK多版本共存并自由切换的操作指南(本文为JDK8和JDK17)

《JDK多版本共存并自由切换的操作指南(本文为JDK8和JDK17)》本文介绍了如何在Windows系统上配置多版本JDK(以JDK8和JDK17为例),并通过图文结合的方式给大家讲解了详细步骤,具有... 目录第一步 下载安装JDK第二步 配置环境变量第三步 切换JDK版本并验证可能遇到的问题前提:公司常

nvm如何切换与管理node版本

《nvm如何切换与管理node版本》:本文主要介绍nvm如何切换与管理node版本问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录nvm切换与管理node版本nvm安装nvm常用命令总结nvm切换与管理node版本nvm适用于多项目同时开发,然后项目适配no

Mybatis从3.4.0版本到3.5.7版本的迭代方法实现

《Mybatis从3.4.0版本到3.5.7版本的迭代方法实现》本文主要介绍了Mybatis从3.4.0版本到3.5.7版本的迭代方法实现,包括主要的功能增强、不兼容的更改和修复的错误,具有一定的参考... 目录一、3.4.01、主要的功能增强2、selectCursor example3、不兼容的更改二、

pytorch+torchvision+python版本对应及环境安装

《pytorch+torchvision+python版本对应及环境安装》本文主要介绍了pytorch+torchvision+python版本对应及环境安装,安装过程中需要注意Numpy版本的降级,... 目录一、版本对应二、安装命令(pip)1. 版本2. 安装全过程3. 命令相关解释参考文章一、版本对

springboot3.4和mybatis plus的版本问题的解决

《springboot3.4和mybatisplus的版本问题的解决》本文主要介绍了springboot3.4和mybatisplus的版本问题的解决,主要由于SpringBoot3.4与MyBat... 报错1:spring-boot-starter/3.4.0/spring-boot-starter-

mac安装nvm(node.js)多版本管理实践步骤

《mac安装nvm(node.js)多版本管理实践步骤》:本文主要介绍mac安装nvm(node.js)多版本管理的相关资料,NVM是一个用于管理多个Node.js版本的命令行工具,它允许开发者在... 目录NVM功能简介MAC安装实践一、下载nvm二、安装nvm三、安装node.js总结NVM功能简介N

java中不同版本JSONObject区别小结

《java中不同版本JSONObject区别小结》本文主要介绍了java中不同版本JSONObject区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录1. FastjsON2. Jackson3. Gson4. org.json6. 总结在Jav

MySQL中的MVCC底层原理解读

《MySQL中的MVCC底层原理解读》本文详细介绍了MySQL中的多版本并发控制(MVCC)机制,包括版本链、ReadView以及在不同事务隔离级别下MVCC的工作原理,通过一个具体的示例演示了在可重... 目录简介ReadView版本链演示过程总结简介MVCC(Multi-Version Concurr