展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 编程开发 > MySQL MVVC多版本并发控制如何实现

MySQL MVVC多版本并发控制如何实现

一、概述MVCC(MultiversionConcurrencyControl),多版本并发控制。它和undolog中的版本链息息相关,MVVC通过数据行的多个版本来实现数据库的并发控制。简单的说就是当前事务查询另一个事务正在更改的行(如果此时读取就会发生脏读),不用加锁等待,而是读取该数据的历史版本,降低响应时间。MVVC是通过undolog和ReadView两种技术实现的。二、快照读与当前读MVCC在MySQLInnoDB中的实现主要是为了提高数据库并发性能,用更好的方式去处理读-写冲突,做到即使有读

本文目录

    一、概述

    MVCC(Multiversion Concurrency Control),多版本并发控制。它和undo log中的版本链息息相关,MVVC通过数据行的多个版本来实现数据库的并发控制。

    简单的说就是当前事务查询另一个事务正在更改的行(如果此时读取就会发生脏读),不用加锁等待,而是读取该数据的历史版本,降低响应时间。

    MVVC是通过undo log和Read View两种技术实现的。

    二、快照读与当前读

    MVCC在MySQL InnoDB中的实现主要是为了提高数据库并发性能,用更好的方式去处理读-写冲突,做到即使有读写冲突时,也能做到不加锁,非阻塞并发读 ,而这个读指的就是快照读 , 而非当前读。当前读实际上是一种加锁的操作。

    1.当前读

    当前读读取的记录一定是最新的数据,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。

    加锁的读被称为当前读,还有数据的增删改都是要先读取数据的,这一读取过程也是当前读。

    SELECT * FROM t LOCK IN SHARE MODE; # 共享锁
    SELECT * FROM t FOR UPDATE; # 排他锁
    UPDATE SET t..

    2.快照读

    快照读又叫一致性读,读取的是数据行的快照版本。在MySQL中,普通的select语句(不加for update或lock in share mode的select语句)默认就是使用的快照读,不加锁。

    SELECT * FROM table WHERE ...

    之所以这样,是因为快照读可以避免加锁操作,降低开销。

    当事务的隔离级别是串行时,快照读就没有用了,会退化为当前读。

    三、隔离级别与版本链复习

    隔离级别:

    在MySQL中默认的隔离级别就是可重复读RR,可以解决不可重复读问题,在MySQL中,特别的还额外支持解决幻读问题。

    它是如何解决幻读问题的呢?有两种方式:

    • 使用间隙锁和临键锁解决,简而言之就是加锁,在此期间其他事务不能够插入数据

    • MVCC方式,无需加锁,消耗低(缺点是没有完全解决幻读问题)。

    undo log版本链:

    对应InnoDB来说,聚簇索引中的每个记录都包含了两个必要的隐藏字段:

    • trx_id:每次一个事务对某条聚簇索引记录进行改动时,都会把该事务的事务id赋值给trx_id隐藏列。

    • roll_pointer:回滚指针,每次修改数据时,都会把旧数据放入undo log日志中,新的数据指向该旧数据,做成一个版本链,该指针字段就称为回滚指针,通过该指针可以找到修改前的数据。

    举例:

    有一个id为8的事务创建了一条数据,那么该记录的示意图大概如下:

    MySQL MVVC多版本并发控制如何实现

    假设之后两个id分别为10、20的事务对这条记录进行update操作,流程如下:

    事务10事务20
    BEGIN; 
     BEGIN;
    UPDATE student SET name='李四' WHERE id=1; 
    UPDATE student SET name='王五' WHERE id=1; 
    COMMIT; 
     UPDATE student SET name='赵六' WHERE id=1;
     UPDATE student SET name='钱七' WHERE id=1;
     COMMIT;

    每次修改都会生成一个undo log日志,每个日志都相互链接,构成版本链,此时该条数据的示意图如下:

    MySQL MVVC多版本并发控制如何实现

    每个版本中还包含生成该版本时对应的事务id 。

    四、Read View

    有了undo log就可以读取到记录的历史版本,那么在什么情况下,读取哪个版本的记录呢?这就用到了Read View,它帮我们解决了行的可见性问题。

    Read View就是当某个事务在使用MVVC机制进行快照读操作时产生的读视图。该视图是数据库当前所有活跃事务id(还未提交的事务)组成的列表的一个快照。

    1.实现原理

    四种隔离级别里,读未提交和串行化是不会使用MVVC的,因为读未提交直接读取某个数据的最新数据即可,串行化是通过加锁来读的。

    读已提交和可重复读都必须保证读到的数据都是其他事务提交了的,所以,其他事务修改了数据但是还未提交,我们不能够访问该数据,但可以通过MVVC机制读取该记录的历史版本,核心问题就是需要判断版本链中的哪条历史版本是当前事务可见的,这也是ReadView要解决的问题。

    Read View包含4个比较重要的内容:

    • creator_trx_id:创建这个Read View的事务id,Read View和事务是一一对应的。

    只有事务对表中的记录做修改时才会为事务分配事务id,否则一个事务中只有读操作,该事务的id默认为0。

    • trx_ids:表示在生成Read View时当前系统中活跃的事务id列表。提交了的事务不在其中。

    • up_limit_id:活跃的事务中最小的事务id。

    • low_limit_id:表示生成Read View时系统应该分配给下一个事务的id值,同样也表示系统中最大的事务id值。

    注意:low_limit_id并不是trx_ids中的最大值,事务id是递增分配的。比如,现在有id为1, 2,5这三个事务,之后id为5的事务提交了。那么一个新的读事务在生成ReadView时, trx_ids就包括1和2,up_limit_id的值就是1,low_limit_id的值就是6。

    MySQL MVVC多版本并发控制如何实现

    2.Read View规则

    MySQL MVVC多版本并发控制如何实现

    版本链

    当某个事务有了Read View,访问某条记录时,需要按照下面的步骤判断该记录的哪个版本可见:

    • 如果该版本记录的trx_id和Read View的creator_trx_id相同,意味着该版本的记录是由当前事务修改的,因此该版本可以被当前事务访问

    • 如果该版本记录的trx_id小于Read View的up_limit_id,证明当前事务生成Read View时,此事务已经提交了,所以当前事务可以读取该版本。

    • 如果该版本的trx_id大于等于low_limit_id,证明生成该版本的事务在当前事务生成Read View之后才开启,所以该版本不可以被当前事务访问。

    • 如果被访问版本的trx_id属性值在ReadView的up_limit_id和low_limit_id之间,那就需要判断一下trx_id属性值是不是在trx_ids列表中,如果不在的话才能访问,否则不能访问。

    3.整体流程

    了解了这些概念之后,我们来看下当查询一条记录的时候,系统如何通过MVCC找到它:

    • 首先获取事务自己的版本号,也就是事务ID;

    • 获取 ReadView;

    • 查询得到的数据,然后与 ReadView 中的事务版本号进行比较;

    • 如果不符合 ReadView 规则,就需要从Undo Log中获取历史快照;

    • 最后返回符合规则的数据。

    在隔离级别为读已提交时,一个事务中的每一次SELECT查询都会重新获取一次Read View,而可重复读是第一SELECT操作才会生成Read View,之后的查询操作复用这一个。

    导致这两种的差距是因为:可重复读要保证一个事务中相同的SELECT读取的内容是相同的。

    MySQL MVVC多版本并发控制如何实现

    五、举例

    1.READ

    COMMITTED隔离级别下

    现在有两个事务id分别为10、20的事务在执行:

    -- id为10的事务
    begin;
    update t set name='李四' where id=1;
    update t set name='王五' where id=1;
    -- id为20的事务
    更新其他行的数据

    此刻,表中id为1的记录得到的版本链表如下所示:

    MySQL MVVC多版本并发控制如何实现

    此时新来一个事务执行如下操作:

    begin;
    select * from t where id=1;
    -- 事务10、20未提交

    查询到的结果为张三。

    具体的过程如下:

    • 在执行select语句前,先生成一个Read View,Read View的creator_trx_id为0,trx_ids列表的内容是[10,20],up_limit_id为10,low_limit_id为21。

    • 查询name为王五的最新版本的记录,按规则进行对比,因为trx_id为10,10刚好是trx_ids中的记录,所以这条记录对当前事务不可见,根据回滚指针得到下一个版本

    • 下一个版本name为李四,也不行

    • 继续找到name为张三的版本,trx_id为8,8小于up_limit_id,所以该版本对当前事务可见,得到最终结果

    接下来,再将id为10的事务进行commit提交。然后id为20的事务来更新记录:

    begin;
    -- id为20的事务
    update t set name='赵六' where id=1;
    update t set name='钱七' where id=1;

    此时版本链更新为:

    MySQL MVVC多版本并发控制如何实现

    再到刚才使用READ COMMITTED隔离级别的事务中继续查找这个id 为1的记录,得到的结果为name=王五的那条记录。执行过程如下:

    • 生成Read View,Read View的creator_trx_id为0,trx_ids列表的内容是[20],up_limit_id为20,low_limit_id为21。

    • 因为前两个版本的记录trx_id为20,存在trx_ids中,所以跳过

    • 到第三条记录时,trx_id为10,小于20,可以读取,所以最终结果为王五

    注意:READ COMMITTED,每次读取数据前都生成一个新的ReadView。

    2.REPEATABLE READ隔离级别下

    假如此时id为10的事务和id为20的事务正在修改,都未提交,修改内容和前面的一样,但是还未提交,此时当前事务做一个查询。

    MySQL MVVC多版本并发控制如何实现

    步骤为:

    • 生成Read View,Read View的creator_trx_id为0,trx_ids列表的内容是[10,20],up_limit_id为10,low_limit_id为21。

    • trx_id为10和20的都不满足要求

    • 最后查找到name为张三的历史版本的数据

    此时,id为10的记录提交事务。

    MySQL MVVC多版本并发控制如何实现

    当前事务又需要select id为1的记录,步骤为:

    • 因为是可重复读,且第一次select已经生成过Read View了,所有会复用它,不重新生成。

    • 所以trx_id为10和20的记录依旧不符合规则,最终得到的数据还是张三,符合可重复读的规范

    注意:REPEATABLE READ,每次读取都复用第一次生成的Read View

    3.如何解决幻读

    假设现在有一条数据,id为1

    MySQL MVVC多版本并发控制如何实现

    当前活跃的事务有10和20。

    此时当前事务启动了,执行如下SQL语句:

    begin;
    select * from student where id>=1;

    在开始前生成Read View,内容如下:creator_trx_id=0,trx_ids= [10,20] , up_limit_id=10, low_limit_id=21。

    由于id大于等于1的数据只有一个,且该数据的trx_id为8,小于up_limit_id,所以可以读取到。

    在这之后id为10的事务新增了一行数据,增加了id为2的数据,且提交了。

    MySQL MVVC多版本并发控制如何实现

    此时当前线程继续查找id>=1的数据,因为是可重复读,复用刚刚的Read View。

    得到两行数据,但是因为id为2的数据trx_id为10,该值在Read View的trx_ids中存在,所以该记录对当前事务不可见,所以最后查询到的数据只有一条记录。

    如果当前事务再插入id为2的数据就插不进去,所以说MVVC只解决了一半的幻读问题。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 MySQL
    相关文章 更多
    精品专题 更多
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    IOS软件

    正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

    AI

    正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw macOS版
    AionClaw macOS版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy macOS版
    Loomy macOS版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirBuddy 3 macOS版
    AirBuddy 3 macOS版

    AirBuddy 3 是面向 macOS 的蓝牙外设增强工具,可集中查看 AirPods、Beats 与苹果设备电量,提供快速连接、播放控制、电量提醒、桌面小组件和多台 Mac 外设接力等功能。

    AirServer macOS版
    AirServer macOS版

    AirServer macOS版可把 Mac 转换为无线投屏接收端,通过 AirPlay 或 Google Cast 接收手机、平板和电脑画面,并支持多设备同时连接、高清镜像及会话录制,适合家庭娱乐、课堂教学、会议演示和应用展示。

    AnyDesk macOS版
    AnyDesk macOS版

    AnyDesk macOS版是一款适用于远程办公、设备维护和客户支持的远程桌面工具,可连接并操作异地计算机,支持文件传输、无人值守访问、会话权限控制及跨平台协作。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。

    讯飞绘文 网页版
    讯飞绘文 网页版

    讯飞绘文网页版是科大讯飞推出的AI图文创作与内容运营工具,覆盖热点选题、文章生成、稿件校对、智能配图、排版发布和数据复盘等环节,适合自媒体创作者及内容团队在线使用。

    Maya(Autodesk Maya) Windows版
    Maya(Autodesk Maya) Windows版

    Autodesk Maya 是面向影视、电视、动画和游戏行业的专业三维制作软件,集多边形与 NURBS 建模、角色绑定、关键帧和动作捕捉动画、Bifrost 特效模拟、材质开发及 Arnold 渲染于一体,

    Aperty Windows版
    Aperty Windows版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw Windows版
    AionClaw Windows版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy Windows版
    Loomy Windows版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。