MySQL多版本并发控制mvcc原理浅析

这篇具有很好参考价值的文章主要介绍了MySQL多版本并发控制mvcc原理浅析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.mvcc简介
1.1mvcc定义

mvcc(Multi Version Concurrency Control),多版本并发控制,是一种数据库的并发控制机制。它用于管理事务并发执行时对数据的访问和修改,保证在多个事务同时对数据库进行读写操作,不会出现数据不一致或丢失的情况

1.2mvcc解决的问题

当多个事务同时访问数据库中的相同数据时,可能会有几种情况:

  • 读:多个事务都是读操作,不会产生并发问题
  • 读+写:事务有读有写,那么会产生脏读、不可重复读、幻读的问题
  • 写:多个事务同时写,可能会产生数据丢失、覆盖等问题

针对以上问题,在读+写的情况下,通常需要加锁来解决问题,mysql的innodb实现了mvcc来更好的处理读写冲突,做到不用加锁,实现非阻塞并发读

在都是写操作的情况下,只能通过加锁的方式解决。

1.3当前读与快照读

当前读:读取的是最新版本的数据,保证读取时不会有其他事务修改数据,需要对记录加锁

加共享锁,读不受影响,写会被阻塞

select ... lock in share mode;

加排他锁,读和写都被阻塞(快照读不受影响)

select ... for update;

更新、插入、删除操作以及串行化隔离级别都是当前读

快照读:每一次修改数据,都会在undolog中存有原始记录(快照),快照读就是读取某一版本的记录。这种方式能够不加锁读数据,但是可能会读到旧的数据。一般的查询都是快照读

select * from tablename;
2.mvcc原理

mvcc主要通过行记录中的隐藏字段、undolog和readview实现的

2.1隐藏字段

mysql中,在每一行记录中除了自定义的字段,还有3个隐藏的字段(innodb引擎)

  1. row_id:如果表没有自定义主键,那么会自动生成row_id作为主键
  2. trx_id:记录修改、新增这条记录的事务id
  3. roll_pointer:回滚指针,指向当前记录的上一个版本
2.2版本链

在修改数据时,mysql会向undolog中记录数据原来的快照,用于进行回滚操作。undolog还能用来实现mvcc

如以下例子,mvcc生成版本链:

当事务1001(trx_id=1001)执行了 insert into user values(1,'竹子',23) 之后:

MySQL多版本并发控制mvcc原理浅析,mysql,mysql,数据库

当事务1002(trx_id=1002)执行了 update user set name='竹笋' where id=1 之后:

MySQL多版本并发控制mvcc原理浅析,mysql,mysql,数据库

当事务1003(trx_id=1003)执行了 update user set name='竹叶' where id=1 之后:

MySQL多版本并发控制mvcc原理浅析,mysql,mysql,数据库

可以看到,不同版本的数据被指针连接起来形成了一个链表。

当我们要读取时,如何判断该读取哪个版本呢?这就与生成的读视图有关了。

2.3ReadView

读视图用于决定事务可以读到哪个版本的数据

它包含以下主要信息:

  1. trx_ids:当前mysql中所有活跃的事务id集合(没提交或回滚的事务集)
  2. low_limit_id:当前出现的最大的事务id+1,表示下一个要分配的事务id
  3. up_limit_id:当前活跃的事务id集合中,最小的事务id
  4. creator_trx_id:生成该ReadView视图的事务的id

MySQL5.7版本的源码对于这些信息的定义如下:
MySQL多版本并发控制mvcc原理浅析,mysql,mysql,数据库

插入一个注意事项:🐭🐮🐯🐰🐉🐍🐴🐑🐒🐔🐶🐷

start transaction不代表立即生成ReadView,而是在事务中第一次快照读的时候生成ReadView,具体参考MySQL可重复读隔离级别下开启事务的一个注意事项

想要开启事务时就生成ReadView,请使用

start transaction with consistent snapshot;
2.4读视图生成原则

ReadView定义了一个可见性算法,当事务进行快照读时,依据该算法判断事务能够读取哪个快照。

源码的可见性判断逻辑如下:(下载源码可访问:官网,操作系统选择Source Code)

/** Check whether the changes by id are visible.
	@param[in]	id	transaction id to check against the view
	@param[in]	name	table name
	@return whether the view sees the modifications of id. */
//判断某个版本的数据是否对当前事务可见
bool changes_visible(
    trx_id_t		id,
    const table_name_t&	name) const
    MY_ATTRIBUTE((warn_unused_result)) {
    ut_ad(id > 0);
    //快照的id小于活跃事务id集合中的最小事务id 或者 快照的id等于创建这个视图的事务id
    if (id < m_up_limit_id || id == m_creator_trx_id) {
        return(true);
    }
    //检查快照id是否合法,如果快照的id大于等于下一要分配的事务id,则需要抛出警告信息(会出现这种情况吗?)
    check_trx_id_sanity(id, name);
    //快照的id大于等于下一要分配的事务id
    if (id >= m_low_limit_id) {
        return(false);
    } 
    //当前不存在活跃的事务
    else if (m_ids.empty()) {
        return(true);
    }
    const ids_t::value_type*	p = m_ids.data();
    //通过二分查找判断快照id是否在活跃事务集合中,存在则快照不可见,不存在则快照可见
    return(!std::binary_search(p, p + m_ids.size(), id));
}
  1. 快照id等于当前事务id时(trx_id=creator_trx_id),说明该版本是当前事务修改的,该快照对当前事务可见
  2. 快照id小于活跃事务的最小id(trx_id<up_limit_id),说明该版本对应的事务已经提交了,该快照对当前事务可见
  3. 快照id大于等于下一个要分配的事务id(trx_id>=low_limit_id),则该快照对当前事务不可见
  4. 快照id小于下一个要分配的事务id并且活跃事务id数量为0(trx_id<low_limit_id && trx_ids.size==0),则该快照对当前事务可见
  5. 当以上条件都不满足,则在活跃事务id集合里查找快照id,如果不存在,则可见,否则不可见
3.rc和rr隔离级别下mvcc的不同

mvcc主要用来解决rc(读已提交)隔离级别下的脏读和rr(可重复读)隔离级别的不可重复读问题,所以mvcc只在rc和rr隔离级别下生效。

区别在于,rc级别下,每一次快照读都会生成一个最新的ReadView;RR级别下,只有事务中的第一次快照读会生成ReadView,之后的快照读会使用第一次生成的ReadView

事务能否查询到其他事物修改的数据,取决于ReadView,而rc和rr两个级别的ReadView生成方式不同,就导致了事务可见性不同。(rc级别下一个事务可以查询到其他事物在此期间修改并提交的数据,因为它的每次查询都会生成新的ReadView;rr级别下事务无法查询到其他事物在此期间修改并提交的数据,因为他的ReadView只在第一次快照读生成)文章来源地址https://www.toymoban.com/news/detail-858030.html

到了这里,关于MySQL多版本并发控制mvcc原理浅析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【MySQL】事务之MVCC(多版本并发控制)

    读-读 :不存在任何问题,也不需要并发控制 读-写 :有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读,幻读,不可重复读 写-写 :有线程安全问题,可能会存在更新丢失问题,比如第一类更新丢失,第二类更新丢失 多版本并发控制 ( MVCC )是一种用来解决 读

    2024年02月14日
    浏览(33)
  • 【MySQL高级篇笔记-多版本并发控制MVCC(下) 】

    此笔记为尚硅谷MySQL高级篇部分内容 目录 一、什么是MVCC 二、快照读与当前读 1、快照读  2、当前读 三、复习 1、再谈隔离级别 2、隐藏字段、Undo Log版本链 四、MVCC实现原理之ReadView  1、什么是ReadView  2、设计思路 3、ReadView的规则 4、MVCC整体操作流程 五、举例说明 1、READ

    2024年02月08日
    浏览(50)
  • MYSQL的多版本并发控制MVCC(Multi-Version Concurrency Control)

    MVCC 是一种用于数据库管理系统的并发控制技术,允许多个事务同时访问数据库,而不会导致读写冲突。也就是说在读写的时候,线程不用去争抢读写锁。因为加锁的过程比较耗性能。 当然很多时候还是必须的,不能避免,比如说,去ATM机取钱的时候,同时又在手机APP上进行

    2024年02月07日
    浏览(29)
  • Mysql--技术文档--MVCC(Multi-Version Concurrency Control | 多版本并发控制)

            MVCC(Multi-Version Concurrency Control)是一种并发控制机制,用于解决并发访问数据库时的数据一致性和隔离性问题。MVCC允许多个事务同时读取数据库的同一数据,而不会相互干扰或导致冲突。         在传统的并发控制机制中,如锁定机制,事务会对读取和写入

    2024年02月11日
    浏览(29)
  • 深入解析MVCC:多版本并发控制的数据库之道

    目录 引言 一、什么是MVCC? 二、MVCC的实现原理 2.1版本号 2.1.1版本号的作用: 2.1.2版本号的组成: 2.1.3.示例 2.2事务id 2.2.1事务ID的作用: 2.2.2事务ID的生成: 2.2.3示例: 2.3 快照(Snapshot) 2.3.1快照的作用: 2.3.2快照的实现方式: 2.3.3示例: 2.4版本链(Version Chain) 2.4.1版本链

    2024年01月24日
    浏览(47)
  • MVCC------Mysql并发事务控制的工具

    MVCC 是 Multi-Version Concurrency Control(多版本并发控制)的缩写,是数据库系统中常用的一种并发控制方法。在MVCC 中,数据库系统可以同时维护多个版本的数据,每个事务在读取数据时会看到一个一致性的快照,从而实现并发访问而不会出现数据不一致的情况。这种机制能够提

    2024年03月14日
    浏览(76)
  • 【Mysql】MVCC版本机制的多并发

    🌇个人主页:平凡的小苏 📚学习格言:命运给你一个低的起点,是想看你精彩的翻盘,而不是让你自甘堕落,脚下的路虽然难走,但我还能走,比起向阳而生,我更想尝试逆风翻盘 。 🛸 Mysql专栏 : Mysql内功修炼基地 家人们更新不易,你们的👍点赞👍和⭐关注⭐真的对我

    2024年02月11日
    浏览(27)
  • 多版本并发控制MVCC

    MVCC (Multiversion Concurrency Control),多版本并发控制。顾名思义,MVCC 是通过数据行的多个版本管理来实现数据库的 并发控制 。这项技术使得在InnoDB的事务隔离级别下执行一致性读操作有了保证。换言之,就是为了查询一些正在被另一个事务更新的行,并且可以看到它们被更

    2024年02月08日
    浏览(27)
  • MVCC并发版本控制之重点ReadView

    本文大部分来自 《MySQL是怎样运行的》,这里只是简单总结,用于各位回忆和复习。 对于使用 InnoDB 存储引擎的表来说,它的聚簇索引记录中都包含两个必要的隐藏列(不知道的快去看《MySQL是怎样运行的》) trx_id :每次一个事务对某条聚簇索引记录进行改动时,都会把该事

    2024年02月09日
    浏览(26)
  • MVCC:多版本并发控制案例分析(二)

    (笔记总结自b站马士兵教育课程) 本文主要分析readview的案例。 readview:表示事务进行快照读操作的时候产生的读视图,在该事务进行快照读的那一刻会生成一个系统当前的快照,但是此时的快照不是数据的快照,而是事务相关信息的快照。 trx_list readview生成时刻当前系统活

    2024年02月08日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包