IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 系统了解Mysql-MVCC并发控制机制 -> 正文阅读

[大数据]系统了解Mysql-MVCC并发控制机制

前言

大概两年前因为排查一个数据可见性的问题也了解过 Mysql 的 MVCC,当时觉得自己都懂了,但始终没有将这块知识串联起来,所以总感觉印象不深刻,其实本质上还是因为没有搞清楚这个东西的来龙去脉,没有真正地理解它。

现在我也没法说都懂了,只能说比以前的我更进步了些。

本文主要包含以下内容:

  • 事务常见的并发问题
  • 事务隔离级别,在不同程度上解决了并发问题
  • 传统事务隔离级别,基于锁实现并发控制
  • MVCC 无锁实现并发控制
  • 幻读

并发问题

多个事务并发执行,常见的问题如下,

  • 读/读:没有数据改动,不存在并发问题。

  • 写/写,如果两个事务同时读取同一条记录,并基于旧值对其进行修改,则会出现前一个事务的修改被后一个事务的修改覆盖的问题;或者前一个事务提交之后另一个事务发生回滚,出现已提交的修改被回滚操作覆盖的问题。这两类问题统称为丢失更新。

读/写或写/读,这种场景最复杂,可能出现如下问题:

  • 一个事务读到另外一个事务未提交的修改,称为脏读
  • 一个事务中前后两次对同一记录的读取结果不一致,称为不可重复读
  • 一个事务中前后两次使用同样的查询条件读取数据,期间其它事务往表里插入了新数据,导致前后两次查询到的结果集不一致,称为幻读

将这些并发问题根据严重程度由高至低排序。

丢失更新 > 脏读 > 不可重复度 > 幻读

事务隔离级别

事务隔离级别在不同程度上解决了上述并发问题,保证事务本身特性(ACID),它是对并发问题的容忍性以及并发性能之间的权衡考量。

  • 读未提交(RU),允许读取未提交的记录,会发生脏读、不可重复读、幻读问题
  • 读已提交(RC),只允许读物已提交的记录,解决了脏读问题,但会出现不可重复读、幻读问题
  • 可重复读(RR),不会发生脏读和不可重复读的问题,但会发生幻读问题
  • 串行化(S),事务串行执行,不存在并发问题,当然性能也最差

以上隔离级别,除串行化不会存在丢失更新的问题,其它几种隔离级别都存在该问题,需要通过对读操作额外加锁解决。

基于锁的实现

传统的事务隔离级别是基于锁实现的。

按照锁的互斥性,可以把锁分为:

  • 共享锁(Shared Locks),简称 S锁
  • 排它锁(Exclusive Locks),简称 X锁

SS 不互斥,XS 互斥,XX 互斥,多个事务可以同时持有同一把 S锁。

按照锁的粒度,可以把锁分为:

  • 行锁,只锁定某一行记录,其他行不受影响
  • 表锁,锁住整个表

按照锁的持有时间,可以把锁分为:

  • 短锁,操作完成后立刻被释放
  • 长锁,直到事务提交后才被释放

四种隔离级别,对应的实现方式如下,

  • 读未提交:读操作不加锁,写操作加上X锁直到事务提交后释放。

  • 读提交:读操作加上S锁(且为短锁,操作完马上释放),写操作加上 X锁直到事务提交后释放。

  • 可重复读:读操作加上S锁(且为长锁,事务提交后被释放),写操作加上 X锁直到事务提交后释放。

  • 串行化:读写操作都加上X锁直到事务提交后释放,且锁的粒度为表锁。

可以在大脑里模拟下不同隔离级别的加锁场景,有助于加深对于并发控制的理解。

举个例子,读提交为什么能够解决脏读,因为它在读操作的时候需要加S锁,写操作需要加X锁,如果此时有其它未提交的事务修改了数据,它是没办法读取到数据的,需要等待其它事务提交或者回滚。

MVCC 实现

MVCC 英文全称 Multiversion Concurrency Control,即多版本并发控制,它通过无锁的方式实现了读提交,可重复读两种隔离级别下对于并发问题的控制,因此在系统性能方面也有显著的提升。

另外读未提交,串行化这两个隔离级别,不在 MVCC 的作用范围内,MVCC 侧重于优化读提交,可重复读隔离级别下读,写操作加锁互斥的性能问题。

MVCC 的核心实现主要包含两块内容:

  • 多版本
  • 读视图

多版本

为了保证在不加锁的情况下,解决读、写操作并发问题,MVCC 引入了多版本的概念,即一个数据行同一时间可能存在多个版本。

在 InnerDB 引擎下,数据行都会包含两个重要的隐藏列:

  • 事务ID(DB_TRX_ID):当事务对记录进行修改时,会把当前事务的事务ID记录到DB_TRX_ID中
  • 回滚指针(DB_ROLL_PTR):当事务对记录进行修改后,会把该记录的旧版本记录到undo日志中,通过回滚指针可以获取旧版本信息。

多个版本可以来源于不同事务,它们之间互不影响,这些版本按照先后顺序,被回滚指针被串联起来。

读视图

事务当前能够读取到哪个版本,则依赖读视图。

读视图本质上是一个数组,其中维护了一组事务id,例如[3, 4, 5, 6],

  • 3 代表视图创建时存在的活跃事务中id最小值,称为 min_id
  • 6 代表未来要创建的事务id,称为 max_id
  • 其余的都是活跃事务id

事务在读取版本记录时,会拿该版本上的事务id与视图做比较:

  • 如果该版本的事务id < min_id,则表示该版本在视图创建前已经提交,故该版本对当前事务可见
  • 如果该版本的事务id >= max_id,则表示该版本所属的事务在视图创建时还不存在,是未来创建的事务,故该版本对当前事务不可见
  • 如果 max_id > 该版本的事务id > min_id,则表示该版本所属的事务在视图创建时还未提交,故该版本对当前事务不可见
  • 当然如果该版本的事务id等于当前事务id,则认为该版本是由当前事务提交的,该版本对当前事务可见

如果发现符合条件的版本,直接返回;否则会通过回滚指针继续查找上一个版本的记录,直到将版本链遍历完还未找到符合条件的版本,则返回空。

读提交,可重复读两种隔离级别主要区别在于创建读视图的时机:

  • 读提交:每次读取数据都会创建新的视图,因此前后两次读取的结果可能不一致,期间别的事务提交的内容也能读到
  • 可重复读:只有在事务开启后首次读取数据会创建视图

注意:由于 MVCC 是采用快照读的方式进行并发控制,读到的数据可能不是最新版本,如果业务上需要读取最新版本的数据,可以通过为读操作加锁强制当前读。

幻读

MVCC 无法直接解决幻读,只有串行化才能解决幻读,但串行化也带来极大的性能问题。

后来间隙锁出现了,于是出现了 MVCC + 间隙锁的解决方案,在避免幻读的同时,还能保证性能。

举个例子,查询某记录是否存在,不存在,准备插入此记录,但执行 插入时发现此记录已存在(其它事务插入了),导致无法插入,此时就发生了幻读。

可以通过如下方式为查询加锁:

select * from table where id = 1 for update;

如果 id = 1 的记录已经存在,则对该记录加上行锁;如果不存在,则会把 id = 1 这个间隙锁上,其它事务无法对该间隙进行插入操作,故解决了幻读问题,当然实际上间隙锁要复杂得多。

通过这次对 MVCC 相关知识点的梳理串联,让自己发现了不少之前忽略的问题,也对 MYSQL 的并发控制机制有了更系统的认识。

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-02-22 20:40:12  更:2022-02-22 20:41:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:11:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码