MySQL的并发控制与MVCC机制深度解析

目录

    • 1. MySQL中的并发问题
    • 2. 数据库的隔离级别
    • 3. MVCC(多版本并发控制)机制
      • 3.1 MVCC的实现原理
      • 3.2 Read View详解
      • 3.3 当前读与快照读
    • 4. MVCC在不同隔离级别下的工作方式
    • 5. MVCC解决幻读问题
    • 6. MVCC的优缺点
      • 优点:
      • 缺点:
    • 7. MVCC在实际应用中的注意事项

1. MySQL中的并发问题

在多用户数据库系统中,并发操作是不可避免的。然而,并发操作可能会导致一些问题,主要包括:

  1. 脏读:一个事务读取了另一个未提交事务修改过的数据:

    A事务读取B事务修改后的数据返回,然而B事务发生了回滚

脏读

  1. 不可重复读:在同一事务内,多次读取同一数据返回的结果有所不同:

​ A事务多次读取同一个数据,B事务修改了该数据,A事务读到的数据不一样

不可重复读

  1. 幻读:在同一事务内,多次查询返回的结果集不一致:

​ A事务多次读取某些数据(比如查询表的数据总数),B事务插入或者删除了数据,A读取的数据数量发生了变更,像幻觉一样

幻读

注意区分幻读和不可重复读

为了解决这些问题,数据库系统引入了事务隔离级别的概念。

2. 数据库的隔离级别

SQL标准定义了四种隔离级别,从低到高分别是:

  1. 读未提交(Read Uncommitted)
  2. 读已提交(Read Committed)
  3. 可重复读(Repeatable Read)
  4. 串行化(Serializable)

让我们用一个图表来展示这些隔离级别如何解决并发问题:
隔离

MySQL的InnoDB存储引擎默认使用**可重复读(Repeatable Read)**隔离级别。他引入了MVCC来解决这个不可重复读的问题(读已提交也有MVCC,两者之间只是创建快照的时机不同,后面再提)

3. MVCC(多版本并发控制)机制

MVCC是MySQL InnoDB存储引擎用于提高并发性能的一种机制。它的核心思想是:

保存数据在某个时间点的快照,形成一个版本链,使得事务可以看到在事务开始时数据的一致性视图。

3.1 MVCC的实现原理

InnoDB的MVCC主要通过以下几个部分来实现:

  1. 隐藏列:每行数据都有两个隐藏列

    1. DB_TRX_ID:最后一次插入或更新该行的事务ID
    2. DB_ROLL_PTR:回滚指针,指向该行的上一个版本(存储在undo log中)
  2. Undo Log:保存了数据被修改前的旧值,用于回滚和MVCC的数据读取。可以认为undo log存储数据的历史版本,通过指针会形成一个版本链。

  3. Read View:事务进行快照读操作时产生的读视图,用于判断当前事务能够看到哪个版本的数据。

让我们用一个图表来展示MVCC的基本结构:
MVCC

3.2 Read View详解

Read View是MVCC实现的核心,它包含以下重要信息:

  • m_ids:活跃事务列表,在生成Read View时活跃的读写事务ID列表,就是记录当前还未提交的事务列表
  • m_low_limit_id/(m_min_limit_id):活跃事务的最小事务id,就是活跃列表的最小值
  • m_up_limit_id/(m_max_limit_id):下一个事务应该被分配的事务id
  • m_creator_trx_id:生成该Read View的事务ID

注意:事务id是递增分配的

当一个事务要读取一行数据时,InnoDB会将该行的DB_TRX_ID(前面提到的,表示这行数据最近一次发生修改的事务id)与Read View中的信息进行比较,以决定是否可以看到该版本的数据:
1. DB_TRX_ID == m_creator_trx_id:当前读取的事务就是创建快照读的事务,说明就是该事务最近修改了这条数据,因此是可读的;
2. DB_TRX_ID < m_low_limit_id:当这条数据最新更改的事务id小于最小活跃事务id,就说明该事务id是已经提交的事务id,该条数据就可读
3. DB_TRX_ID >= m_up_limit_id:这条数据的最新记录是在快照建立之后执行的,显然属于不可读,根据回滚指针找到合适的历史版本数据进行返回
4. m_low_limit_id < DB_TRX_ID < m_up_limit_id:这条数据最新更改的事务id在最小活跃事务id和最大事务id(下一次分配的事务id)之间,那就需要去扫描活跃事务列表,判断是否有这个id存在:

  1. 有就说明该数据还没有被提交是不可读的,那么他就会根据DB_ROLL_PTR去找到该数据的历史版本,同样会进行判断,直至找到符合可读条件的数据返回
  2. 如果列表没有就表明该事务已经被提交了,就是可读的

快照可读

3.3 当前读与快照读

在InnoDB中,我们有两种读取数据的方式:

  1. 当前读(Current Read)

    1. 读取的是记录的最新版本
    2. 会对读取的记录进行加锁
    3. 常见的当前读操作:SELECT ... FOR UPDATE, SELECT ... LOCK IN SHARE MODE, UPDATE, DELETE
  2. 快照读(Snapshot Read)

    1. 读取的是记录的快照版本
    2. 不会对读取的记录进行加锁
    3. 常见的快照读操作:不带锁的SELECT

让我们用一个图表来说明当前读和快照读的区别:

快照读VS当前读

4. MVCC在不同隔离级别下的工作方式

MVCC主要工作在读已提交可重复读这两个隔离级别下:

  1. 读已提交

    1. 每次读取数据前都会生成一个新的Read View
    2. 能看到其他事务已经提交的修改
  2. 可重复读

    1. 在事务开始时生成一个Read View,并在整个事务过程中使用这个Read View
    2. 保证在同一事务中多次读取数据时结果一致

让我们用一个例子来说明这两种隔离级别下MVCC的工作方式:

MVCC2

5. MVCC解决幻读问题

虽然MVCC可以有效解决不可重复读问题,但对于幻读,它只能提供部分解决方案。在可重复读隔离级别下,MVCC可以防止"快照读"出现幻读,但无法完全阻止"当前读"的幻读问题。

为了进一步解决幻读问题,InnoDB引入了Next-Key Lock(临键锁)机制,它是记录锁(Record Lock)和间隙锁(Gap Lock)的组合。
临键锁

Next-Key Lock不仅锁定查询涉及的索引记录,还锁定这些记录之间的间隙,有效防止了其他事务在查询范围内插入新记录,从而解决了幻读问题。

6. MVCC的优缺点

优点:

  1. 提高并发性:允许读写并发,读操作不会阻塞写操作,写操作也不会阻塞读操作。
  2. 解决一致性问题:提供了一致性的数据视图,避免了脏读和不可重复读问题。
  3. 降低锁竞争:通过版本链和快照读,减少了锁的使用范围,从而提高了系统的整体性能。
  4. 支持时间点查询:可以查询某个时间点的历史数据,对于某些应用场景非常有用。

缺点:

  1. 存储开销:需要额外的存储空间来保存多个版本的数据。
  2. 复杂性:实现和维护MVCC机制相对复杂,增加了数据库系统的复杂度。
  3. 清理问题:需要定期清理无用的历史版本,否则可能导致存储空间的浪费。
  4. 事务大小限制:长事务可能会导致版本链过长,影响性能。

7. MVCC在实际应用中的注意事项

  1. 合理设置隔离级别:根据应用需求选择适当的隔离级别,避免过度使用高隔离级别带来的性能开销。
  2. 控制事务大小:尽量使用短事务,避免长事务导致的版本链过长问题。
  3. 定期维护:对于频繁更新的表,需要定期进行维护操作,如优化表结构、清理无用的历史版本等。
  4. 索引优化:合理设计索引可以提高MVCC的效率,减少不必要的版本链遍历。
  5. 监控与调优:定期监控系统性能,关注MVCC相关的指标,如undo log的大小、长事务的数量等,及时进行调优。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络编程 02:IP 地址,IP 地址的作用、分类,通过 Java 实现 IP 地址的信息获取

一、概述 记录时间 [2024-12-18] 前置文章&#xff1a;网络编程 01&#xff1a;计算机网络概述&#xff0c;网络的作用&#xff0c;网络通信的要素&#xff0c;以及网络通信协议与分层模型 本文讲述网络编程相关知识——IP 地址&#xff0c;包括 IP 地址的作用、分类&#xff…

游戏AI实现-寻路算法(Dijkstra)

戴克斯特拉算法&#xff08;英语&#xff1a;Dijkstras algorithm&#xff09;&#xff0c;又称迪杰斯特拉算法、Dijkstra算法&#xff0c;是由荷兰计算机科学家艾兹赫尔戴克斯特拉在1956年发现的算法。 算法过程&#xff1a; 1.首先设置开始节点的成本值为0&#xff0c;并将…

【第二节】Git 工作流程、概念及仓库创建

目录 一、Git 工作流程 二、Git 基本概念 2.1 工作区 2.2 暂存区 2.3 版本库 2.4 操作流程 三、Git 仓库创建 3.1 初始化仓库 3.2 克隆仓库 一、Git 工作流程 Git 的工作流程通常包括以下几个步骤&#xff1a; 1. **克隆 Git 资源**&#xff1a;将远程 Git 仓库克隆到…

概率论得学习和整理30: 用EXCEL 描述泊松分布 poisson distribution

目录 1 泊松分布的基本内容 1.1 泊松分布的关键点 1.1.1 属于离散分布 1.1.2 泊松分布的特点&#xff1a;每个子区间内概率相等 &#xff0c; λ就是平均概率 1.2 核心参数 1.3 pmf公式 1.4 期望和方差 2 例1&#xff1a;用EXCEL计算泊松分布的概率 3 比较λ不同值时…

【机器学习】【无监督学习——聚类】从零开始掌握聚类分析:探索数据背后的隐藏模式与应用实例

从零开始掌握聚类分析&#xff1a;探索数据背后的隐藏模式与应用实例 基本概念聚类分类聚类算法的评价指标&#xff08;1&#xff09;内部指标轮廓系数&#xff08;Silhouette Coefficient&#xff09;DB指数&#xff08;Davies-Bouldin Index&#xff09;Dunn指数 &#xff08…

灵活接入第三方接口,解析第三方json数据,返回我们想要的json格式

需求&#xff1a;我想接入任意第三方http 接口&#xff08;暂不考虑鉴权问题&#xff09;、接口返回任意json数据。 1、要求返回的json数据通过我的R< T > 返回。 2、我的R< T > 里面包含参数 data&#xff0c;code&#xff0c;msg&#xff0c;success标识。 3、…

Nginx 在不同操作系统下的安装指南

Nginx 在不同操作系统下的安装指南 一、Linux 系统下 Nginx 的安装 &#xff08;一&#xff09;基于 Ubuntu 系统 更新软件包列表 打开终端&#xff0c;首先执行sudo apt-get update命令。这一步是为了确保系统的软件包列表是最新的&#xff0c;能够获取到最新版本的 Nginx 及…

docker redis 详细教程

1. 拉取镜像 docker pull redis 2. 创建数据存储目录 cd /home/ mkdir redis cd redis mkdir data mkdir log mkdir conf 3.创建容器并且运行 docker run \ -p 6379:6379 \ --name redis \ -v /home/redis/data:/data \ -d redis 参考链接 史上最详细Docker安装Redis &am…

学技术学英文:代码中的锁:悲观锁和乐观锁

本文导读&#xff1a; 1. 举例说明加锁的场景&#xff1a; 多线程并发情况下有资源竞争的时候&#xff0c;如果不加锁&#xff0c;会出现数据错误&#xff0c;举例说明&#xff1a; 业务需求&#xff1a;账户余额>取款金额&#xff0c;才能取钱。 时间线 两人共有账户 …

云计算赋能:TSP 问题求解与创新定价机制的全景剖析

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;编程探索专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年12月18日14点02分 神秘男子影, 秘而不宣藏。 泣意深不见, 男子自持重, 子夜独自沉。 论文源地址&#xff1a; Aspiringco…

二、windows环境下vscode使用wsl教程

本篇文件介绍了在windows系统使用vscode如何连接使用wsl&#xff0c;方便wsl在vscode进行开发。 1、插件安装 双击桌面vscode&#xff0c;按快捷键CtrlShiftX打开插件市场&#xff0c;搜索【WSL】点击安装即可。 2、开启WSL的linux子系统 点击左下方图标【Open a Remote Win…

QScreen在Qt5.15与Qt6.8版本下的区别

简述 QScreen主要用于提供与屏幕相关的信息。它可以获取有关显示设备的分辨率、尺寸、DPI&#xff08;每英寸点数&#xff09;等信息。本文主要是介绍Qt5.15与Qt6环境下&#xff0c;QScreen的差异&#xff0c;以及如何判断高DPI设备。 属性说明 logicalDotsPerInch&#xff1…

【已解决】在Visual Studio里将应用与Microsoft Store关联时提示网络异常

发布Windows应用时。在Visual Studio里点击"发布“&#xff0c;将应用与Microsoft Store关联时&#xff0c;一直提示网络错误。 查了一下论坛&#xff0c;发现之前也经常出现&#xff0c;但我是第一次遇到。 不能就这样一直被卡着呀&#xff0c;研究了一下&#xff0c;还…

【从零开始入门unity游戏开发之——C#篇10】循环结构——while、do-while、for、foreach的使用

文章目录 一、while 循环1、语法&#xff1a;2、示例&#xff1a; 二、 do-while 循环1、语法&#xff1a;2、示例&#xff1a; 三、for 循环1、语法&#xff1a;2、示例&#xff1a; 四、foreach 循环1、语法&#xff1a;2、示例&#xff1a; 五、总结对比六、注意事项七、使用…

【数据分析】数据结构数据内容概述

文章目录 表格结构数据特征数据类别结构化数据表格结构数据层级表格结构的数据类型单元格的格式属性 表格结构数据获取方法从企业后台数据库系统获取后台数据库系统获取数据流程前端操作平台获取从企业外部渠道获取数据 表格结构数据使用方法单元格值的引用方法单元格区域值的引…

控制策略和算法:两者的类型、应用领域

目录 控制策略类型&#xff1a; 控制算法类型&#xff1a; 应用领域&#xff1a; 其他学术知识 控制策略类型&#xff1a; 开环控制&#xff1a; 在没有反馈的情况下&#xff0c;控制信号是根据对系统模型的预测或设定目标生成的。适用于系统动态特性已知且外部干扰较小的情…

Nacos 3.0 考虑升级到 Spring Boot 3 + JDK 17 了!

Nacos 由阿里开源&#xff0c;是 Spring Cloud Alibaba 中的一个重要组件&#xff0c;主要用于发现、配置和管理微服务。 由于 Spring Boot 2 的维护已于近期停止&#xff0c;Nacos 团队考虑升级到 Spring Boot 3 JDK 17&#xff0c;目前正在征求意见和建议。 这其实是一件好…

【笔记】RT-Thread Studio+STM32CubeMX联合开发,使用SPI+DMA驱动WS2812B RGB灯条,实现单独操控任意灯珠。

硬件平台&#xff1a;STM32L431RCT6 软件版本&#xff1a;RT-Thread Studio 2.2.8&#xff0c;STM32CubeMX 6.12.0 RT-Thread版本&#xff1a;4.1.0 言&#xff1a;之前写过一篇WS2812B的教程&#xff0c;但是最近扒出来用发现不能单独点亮或者熄灭特定位置的灯珠&#xff0c;只…

Vue 中实现节点对齐

Vue 如何将两个 Dom 节点进行对对齐&#xff0c;在前端页面中如何快速的对两个节点元素进行对齐操作&#xff0c;最简单的方式就是使用 Postion&#xff1a;Relative 加 Absolute 实现两个元素的相对位置。今天使用 dom-align 库实现节点对齐&#xff0c;实现以下效果&#xff…

计算机网络-HTTP协议

HTTP HTTP是一种不保存状态&#xff0c;即无状态的协议。HTTP协议自身不对请求和响应之间的通信进行保存。为了保存状态因此后面也有一些技术产生比如Cookies技术。 HTTP是通过URI定位网上的资源&#xff0c;理论上将URI可以访问互联网上的任意资源。 如果不是访问特定的资源…