【Mysql】深入理解 MVCC 多版本并发控制
MVCC
MVCC(Multi-Version Concurrency Control),即多版本并发控制。是 innodb 实现事务并发与回滚的重要功能。锁机制可以控制并发操作,但是其系统开销较大,而MVCC可以在大多数情况下代替行级锁,使用MVCC,能降低其系统开销.
具体实现是在数据库的每一行中,额外添加三个字段:
DB_TRX_ID
: 记录插入或更新该行的最后一个事务的事务ID
DB_ROLL_PTR
: 指向改行对应undolog
的指针
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)# MVCC
MVCC(Multi-Version Concurrency Control),即多版本并发控制。是 innodb 实现事务并发与回滚的重要功能。锁机制可以控制并发操作,但是其系统开销较大,而MVCC可以在大多数情况下代替行级锁,使用MVCC,能降低其系统开销.
具体实现是在数据库的每一行中,额外添加三个字段:
DB_TRX_ID
: 记录插入或更新该行的最后一个事务的事务ID
DB_ROLL_PTR
: 指向改行对应undolog
的指针
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)
【Mysql】深入理解 MVCC 多版本并发控制的更多相关文章
- MySQL MVCC(多版本并发控制)
概述 为了提高并发MySQL加入了多版本并发控制,它把旧版本记录保存在了共享表空间(undolog),当事务提交之后将重做日志写入磁盘(前提innodb_flush_log_at_trx_commit ...
- mysql的MVCC多版本并发控制机制
MVCC多版本并发控制机制 全英文名:Multi-Version Concurrency Control MVCC不会通过加锁互斥来保证隔离性,避免频繁的加锁互斥. 而在串行化隔离级别为了保证较高的隔 ...
- InnoDB学习(五)之MVCC多版本并发控制
MVCC多版本并发控制,是一种数据库管理系统并发控制的方法.MVCC多版本并发控制下,数据库中的数据会有多个版本,分别对应不同的事务,从而达到事务之间并发数据的隔离.MVCC最大的优势是读不加锁,读写 ...
- MVCC多版本并发控制
MVCC多版本并发控制 爱情小傻蛋关注 82019.09.28 23:23:37字数 4,740阅读 91,421 前提概要 什么是MVCC 什么是当前读和快照读? 当前读,快照读和MVCC的关系 M ...
- [MySQL] MVCC 多版本并发控制实现的事务
1.没有一个统一的实现标准,实现了非阻塞的读操作,写操作也只锁定必要的行2.通过保存数据在某个时间点的快照实现的3.典型的有乐观并发控制和悲观并发控制4.innodb的mvcc是每次事务都有递增的版本 ...
- MVCC多版本并发控制的理解
前置知识 当前读与快照读 当前读 什么是当前读:读取的是最新的数据,不会读到老数据. 何时触发:update.insert.delete.select lock in share mode.selec ...
- 针对MySQL的MVCC多版本并发控制的一些总结
MVCC MVCC细节太多,我直接备忘一下总结: MVCC就是通过事务的ID与行数据的版本(修改事务的ID)进行比较(通过redo log可以回溯版本)得出哪些版本的行数据可见和不可见而实现的事务隔离 ...
- 聊聊MVCC多版本并发控制
一.介绍 MVCC只在RR和RC 2个隔离级别下才能工作.MySQL的大多数事务存储引擎实现的都不是简单的行级锁机制.基于提升并发性能的考虑,它们一般都同时实现了MVCC. 通俗的来讲,MVCC是行级 ...
- MVCC 多版本并发控制
关于事务的介绍暂且不谈. InnoDB行级锁,虽然在很大程度上提高了事务的并发性,但是终究还是要耗费很大的.为了更进一步的提高并发性同时降低开销,存储引擎会同时实现MVCC. InnoDB实现MVCC ...
随机推荐
- android和IOS自动化定位方法
元素定位 方法:id定位,name定位(text定位),class_name定位, accessibility_id定位,xpath定位等 (目前1.5版本的已经不支持name定位了),所以APP的定 ...
- 哈工大知识图谱(Knowledge Graph)课程概述
一.什么是知识图谱 知识(Knowledge)可以理解为 精炼的数据,知识图谱(Knowledge Graph)即是对知识的图形化表示,本质上是一种大规模语义网络 (semantic network) ...
- CAD网页Web端显示开发为什么要以WebGIS的思路来开发?
背景 在之前的博文CAD图DWG解析WebGIS可视化技术分析总结中讲解了如何把CAD的DWG格式的图纸Web可视化的方案.博文发布后,受到不少同行们的关注,也有不少咨询一些专业问题,其中大家可能疑惑 ...
- 初学python-day5 集合
- 【Spring】IoC容器 - Spring Bean作用域Scope(含SpringCloud中的RefreshScope )
前言 上一章学习了[依赖来源],本章主要讨论SpringBean的作用域,我们这里讨论的Bean的作用域,很大程度都是默认只讨论依赖来源为[Spring BeanDefinition]的作用域,因为在 ...
- abstract使用方式
springMVC中的 LocalContextHolder是一个 abstract类.里边方法都是static 的. 不能被继承.不能实例化.只能调用其定义的static 方法.这种 abstrac ...
- 软件工程个人博客作业-软件案例分析:VS与VS Code
项目 内容 本作业属于北航 2020 年春软件工程 博客园班级连接 本作业是本课程个人项目作业 作业要求 我在这个课程的目标是 提高软件开发能力.团队协作能力 这个作业在哪个具体方面帮助我实现目标 提 ...
- 助你上手Vue3全家桶之Vue3教程
目录 前言 1,setup 1.1,返回值 1.2,注意点 1.3,语法 1.4,setup的参数 2,ref 创建响应式数据 3,reactive 创建响应式数据 4,computed 计算属性 5 ...
- 表示数值的字符串 牛客网 剑指Offer
表示数值的字符串 牛客网 剑指Offer 题目描述 请实现一个函数用来判断字符串是否表示数值(包括整数和小数).例如,字符串"+100","5e2"," ...
- 面试官问我JVM内存结构,我真的是
面试官:今天来聊聊JVM的内存结构吧? 候选者:嗯,好的 候选者:前几次面试的时候也提到了:class文件会被类加载器装载至JVM中,并且JVM会负责程序「运行时」的「内存管理」 候选者:而JVM的内 ...