MySQL 8.0 MVCC 源码解析

本文深入解析了MySQL 8.0中的MVCC(多版本并发控制)机制,详细介绍了MVCC的基础概念、事务隔离级别、InnoDB的MVCC实现,包括核心数据结构、增删改的底层操作以及一致性读取视图的构建。通过实例分析了MVCC如何解决并发事务中的问题,如脏读、不可重复读和幻读,并探讨了MVCC在不同事务隔离级别下的表现。文章适合对数据库并发控制感兴趣的读者,尤其是准备面试的Java开发者。
摘要由CSDN通过智能技术生成

微信搜索【程序员囧辉】,关注这个坚持分享技术干货的程序员。

前言

之前在 面试必问的 MySQL,你懂了吗?中简单的介绍了 MVCC 的原理,掌握了这个原理其实在面试时是可以加分不少的。

 

因为现在很多人的理解还是停留在《高性能 MySQL》书中的版本,也就是通过创建版本号删除版本号来判断。这个时候如果你能给出正确的理解,则会让面试官眼前一亮,这也是我们在面试中凸显出“自己和其他候选者不一样的地方”,会更有利于在众多候选者中脱颖而出。

 

本文在此基础上,对 MVCC 展开详细的分析,同时修改了之前的一些不太准确的说法,希望可以助你在面试中更好的发(zhuang)挥(bi)。

 

PS:本文的源码基于MySQL 8.0.16,对于现阶段生产环境常用的 5.7.* 版本,MVCC 部分的源码基本相同,因此可以放心参考。而 5.6.* 则有比较大的不同,主要是一些数据结构都改变了,但是究其核心原理还是基本一致的。

 

基础概念

并发事务带来的问题(现象)

脏读:一个事务读取到另一个事务更新但还未提交的数据,如果另一个事务出现回滚或者进一步更新,则会出现问题。

 

不可重复读:在一个事务中两次次读取同一个数据时,由于在两次读取之间,另一个事务修改了该数据,所以出现两次读取的结果不一致。

 

幻读:在一个事务中使用相同的 SQL 两次读取,第二次读取到了其他事务新插入的行。

 

要解决这些并发事务带来的问题,一个比较简单粗暴的方法是加锁,但是加锁必然会带来性能的降低,因此 MySQL 使用了 MVCC 来提升并发事务下的性能。

 

MVCC 带来的好处?

试想,如果没有 MVCC,为了保证并发事务的安全,一个比较容易想到的办法就是加读写锁,实现:读读不冲突、读写冲突、写读冲突,写写冲突,在这种情况下,并发读写的性能必然会收到严重影响。

 

而通过 MVCC,我们可以做到读写之间不冲突,我们读的时候只需要将当前记录拷贝一份到内存中(ReadView),之后该事务的查询就只跟 ReadView 打交道,不影响其他事务对该记录的写操作。

 

事务隔离级别

读未提交(Read Uncommitted):最低的隔离级别,会读取到其他事务还未提交的内容,存在脏读。

读已提交(Read Committed):读取到的内容都是已经提交的,可以解决脏读,但是存在不可重复读。

可重复读(Repeatable Read):在一个事务中多次读取时看到相同的内容,可以解决不可重复读,但是存在幻读。但是在 InnoDB 中不存在幻读问题,对于快照读,InnoDB 使用 MVCC 解决幻读,对于当前读,InnoDB 通过 gap locks 或 next-key locks 解决幻读。

串行化(Serializable):最高的隔离级别,串行的执行事务,没有并发事务问题。

 

 

InnoDB MVCC 实现

核心数据结构

trx_sys_t:事务系统中央存储器数据结构

struct trx_sys_t {
  TrxSysMutex mutex; /*! 互斥锁 */
​
  MVCC *mvcc;    /*!  mvcc */
​
  volatile trx_id_t max_trx_id; /*! 要分配给下一个事务的事务id*/
​
  std::atomic<trx_id_t> min_active_id; /*! 最小的活跃事务Id */
  
  // 省略...
​
  trx_id_t rw_max_trx_id; /*!< 最大读写事务Id */
​
  // 省略...
​
  trx_ids_t rw_trx_ids; /*! 当前活跃的读写事务Id列表 */
​
  Rsegs rsegs; /*!< 回滚段 */
​
  // 省略...
};

 

MVCC&#x

  • 52
    点赞
  • 140
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 25
    评论
MySQL存储引擎源码解析是一个非常广泛的话题,涉及到MySQL的整个存储引擎架构和实现细节。这里只能给出一个简要的概述,请注意这里只提供一般性的信息,具体的细节需要参考MySQL官方文档或相关专业书籍。 MySQL是一个开源的关系型数据库管理系统,它支持多种存储引擎,包括InnoDB、MyISAM、NDB Cluster等。每个存储引擎都负责管理数据的存储和检索,具有不同的特点和适用场景。 InnoDB是MySQL的默认存储引擎,它是一个基于B+树的事务型存储引擎,支持ACID事务和行级锁。InnoDB的源码主要包括存储引擎接口、缓冲池、日志、索引、锁等模块。它使用了多版本并发控制(MVCC)来实现高并发和数据一致性。 MyISAM是另一个常用的存储引擎,它采用了表级锁定和非事务性的设计。MyISAM的源码包括数据文件格式、索引、缓冲、锁等模块。相比于InnoDB,MyISAM对读操作具有较好的性能,但在写操作和并发性方面有一定的限制。 NDB Cluster是MySQL的分布式存储引擎,它是一个基于共享存储的集群数据库系统。NDB Cluster的源码包括数据节点、管理节点、事务协调器等模块,它使用了主从复制和数据分片等技术来实现高可用性和扩展性。 除了以上提到的存储引擎,MySQL还支持其他存储引擎,如MEMORY、CSV、BLACKHOLE等。每个存储引擎都有不同的数据结构、存储方式和性能特点,开发人员可以根据实际需求选择适合的存储引擎。 总的来说,MySQL存储引擎源码解析需要深入研究每个存储引擎的源码,了解其实现原理和具体实现细节。这需要一定的数据库和编程经验,以及对底层数据结构和算法的理解。如果你对具体的存储引擎有更深入的问题,可以提供更多细节,我会尽量回答。
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员囧辉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值