InnoDB MVCC——隐藏字段、Undolog、ReadView
和MVCC相关的三个东西#
- 隐藏字段:InnoDB表中的每个行前都有的三个隐藏字段,用于实现MVCC机制
- undolog:用于记录数据的历史版本,每一个数据的历史版本在undolog中构成一个历史版本链
- readview*:每个事务都有一个,用于确定它能读到链中的哪些历史版本
隐藏字段#
通过这一小节,你将知道InnoDB为了实现MVCC机制,在数据行上做了什么,它添加了三个隐藏字段
DB_TRX_ID
:最后对该行进行插入或修改的事务IDDB_ROLL_PTR
:回滚指针,指向该数据的上一个版本,用于维护历史版本链DB_ROW_ID
:隐藏主键,只有当表没设置主键时才有,它和MVCC也没啥关系
undolog#
通过这一小节,你将知道undolog是如何保存一行数据的历史版本的,以及DB_ROLL_PTR
如何构建版本链,为了简单,我们省略DB_ROW_ID
列
假设现在有这样一个表,它只有一个列A
ReadView#
通过这一小节,你将知道当一个事务进行快照读时,如何确定自己应该读取历史版本链中的哪个数据。
ReadView
快照能够在事务的查询中帮助解决这个问题,快照中包含以下关键内容:
m_ids
:当前系统中活动(已经开始,尚未提交回滚)事务id列表,有序max_trx_id
:下一个尚未分配的事务idmin_trx_id
:m_ids
列表中最小的一个id
然后,假如我们就拿可重复读的标准来考虑,并假设ReadView
生成的时间就是当前查询事务开启的时间:
- 如果待查询数据的
DB_TRX_ID < min_trx_id
,因为该数据在ReadView快照生成时已经是提交过的了,直接使用就行 - 如果待查询数据的
DB_TRX_ID = 当前事务id
,一个事务肯定能读到自己做的修改,直接使用就行 - 如果待查询数据的
DB_TRX_ID >= max_trx_id
,那么该数据是ReadView生成时尚未提交过的,需要沿DB_ROLL_PTR
访问undolog的历史版本链,找到该读的数据 - 还有种可能是
DB_TRX_ID
属于[min_trx_id, max_trx_id)
这个区间- 如果
DB_TRX_ID
在列表中,说明它在ReadView创建时还未提交,不能使用,需要访问历史版本链 - 否则,它在ReadView创建时已经提交,直接访问该数据
- 如果
如果给事务一个
ReadView
,让事务按上面的规则进行读取,那么事务就能读取到ReadView
生成时已经提交的最新版本数据
众所周知,MVCC机制支持在Read Committed
和Repeatable Read
级别下工作,那么我们只需要控制生成ReadView
的时机,就可以模拟出这两种隔离级别应有的读取行为。
Read Committed
级别时,每次遇到读取命令生成一个ReadView
Repeatable Read
级别时,第一次遇到读取命令生成一个ReadView
,并且该ReadView
在整个事务中共享
作者:Yudoge
出处:https://www.cnblogs.com/lilpig/p/16731925.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
欢迎按协议规定转载,方便的话,发个站内信给我嗷~
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· winform 绘制太阳,地球,月球 运作规律
· 上周热点回顾(3.3-3.9)