MySQL的MVCC多版本控制原理

作者: 迦叶_金色的人生_荣耀而又辉煌 | 来源:发表于2021-01-15 07:16 被阅读0次

    上一篇 <<<MySQL的并发文件及事务隔离级别
    下一篇 >>>


    MVCC(Multi-Version Concurrency Control)即多版本并发控制。就是同一份数据临时保留多版本的一种方式,进而实现并发控制
    传统锁的方式保证实现多版本控制,需要通过锁的方式实现,效率非常低。
    MVCC 使用了一种不同的手段, 无锁并发控制每个连接到数据库的读者,在某个瞬间看到的是数据库的一个快照,写操作造成的变化在写操作完成之前(或者数据库事务提交之前)对于其他的读者来说是不可见的。

    Innodb中的隐藏列

    列名 长度(字节) 作用
    DB_ROW_ID 6 用于聚簇索引隐式产生的索引行(隐藏单调自增id)
    DB_TRX_ID 6 插入或更新行的最后一个事务的事务标识符,每处理一个事务,值+1。(删除视为更新,将其标记为已删除)
    DB_ROLL_PTR 7 指向当前记录项的rollback segment的undo log记录,找之前版本的数据就是通过这个指针
    DELETE_BIT 标识该记录是否被删除,这里的不是真正的删除数据,而是标志出来的删除。真正意义的删除是在commit的时候

    各种语句的执行过程

    1.insert

    InnoDB为每个新增行记录当前系统版本号作为DB_TRX_ID
    比如插入一条记录, 事务id 假设是1,那么记录如下:(创建版本号就是事务版本号)

    id name DB_TRX_ID DELETE_BIT
    1 test 1

    2.update

    InnoDB复制了一行。先标记旧的记录为已删除(DELETE_BIT),并且版本号更新为当前事务版本号,然后插入一行新的记录的方式。
    比如,针对上面的记录,当前事务id为2,更新name字段:

    id name DB_TRX_ID DELETE_BIT
    1 test 2 1
    1 test2 2

    3.delete

    设当前版本号为3,InnoDB为每个删除行的记录当前系统版本号作为行的删除ID,并且设置DELETE_BIT,比如:
    delete from table a where id = 1;

    id name DB_TRX_ID DELETE_BIT
    1 test2 3 1

    4.select

    Innodb检查每行数据,确保他们符合两个标准:
    1、InnoDB只查找记录行中版本 <= 当前事务版本的数据行,这确保当前事务读取的行都是事务之前已经存在的,或者是由当前事务创建或修改的行
    2、行的删除操作的版本一定是未定义的或者>当前事务的版本号,确定了当前事务开始之前,行没有被删除

    通过版本号来减少锁的争用,符合了以上两点则返回查询结果。

    说明:

    • insert操作时“创建时间”=DB_ROW_ID,这时,“删除时间 ”是未定义的;
    • update时,复制新增行的“创建时间”=DB_ROW_ID,删除时间未定义,旧数据行“创建时间”不变,删除时间=当前事务的DB_ROW_ID;
    • delete操作,相应数据行的“创建时间”不变,删除时间=该事务的DB_ROW_ID;
    • select操作对两者都不修改,只读相应的数据
    • 只有read-committed和repeatable-read两种事务隔离级别才能使用MVCC;read-uncommited由于是读到未提交的,所以不存在版本的问题;而serializable则会对所有读取的行加锁。

    相关文章

      网友评论

        本文标题:MySQL的MVCC多版本控制原理

        本文链接:https://www.haomeiwen.com/subject/xqdeoktx.html