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

相关文章

使用jenv工具管理多个JDK版本的方法步骤

《使用jenv工具管理多个JDK版本的方法步骤》jenv是一个开源的Java环境管理工具,旨在帮助开发者在同一台机器上轻松管理和切换多个Java版本,:本文主要介绍使用jenv工具管理多个JD... 目录一、jenv到底是干啥的?二、jenv的核心功能(一)管理多个Java版本(二)支持插件扩展(三)环境隔

MySQL版本问题导致项目无法启动问题的解决方案

《MySQL版本问题导致项目无法启动问题的解决方案》本文记录了一次因MySQL版本不一致导致项目启动失败的经历,详细解析了连接错误的原因,并提供了两种解决方案:调整连接字符串禁用SSL或统一MySQL... 目录本地项目启动报错报错原因:解决方案第一个:第二种:容器启动mysql的坑两种修改时区的方法:本地

conda安装GPU版pytorch默认却是cpu版本

《conda安装GPU版pytorch默认却是cpu版本》本文主要介绍了遇到Conda安装PyTorchGPU版本却默认安装CPU的问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录一、问题描述二、网上解决方案罗列【此节为反面方案罗列!!!】三、发现的根本原因[独家]3.1 p

Redis指南及6.2.x版本安装过程

《Redis指南及6.2.x版本安装过程》Redis是完全开源免费的,遵守BSD协议,是一个高性能(NOSQL)的key-value数据库,Redis是一个开源的使用ANSIC语言编写、支持网络、... 目录概述Redis特点Redis应用场景缓存缓存分布式会话分布式锁社交网络最新列表Redis各版本介绍旧

IIS 7.0 及更高版本中的 FTP 状态代码

《IIS7.0及更高版本中的FTP状态代码》本文介绍IIS7.0中的FTP状态代码,方便大家在使用iis中发现ftp的问题... 简介尝试使用 FTP 访问运行 Internet Information Services (IIS) 7.0 或更高版本的服务器上的内容时,IIS 将返回指示响应状态的数字代

Android NDK版本迭代与FFmpeg交叉编译完全指南

《AndroidNDK版本迭代与FFmpeg交叉编译完全指南》在Android开发中,使用NDK进行原生代码开发是一项常见需求,特别是当我们需要集成FFmpeg这样的多媒体处理库时,本文将深入分析A... 目录一、android NDK版本迭代分界线二、FFmpeg交叉编译关键注意事项三、完整编译脚本示例四

查看MySQL数据库版本的四种方法

《查看MySQL数据库版本的四种方法》查看MySQL数据库的版本信息可以通过多种方法实现,包括使用命令行工具、SQL查询语句和图形化管理工具等,以下是详细的步骤和示例代码,需要的朋友可以参考下... 目录方法一:使用命令行工具1. 使用 mysql 命令示例:方法二:使用 mysqladmin 命令示例:方

Python实现剪贴板历史管理器

《Python实现剪贴板历史管理器》在日常工作和编程中,剪贴板是我们使用最频繁的功能之一,本文将介绍如何使用Python和PyQt5开发一个功能强大的剪贴板历史管理器,感兴趣的可以了解下... 目录一、概述:为什么需要剪贴板历史管理二、功能特性全解析2.1 核心功能2.2 增强功能三、效果展示3.1 主界面

Java版本不兼容问题详细解决方案步骤

《Java版本不兼容问题详细解决方案步骤》:本文主要介绍Java版本不兼容问题解决的相关资料,详细分析了问题原因,并提供了解决方案,包括统一JDK版本、修改项目配置和清理旧版本残留等步骤,需要的朋... 目录错误原因分析解决方案步骤第一步:统一 JDK 版本第二步:修改项目配置第三步:清理旧版本残留兼容性对

Linux搭建单机MySQL8.0.26版本的操作方法

《Linux搭建单机MySQL8.0.26版本的操作方法》:本文主要介绍Linux搭建单机MySQL8.0.26版本的操作方法,本文通过图文并茂的形式给大家讲解的非常详细,感兴趣的朋友一起看看吧... 目录概述环境信息数据库服务安装步骤下载前置依赖服务下载方式一:进入官网下载,并上传到宿主机中,适合离线环境