• MVCC实现机制


    1. MVCC简介

    1.1 什么是MVCC

      MVCC(Multiversion concurrency control )是一种多版本并发控制机制。

    1.2 MVCC是为了解决什么问题?

      并发访问(读或写)数据库时,对正在事务内处理的数据做多版本的管理。以达到用来避免写操作的堵塞,从而引发读操作的并发问题。
      大家都应该知道,锁机制可以控制并发操作,但是其系统开销较大,而MVCC可以在大多数情况下代替行级锁,使用MVCC,能降低其系统开销。

    1.3 MVCC实现

      MVCC是通过保存数据在某个时间点的快照来实现的。不同存储引擎的MVCC实现是不同的,典型的有乐观并发控制和悲观并发控制。当我们创建表完成后,mysql会自动为每个表添加 数据版本号(最后更新数据的事务id)db_trx_id 删除版本号 db_roll_pt (数据删除的事务id) 事务id由mysql数据库自动生成,且递增。

    2.MVCC 具体实现分析

    2.1 MVCC逻辑流程-插入(insert)

      如下图,同一事务中(假设事务id=1)插入两条记录,记录的数据版本号为事务id=1,删除版本号为null

    start transaction;(事务id为1)
    INSERT INTO user (name,sex) VALUES ('张三','');
    INSERT INTO user (name,sex) VALUES ('李四','');
    commit;

      对应在数据中的表如下(后面两列是隐藏列,我们通过查询语句并看不到)

      

    2.2 MVCC逻辑流程-查询(select)

      查询时需要同时满足以下两个条件
      1、查找数据版本号,早于(小于等于)当前事务id的数据行。 这样可以确保事务读取的数据是事务之前已经存在的。或者是当前事务插入或修改的。
      2、查找删除版本号为null 或者大于当前事务版本号的记录。 这样确保取出来的数据在当前事务开启之前没有被删除。

      如下图,假如有一个事务中执行查询(假设事务id=2)

    start transaction;(事务id为2)
    select * from user where sex = '';  --(1select * from user where sex = '';  --(2commit;

      假设在执行这个事务ID为2的过程中,刚执行到(1),这时有另一个事务(假设事务id=3)往这个表里插入了一条数据; 

    start transaction;(事务id为3)
    INSERT INTO user (name,sex) VALUES ('王五','');
    commit;

      此时表中的数据如下:

      

      然后接着执行事务 id=2 中的(2),由于id=3的数据的创建时间(事务ID为3),执行当前事务的ID为2,而InnoDB只会查找事务ID小于等于当前事务ID的数据行,所以 id=3 的数据行并不会在执行事务 id=2 中的 (2) 被检索出来。在事务 id=2 中的两条select 语句检索出来的数据都只会下表:

      

    2.3 MVCC逻辑流程-删除(delete)

      如下图,假如有一个事务中执行查询(假设事务id=4)

    start transaction;(事务id为4)
    select * from user where sex = '';  --(1)
    select * from user where sex = '';  --(2)
    commit;

      假设事务 id=4 刚执行到(1),此时有另外一个事务 id=5 执行了删除语句,会更新数据的删除版本号为当前事务id = 5 

    start transaction;(事务id为5)
    DELETE FROM user WHERE id = 1;
    commit;

      此时数据库表中数据如下:

      

      接着执行事务 id=4的事务(2),根据SELECT 检索条件可以知道,它会检索创建时间(创建事务的ID)小于当前事务ID的行和删除时间(删除事务的ID)大于当前事务的行,表中id=1的行由于删除时间(删除事务的ID)大于当前事务的ID,所以事务 id=2 的(2)在执行的时候也会把表中 id=1 的数据检索出来,所以事务4中的两条select 语句检索出来的数据都如下:

      

    2.4 MVCC逻辑流程-修改(update)

      可以理解为,当一个事务中 修改一条记录时, 是先复制该数据,新数据数据版本号为当前事务id,删除版本号为 null 。然后更新 原来数据的删除版本号为 当前事务id。如下:

      假如一个事务 id=6 执行了一条update语句

    start transaction;(事务id为6)
    UPDATE user SET name='李四1' WHERE id = 2
    commit;

      执行结果如下:

      

     

  • 相关阅读:
    DS博客作业05--查找
    DS博客作业04--图
    DS博客作业03--树
    栈和队列
    第六次作业
    第五次作业
    第四次作业
    第三次作业
    java任务
    第三周-自主学习任务-面向对象基础与类的识别
  • 原文地址:https://www.cnblogs.com/luchangyou/p/11321607.html
Copyright © 2020-2023  润新知