MVCC(多版本并发控制)(高频面试题)MVCC的几个基本概念当前读我们读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁,
对于我们日常的操作,如:select...lock in share mode(共享锁),select...for update,update,insert,delete(排他锁)
都是一种当前读 。
案例:
在RR的隔离级别下
- 事务A进行查询操作,事务B进行更新操作并提交事务
- 事务A使用当前读select...此时读取的是事务B更新之前的数据(原因是隔离级别)
- 事务A使用select...lock in share mode(当前读)此时读取的是事务B更新之后的数据 。
- Read Committed隔离级别:每次select都生成一个快照读
- Repeatable Read隔离级别:开启事务后第一个select语句才是快照读的地方(后续查的就是这个快照数据)
- Serializable隔离级别:快照读会退化为当前读
指的是维护一个数据的多个版本,使得读写操作没有冲突 。
快照读为MYSQL实现MVCC提供了一个非阻塞读功能,MVCC的具体实现,还需要依赖,数据库的三个隐藏字段、
undo log日志、readView
MVCC-实现原理记录中的隐藏字段当我们创建了表除了自己本身创建的字段,innoDB引擎会自动给我们创建三个字段
分别是:
- DB_TRX_ID
- DB_ROLL_PTR
- DB_ROW_ID
可以查看表空间文件内容来查看隐藏字段信息在MYSQL中提供了一个命令来查看表空间文件的记录信息
事务id是自增的!
ibd2sdi xxx.ibdundo log版本链回滚日志,在insert、update、delete的时候产生的便于数据回滚的日志
当insert的时候,产生的undo log日志只在回滚时需要,在事务提交后,可被立即删除 。
当update、delete的时候,产生的undo log日志不只是回滚时需要,在快照读时也需要,不会被立即删除 。
Undo log版本链
不同事务或相同事务对同一条记录进行修改,会导致该记录的undo log生成一个记录的版本链表,链表的头部是最新的旧记录,链表的尾部是最早的旧记录 。
文章插图
执行顺序:
从上到下代表执行顺序 。在同一行代表同一时间执行 。
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的四个核心字段进行比对
- trx_id == creator_trx_id 可以访问该版本这个条件成立代表数据是当前这个事务更改的
- trx_id < min_trx_id 可以访问该版本 这个条件成立,说明数据已提交
经验总结扩展阅读
- StampedLock:一个并发编程中非常重要的票据锁
- Longchamp龙骧饺子包
- <三>从编译器角度理解C++代码编译和链接原理
- <一>关于进程虚拟地址空间区域内存划分和布局
- GitLab私有化部署 - CI/CD - 持续集成/交付/部署 - 源代码托管 & 自动化部署
- 🔥支持 Java 19 的轻量级应用开发框架,Solon v1.10.4 发布
- Bert不完全手册9. 长文本建模 BigBird & Longformer & Reformer & Performer
- InnoDB关于事务、锁、MVCC专题
- XXI Open Cup, Grand Prix of Belarus 2020-2021 Winter Petrozavodsk Camp, Belarusian SU Contest 题解
- Petrozavodsk Winter Training Camp 2016: Moscow SU Trinity Contest