美文网首页
数据库的隔离级别和 MVCC

数据库的隔离级别和 MVCC

作者: jijs | 来源:发表于2020-03-23 00:28 被阅读0次

    MVCC (Multi-Version Concurrency Control),多版本并发控制。数据库实现并发访问请求,就是基于 MVCC 实现的。

    首先了解下数据库事物的隔离级别。

    隔离级别

    • Read Uncommiteed 读未提交
      读取未提交的数据,即其他事物已经修改但还未提交的数据,这是最低的隔离级别。
    • Read committed 读已提交
      读取已提交的数据。在一个事物中,对同一条数据,可能会出现读取不一致现象。
    • Repeatable Read 可重复读
      可重复读取,在一个事物中,对同一条数据,确保多次读取的结果一样。(Mysql 默认隔离级别)
    • Serializable 序列化
      串行执行,数据库中的事物都是串行执行,不能并行执行,效率最差。

    隔离级别主要是为了实现读操作不需要加锁, 从而提高数据库的性能。

    不同隔离级别出现的问题

    隔离级别 脏读 幻读 不可重复读
    读未提交
    读已提交
    可重复度
    序列化

    Read Uncommiteed 和 Serializable 不需要使用多版本控制技术就可实现。
    Read Uncommiteed :直接修改原始数据即可,其他事物查看数据的时候直接可以查看到,无须其他操作即可实现。
    Serializable: 所有的事物都是串行执行的,只需要一个独占锁即可实现。

    其中Read committed 和 Repeatable Read 两种事物隔离使用到 MVCC 进行实现的。

    MVCC 实现原理

    MVCC (Multi-Version Concurrency Control),多版本并发控制。MVCC 对每行数据维护多个版本。可以实现读操作不需要加锁,即可实现在同一个事物中多次读取一条数据,结果都是一致的。

    MySql InnoDB存储引擎为例,InnoDB 在表中增加了两个隐藏字段。每个事物都是一个事物ID,其中一个列存储了修改时的事物ID,另一个列存储的是删除这条数据的事物ID。每开启一个事物都会生成一个自增的事物ID,当查询一条数据时,都会用当前的事物ID,和隐藏列中的事物ID进行对比,然后根据不同的事物隔离级别来决定是否返回该行数据。

    下面对 Select、Delete、 Insert、 Update 四种操作了解 MVCC 的实现原理

    创建一个表,表中有两个字段 id、name。MVCC 中增加两个隐藏列 update_version、delete_version。
    update_version: 存储修改时,当前事物的ID
    delete_version: 存储删除时,当前事物的ID。

    Insert

    假设当前事物的ID=1

    插入一条数据时,update_version 存储当前事物的ID,。

    id name update_version delete_version
    1 张三 1

    Update

    当前事物ID=2

    修改一条数据时,会新把原来的行复制一份,并把之前的那条数据delete_version 列设置成当前的事物ID 2,标记当前数据为删除,新插入的数据 update_version 设置成当前事物ID 2。

    id name update_version delete_version
    1 张三 1 2
    1 张小三 2

    Delete

    当前事物ID=4

    删除数据时,直接把 delete_version 这个字段设置为当前的事物ID 4.

    id name update_version delete_version
    1 张三 1 2
    1 张小三 2 4

    Select

    查询必须满足以下两种条件才能返回:

    • 行的 update_version 版本号小于等于当前事物ID
    • 行的 delete_version 版本无值或大于当前事物ID
    Select 示例一

    比如事物ID=3, 查询 id=1 的数据

    id name update_version delete_version
    1 张三 1 2
    1 张小三 2

    查询条件为:id=1 and update_version<=3 and delete_version>3
    查询出来的数据应该是 “张小三” 这条数据。

    Select 示例二

    假设,事物ID 3 执行的查询时间比较长,这时事物4开始删除这条数据,并提交,然后事物ID=3 的查询才开始执行,应该是能查询到 id=1 的数据。

    事物ID=4 删除后的数据。

    id name update_version delete_version
    1 张三 1 2
    1 张小三 2 4

    查询条件为:id=1 and update_version<=3 and delete_version>3
    查询结果应该为 “张三” 这条数据。

    相关文章

      网友评论

          本文标题:数据库的隔离级别和 MVCC

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