MVCC底层机制

MVCC底层机制

​ MVCC 是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问(乐观锁)。

​ MVCC具体的操作方式是:

  1. innodb引擎会在每一行加上隐藏的两列:事务ID和回滚指针。

    注:一个session对应的事务ID需要通过update、delete语句的执行来生成的
    MVCC底层机制

  2. 对于account表,假设原有字段数据如下:

    MVCC底层机制

    当执行事务id为300的事务时,执行更新语句,此时会向表中插入一条 id=1,name='lilei300’的数据,而之前的这条name=lilei的数据将会被放到undo日志当中,同时新数据中的回滚指针会指向旧数据,如

MVCC底层机制

  1. 此时在一个新的session里执行select操作。

    • 第一次select操作:**mysql会在第一次执行select语句的时候会生成一个一致性的视图read-view,由执行查询语句时的所有未提交事务id数组和已创建最大事务id组成,如图1中的100,200300(最大事务id)。当然每个session中的read-view不一定一样,会实时更新。**而最后查询的结果则是通过以下规则决定:

      • 对于可重复读隔离级别:

        1. 每次执行select时会沿用第一次select查询语句生成的read-view
        2. 得到read-view之后会使用最大事务ID未提交事务ID中的最小ID分成三个部分:

      MVCC底层机制

      1. 此时需要从版本链顶端数据的事务ID进行比对,得到其落在哪个区间中:

        • 绿色区间(trx_id < min_id):事务已提交,数据可见;

        • 红色区间(trx_id >max_id):版本由未来启动的事务生成,不可见;

        • 黄色区间(min_id <= trx_id <= max_id):

          • 如果trx_id在未提交事务id数组中,则表示事务还未提交,不可见;

            如果trx_id在未提交事务id数组中,但是当前select语句是在自己的事务中,那么是可见的;

          • 如果trx_id不在未提交事务id数组中,则事务已经提交,是可见的。

      • 对于已提交读的隔离级别:每次执行select时会重新生成read-view。
    • 第二次select操作:此时已经执行完图中阴影部分的sql语句:

    MVCC底层机制

    此时数据版本链中事务ID=300的数据已经不是最新的版本链数据了,而是

MVCC底层机制

根据步骤,从版本链顶端开始查找,此时min_id=100,trx_id = 100,属于黄色区间,且在未提交事务id数组中,故不可见;直到tri_id=300时,此时tri_id不在未提交事务id数组中,结果可见。

  • 第三次select操作同第二次。

注:一个session中所有select都会沿用同一个read-view,即第一次select时生成的read-view,尽管他们可能查询的数据不在一张表。