MYSQL-->InnoDB引擎底层原理( 四 )


MVCC(多版本并发控制)(高频面试题)MVCC的几个基本概念当前读我们读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁,
对于我们日常的操作,如:select...lock in share mode(共享锁),select...for update,update,insert,delete(排他锁)
都是一种当前读 。
案例:
在RR的隔离级别下

  1. 事务A进行查询操作,事务B进行更新操作并提交事务
  2. 事务A使用当前读select...此时读取的是事务B更新之前的数据(原因是隔离级别)
  3. 事务A使用select...lock in share mode(当前读)此时读取的是事务B更新之后的数据 。
快照读简单的select(不加锁)就是快照读,读取的是记录数据的可见版本,可能是历史数据,不加锁是非阻塞读 。
  1. Read Committed隔离级别:每次select都生成一个快照读
  2. Repeatable Read隔离级别:开启事务后第一个select语句才是快照读的地方(后续查的就是这个快照数据)
  3. Serializable隔离级别:快照读会退化为当前读
MVCC介绍全称Multi-Version Concurrency Control 多版本并发控制 。
指的是维护一个数据的多个版本,使得读写操作没有冲突 。
快照读为MYSQL实现MVCC提供了一个非阻塞读功能,MVCC的具体实现,还需要依赖,数据库的三个隐藏字段、
undo log日志、readView
MVCC-实现原理记录中的隐藏字段当我们创建了表除了自己本身创建的字段,innoDB引擎会自动给我们创建三个字段
分别是:
  1. DB_TRX_ID
  2. DB_ROLL_PTR
  3. DB_ROW_ID
隐藏字段含义DB_TRX_ID最近修改事务ID,记录插入这条记录或者最后一次修改该记录的ID(事务id)DB_ROLL_PTR回滚指针,指向这条记录的上一个版本,用于配合undo log指向上一个版本DB_ROW_ID隐藏主键,如果表结构没有指定主键,就会生成该隐藏字段
可以查看表空间文件内容来查看隐藏字段信息
事务id是自增的!
在MYSQL中提供了一个命令来查看表空间文件的记录信息
ibd2sdi xxx.ibdundo log版本链回滚日志,在insert、update、delete的时候产生的便于数据回滚的日志
当insert的时候,产生的undo log日志只在回滚时需要,在事务提交后,可被立即删除 。
当update、delete的时候,产生的undo log日志不只是回滚时需要,在快照读时也需要,不会被立即删除 。
Undo log版本链
不同事务或相同事务对同一条记录进行修改,会导致该记录的undo log生成一个记录的版本链表,链表的头部是最新的旧记录,链表的尾部是最早的旧记录 。
MYSQL-->InnoDB引擎底层原理

文章插图
执行顺序:
从上到下代表执行顺序 。在同一行代表同一时间执行 。
ReadView(读视图)ReadView(读视图)是快照读SQL执行时MVCC提取数据的依据,记录并维护系统当前活跃的事务(未提交的)id
ReadView中包含了四个核心字段
字段含义m_ids当前活跃的事务id集合min_trx_id最小活跃的事务IDmax_trx_id预分配事务ID,当前最大事务ID+1(因为事务ID是自增的)creator_trx_idReadView创建者的事务ID版本链数据访问规则
trx_id 代表的是当前事务的id
用这个id和ReadView的四个核心字段进行比对
  1. trx_id == creator_trx_id 可以访问该版本这个条件成立代表数据是当前这个事务更改的
  2. trx_id < min_trx_id           可以访问该版本          这个条件成立,说明数据已提交

    经验总结扩展阅读