MySQL多版本并发控制MVCC深入学习

 更新时间:2021年11月28日 16:10:50   作者:CJ-cooper  
这篇文章主要介绍了MySQL多版本并发控制MVCC,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

MVCC

MVCC(Multi-Version Concurrency Control),即多版本并发控制。是 innodb 实现事务并发与回滚的重要功能。锁机制可以控制并发操作,但是其系统开销较大,而MVCC可以在大多数情况下代替行级锁,使用MVCC,能降低其系统开销.

具体实现是在数据库的每一行中,额外添加三个字段:

  1. DB_TRX_ID : 记录插入或更新该行的最后一个事务的事务ID
  2. DB_ROLL_PTR : 指向改行对应undolog 的指针
  3. DB_ROW_ID : 单调递增的ID,他就是AUTO_INCREMENT的主键ID

快照读

像不加锁的select操作就是快照读,快照读的出现是基于提高并发性能的考虑,快照读的实现是基于多版本并发控制,即MVCC。可以认为 MVCC 是行锁的一个变种,在很多情况下,避免了加锁操作,降低了开销;既然是基于多版本,即快照读可能读到的并不一定是数据的最新版本,而有可能是之前的历史版本

当前读

读取的是当前的数据,不需要通过undo log回溯到事务开启前的状态。读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。

数据库并发场景有三种,分别为:

  • 读-读:不存在任何问题,也不需要并发控制
  • 读-写:有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读,幻读,不可重复读
  • 写-写:有线程安全问题,可能会存在更新丢失问题,比如第一类更新丢失,第二类更新丢失

说白了 MVCC 就是为了实现读-写冲突不加锁,而这个读指的就是快照读, 而非当前读,当前读实际上是一种加锁的操作,是悲观锁的实现

MVCC的出现就是大佬们不满意用悲观锁去解决读-写冲突问题,所以有两个方案:

  • MVCC + 悲观锁
    MVCC解决读写冲突,悲观锁解决写写冲突
  • MVCC + 乐观锁
    MVCC 解决读写冲突,乐观锁解决写写冲突

MVCC实现原理

三个隐藏字段

  • DB_TRX_ID
    6 字节,最近修改(修改/插入)事务 ID:记录创建这条记录/最后一次修改该记录的事务 ID
  • DB_ROLL_PTR
    7 字节,回滚指针,指向这条记录的上一个版本(存储于 rollback segment 里)
  • DB_ROW_ID
    6 字节,隐含的自增 ID(隐藏主键),如果数据表没有主键,InnoDB 会自动以DB_ROW_ID产生一个聚簇索引

版本链 / undo log

因为undo log会记录事务前老版本数据,然后行记录中回滚指针会指向老版本位置,如此形成一条版本链。Read View 会一直遍历链表的DB_TRX_ID,直到找到满足特定条件的 DB_TRX_ID。那么这个DB_TRX_ID所在的旧记录就是当前事务能看见的最新”老版本“

Read View

是事务开启时,当前所有活跃事务(还未提交的事务)的一个集合。或者说Read View 就是事务进行快照读操作的时候生产的读视图 (Read View),在该事务执行的快照读的那一刻,会生成数据库系统当前的一个快照,记录并维护系统当前活跃事务的 ID

三个Read View重要结构:

  • trx_list(名称我随意取的)
    一个数值列表
    用于维护 Read View 生成时刻系统 正活跃的事务 ID 列表
  • up_limit_id
    是 trx_list 列表中事务 ID 最小的 ID
  • low_limit_id

ReadView 生成时刻系统尚未分配的下一个事务 ID ,也就是 目前已出现过的事务 ID 的最大值 + 1

为什么是 low_limit ? 因为它也是系统此刻可分配的事务 ID 的最小值

MVCC实现的整体流程:

总结

  • 应对高并发事务, MVCC比单纯的加锁更高效
  • MVCC只在 读已提交 和 可重复读 两个隔离级别下工作
  • 读已提交隔离级别下,会在每次快照读(查询)都生成一个Read View,可重复读只在事务开始时生成一个Read View,以后每次查询都用这个Read View,以此实现不同隔离级别。

参考:

【MySQL笔记】正确的理解MySQL的MVCC及实现原理_(推荐)

MySQL · 引擎特性 · InnoDB 事务系统 (taobao.org)

mvcc详解 - 简书 (jianshu.com)

到此这篇关于MySQL多版本并发控制MVCC深入学习的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • MySQL备份恢复最佳实践指北

    MySQL备份恢复最佳实践指北

    这篇文章主要介绍了MySQL备份恢复最佳实践的终极指南详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • mysql自动停止 Plugin FEDERATED is disabled 的完美解决方法

    mysql自动停止 Plugin FEDERATED is disabled 的完美解决方法

    今天在配置服务器的时候,发现mysql的一个错误提示在 本地计算机 无法启动 MySQL 服务。错误 1067: 进程意外终止,其实原因很多这个不是导致进程意外终止的最终原因,但可以解决
    2016-04-04
  • MySQL慢查询以及解决方案详解

    MySQL慢查询以及解决方案详解

    MySQL的慢查询,全名是慢查询日志,是MySQL提供的一种日志记录,用来记录在MySQL中响应时间超过阀值的语句,下面这篇文章主要给大家介绍了关于MySQL慢查询以及解决方案的相关资料,需要的朋友可以参考下
    2023-05-05
  • MySQL InnoDB如何保证事务特性示例详解

    MySQL InnoDB如何保证事务特性示例详解

    这篇文章主要给大家介绍了关于MySQL InnoDB如何保证事务特性的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用MySQL具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-10-10
  • MySQL中SQL命令语句条件查询实例详解

    MySQL中SQL命令语句条件查询实例详解

    SELECT语句可以通过WHERE条件来设定查询条件,查询结果是满足查询条件的记录,下面这篇文章主要给大家介绍了关于MySQL中SQL命令语句条件查询的相关资料,需要的朋友可以参考下
    2022-11-11
  • MySQL8新特性:持久化全局变量的修改方法

    MySQL8新特性:持久化全局变量的修改方法

    这篇文章主要给大家介绍了关于MySQL 8新特性:持久化全局变量的修改的相关内容,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-07-07
  • mysql之如何查找配置文件my.ini的位置

    mysql之如何查找配置文件my.ini的位置

    这篇文章主要介绍了mysql之如何查找配置文件my.ini的位置问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • Mysql慢查询优化方法及优化原则

    Mysql慢查询优化方法及优化原则

    这篇文章主要介绍了Mysql慢查询优化方法及优化原则,本文给大家介绍的非常详细,具有一定的参考借鉴价值 ,需要的朋友可以参考下
    2019-05-05
  • 想取消错误的mysql命令怎么办?

    想取消错误的mysql命令怎么办?

    今天小编就为大家分享一篇关于想取消错误的mysql命令怎么办?,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-04-04
  • 尽量避免使用索引合并的场景问题解析

    尽量避免使用索引合并的场景问题解析

    这篇文章主要为大家介绍了尽量避免使用索引合并的场景问题解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05

最新评论