MYSQL中MVCC是什么?

基本概念

  MVCC:全称Multi-Version Concurrency Control,多版本并发控制。指维护一个数据的多个版本,使得读写操作没有冲突,快照读为MySQL实现

MVCC提供了- -个非阻塞读功能。MVCC的具体实现,还需要依赖于数据库记录中的三个隐式字段、undo log日志、readView。

  当前读:读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。对于我们日常的操作,如:

select .. lock in share mode(共享锁), select ... for update、update、 insert、 delete(排他锁)都是一 -种 当前读。

  快照读:简单的select (不加锁)就是快照读,快照读,读取的是记录数据的可见版本,有可能是历史数据,不加锁,是非阻塞读。

      Read Committed:每次select, 都生成一一个快照读。
      Repeatable Read:开启事务后第一 个select语句才是快照读的地方。
      Serializable: 快照读会退化为当前读。

 

实现原理

  一、数据库在每张表内都维护了三个隐藏字段

  1,DB_TRX_ID:最近修改事务,记录插入这条记录或最后一次修改该记录的事务id。

  2,DB_ROLL_PTR:回滚指针,指向这条记录的上一个版本,用于配合undo log,指向上一个版本。

  3,DB_ROW_ID:隐藏主键,如果表结构没有指定主键,将会自动生成该字段。

 

    二、undo log:回滚日志,在insert,update,delete的时候产生的便于数据回滚的日志。当insert的时候,产生的undo log只在回滚时需要,在事务被提交后,可立即被删除。而update,delete的时候,产生的undo log日志不仅在回滚时需要,在快照读时也需要,不会立即被删除。不同事务或相同事务对同一条记录进行修改,会导致该记录的undo log生成一条版本链表,链表的头部是最新的旧记录,链表尾部是最早的旧记录。

 

   问题是:在查询的时候,返回的是undo log中哪个版本呢? 这个不是由版本链控制的,具体要返回哪个版本又涉及到MVCC实现原理的第三个组件,readView

 

  三、readView : ReadView读视图是快照都SQL执行时MVCC提取数据的依据,记录并维护系统当前活跃的事务(未提交的)id,ReadView中包含四个核心字段

     1、m_ids:当前活跃的事务id集合

     2、min_trx_id:最小活跃事务id

     3、max_trx_id:预分配事务id,当前最大事务id+1,因为事务id是自增的

     4、creator_trx_id:ReadView创建者的事务id

   版本链数据访问规则:如果事务id为trx_id来进行查询,要遵循如下规则。

     1、 trx_id == creator_trx_id  , 说明数据是当前这个事务更改的,则可以访问该版本

     2、trx_id < min_trx_id , 说明数据已经提交了,可以访问该版本

     3、trx_id > max_trx_id ,说明事务是在readView生成后才开启的,不可以访问该版本

     4、min_trx_id <= trx_id <= max_trx_id ,而且trx_id 不在m_ids中,说明数据已经提交,可以访问该版本

   另外要注意的是,不同的隔离级别,生成ReadView的时机不同,read committed是在事务中每一次执行快照读时生成readview,repeated read仅在事务中第一次执行快照读时生成readView,后续复用该readView。

   先以RC为例,如下图

 

 

   在RR中,用的都是同一个ReadView,所以查询到的数据也是一样的,这也是为什么RR解决了不可重复读的原因。

 

 

  

 

 

 

 

 

 

 

 

  

posted @   wwwwwwwty  阅读(124)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示