Mysql——MVCC学习

概念:

MVCC,即多版本并发控制,是InnoDB实现高并发事务的核心机制。它的核心思想是:不通过加锁阻塞读写,而是为每一行数据维护多个历史版本,让读写事务可以无冲突地并发进行。这是InnoDB在"可重复读"和"读已提交"隔离级别下实现的关键。

解决问题

  • 解决脏读:因为事务只能看到已提交事务产生的版本。

  • 解决不可重复读(在"可重复读"级别下):因为在一个事务内第一次快照读就创建 了ReadView,之后的所有快照读都复用这个ReadView,所以看到的数据 snapshot 是一致的。

当前数据行的关键数据结构

  • DB_TRX_ID(6字节):事务ID。记录最后一次插入或更新这行数据的事务ID。

  • DB_ROLL_PTR(7字节):回滚指针。指向这行数据上一个版本的undo log记录地址,是构成版本链的关键。

  • DB_ROW_ID(6字节):行ID。如果表没有主键,InnoDB会用它生成聚簇索引。

Undo log

  • 每次修改数据时(INSERT/UPDATE/DELETE),都会在undo log中记录一条逻辑相反的日志,用于回滚和构建历史版本。

  • UPDATE操作会产生一个"更新日志",其中包含了被修改前的数据镜像,并通过DB_ROLL_PTR串联起来,形成一条单向链表,即"版本链"。链头是最新数据,链尾是最老数据。

链表节点存储数据

python 复制代码
class UndoLogNode():
	def __init__(tri_id, preNode, data):
		self.data = data # 该行数据被修改前的完整内容
		self.tri_id = tri_id # 该记录产生时对应的事务ID
		self.pre_node = preNode or None # 指向更早一个版本的Undo Log记录的指针

ReadView

在事务执行第一个快照读时,根据瞬间截取的当时数据库系统的一个全局状态快照创建,它定义了当前事务能看到哪些版本的数据。

数据结构

  • m_ids:生成ReadView时,系统中活跃的(未提交的)读写事务ID列表。这个列表是从全局事务表中实时获取的。

  • min_trx_id:m_ids中的最小值。由 m_ids列表直接计算得出

  • max_trx_id:生成ReadView时,系统应该分配给下一个事务的ID。通常是当前的全局事务 ID (trx_sys->max_trx_id) + 1。

  • creator_trx_id:创建该ReadView的事务自己的ID。

工作流程

查询时

  1. 定位数据行:首先找到数据页中最新的那条记录。

  2. 遍历版本链:顺着该记录的DB_ROLL_PTR指针,在undo log中遍历它的历史版本链表。

  3. 可见性判断(核心规则):

    • 拿每个版本中的DB_TRX_ID(即产生该版本的事务ID),与当前ReadView进行比对:

    • 如果 DB_TRX_ID< min_trx_id,说明这个版本是在当前事务开始前就已提交的,可见。

    • 如果 DB_TRX_ID>= max_trx_id,说明这个版本是在当前事务开始后才开启的,不可见,继续找更老的版本。

    • 如果 min_trx_id<= DB_TRX_ID< max_trx_id,则需要判断DB_TRX_ID是否在m_ids(活跃事务列表)中:

      • 如果在,说明生成该版本的事务在ReadView创建时还未提交,不可见。

      • 如果不在,说明生成该版本的事务在ReadView创建时已提交,可见。

  4. 返回数据:找到第一个对当前事务可见的版本,将其数据返回。如果遍历完链都没找到,则说明此行对当前事务不可见。

MVCC工作流程

  1. 准备工作(由 InnoDB 自动维护)
    • Undo Log 记录历史
    • 构建版本链:表中的当前数据行,其隐藏字段 DB_ROLL_PTR指向了最近一次修改它所产生的 Undo Log 记录。
  2. 创建裁判规则ReadView
  3. ReadView执行其工作流程
相关推荐
两点王爷7 小时前
PostgreSQL 常用 SQL 语句与 GIS 相关函数详解
数据库·后端
两点王爷7 小时前
PostgreSQL 好用又独特的特性与空间函数
数据库
梦帮科技7 小时前
AI 音乐产品的发布工程:验证门、数据发布、回滚与生产运维纪律
数据结构·数据库·架构·node.js·音视频·动态规划·推荐算法
一只路人甲8 小时前
使用AI快速学习
学习
传奇开心果编程8 小时前
【Rust入门练中学】第2课:变量、可变性与常量
开发语言·学习·rust
TDengine (老段)9 小时前
TDengine 常见问题 TOP3
大数据·数据库·物联网·时序数据库·tdengine·涛思数据
边境悍匪10 小时前
蜗牛学苑 Java 智能体学习 Day42|项目周开发技术汇总 1 思维导图复盘
java·开发语言·spring boot·学习·spring
Gyr011 小时前
浅刷了一遍51CTO软考题库客观题及其解析(4)
学习·软考·知识点·信息安全工程师
螺蛳粉 螺蛳粉11 小时前
MySQL 分布式集群系列 · 第五篇——全方位对比:NDB、MGR、主从复制、分库分表怎么选?
数据库·分布式·mysql
是隼人11 小时前
buuctf-pwn [NewStarCTF 2023 公开赛道]stack migration(64位栈迁移)题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门