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执行其工作流程
相关推荐
疯狂打码的少年2 小时前
【数据库技术】关系模型基本概念(关系/属性/元组/键)
java·服务器·数据库·笔记
普马萨特4 小时前
实体与位置关系的数据从哪里来:获取、治理与仍待解决的问题
网络·数据库
Bruce_Liuxiaowei4 小时前
从基础理论开始学习人工智能(三):盲目搜索——从状态空间图到生成-测试范式
人工智能·学习
醉颜凉5 小时前
KingbaseES日期格式化:MySQL date_format函数的迁移指南
mysql·date_format·kingbasees·数据库兼容·函数迁移
醉颜凉5 小时前
MySQL 8 忘记 root 密码?这两种方法帮你轻松解决
数据库·mysql·adb
有梦想的骇客5 小时前
PyTorch学习笔记
pytorch·笔记·学习
刃神太酷啦5 小时前
Linux 系统 MySQL 完整安装配置教程:从卸载 MariaDB 到优化 my.cnf----《Hello MySQL!》(1)
android·linux·c语言·c++·mysql·leetcode·mariadb
RestCloud5 小时前
集成链路监控体系搭建:接口调用、数据流转与异常告警全覆盖
数据库·数据安全·ipaas·api管理·数据监控·集成平台·api 治理
陈年老古董5 小时前
深度学习入门笔记:从神经元到深度神经网络
人工智能·笔记·深度学习·神经网络·学习
xxwl5856 小时前
MySQL 基础学习笔记
数据库·mysql