MVCC:数据库事务隔离的 “时空魔法”

目录

一、引入

二、概念

[2.1 MVCC 是什么?](#2.1 MVCC 是什么?)

[2.2 什么是版本链?](#2.2 什么是版本链?)

[2.3 ReadView 是什么?](#2.3 ReadView 是什么?)

[2.4 可见性规则:](#2.4 可见性规则:)

[1. trx_id < min_trx_id:已提交,可见。](#1. trx_id < min_trx_id:已提交,可见。)

[2. trx_id > max_trx_id:未开始,不可见。](#2. trx_id > max_trx_id:未开始,不可见。)

[3. trx_id in m_ids:活跃中,未提交,不可见。](#3. trx_id in m_ids:活跃中,未提交,不可见。)

[4. trx_id == creator_trx_id:自己改的,可见。](#4. trx_id == creator_trx_id:自己改的,可见。)

[2.5 RC 与 RR 的核心区别:ReadView 的生成时机](#2.5 RC 与 RR 的核心区别:ReadView 的生成时机)


在默认隔离级别(REPEATABLE READ)下,InnoDB 的普通 SELECT 默认是快照读 (底层就是MVCC实现)。

而快照读之所以出现,根本原因正是为了解决"共享锁(S 锁)与排他锁(X 锁)互斥"带来的读写阻塞问题

💡了解一下 :不普通的SELECT读就是显式加锁的 SELECT ( 也就是手动加锁的情况**)。**

一、引入

MVCC(多版本并发控制) 是MySQL实现高并发事务的核心机制,其核心在于通过版本链和ReadView实现不同隔离级别下的数据可见性控制 。下面我将详细解释MVCC的工作原理,以及Read View在RC(读已提交) 和**RR(可重复读)**隔离级别下的不同表现。

二、概念

2.1 MVCC 是什么?

MVCC(Multi-Version Concurrency Control)是 InnoDB 实现高并发读写 的机制。

它通过以下三部分协同工作:

  • 隐藏字段 :每条记录有 trx_id(最近修改事务ID)和 roll_ptr(指向旧版本)。

  • Undo Log :保存数据的历史版本,形成版本链

  • ReadView:事务执行快照读时生成的"可见性快照",决定当前事务能看到哪个版本的数据。

2.2 什么是版本链?

版本链 = 同一条记录被多次修改后,借助 Undo Log 形成的"历史快照链表"。

InnoDB 根据 roll_ptr 指针把旧版本串起来,快照读时顺着这条链找可见版本。

2.3 ReadView 是什么?

ReadView 是一个逻辑快照,包含以下关键信息:

  • m_ids:当前活跃的事务ID列表。

  • min_trx_id:最小活跃事务ID。

  • max_trx_id:下一个将分配的事务ID。

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

2.4 可见性规则

遍历版本链,找到第一个满足以下条件的数据版本:

1. trx_id < min_trx_id:已提交,可见。
  • min_trx_id 是当前系统中最小活跃事务 ID

  • 如果某个数据版本的 trx_id 小于 min_trx_id,说明它早于所有当前活跃事务已经提交 ,所以可见

2. trx_id > max_trx_id:未开始,不可见。
  • max_trx_id 是系统下一个即将分配的事务 ID

  • 如果某个数据版本的 trx_id 大于 max_trx_id,说明这个版本是由未来事务 生成的,还没开始 ,所以不可见

3. trx_id in m_ids:活跃中,未提交,不可见。
  • m_ids 是当前活跃事务列表

  • 如果某个数据版本的 trx_id 在这个列表中,说明这个事务还没提交 ,所以不可见

4. trx_id == creator_trx_id:自己改的,可见。
  • 如果某个数据版本的 trx_id 就是当前事务自己的 ID ,那说明是自己修改的,自己当然能看到

2.5 RC 与 RR 的核心区别:ReadView 的生成时机

隔离级别 ReadView 生成时机 可见性表现
RC(读已提交) 每次 SELECT 都新建 ReadView 每次都能看到最新已提交的数据 ,可能会不可重复读
RR(可重复读) 事务中第一次 SELECT 创建 ReadView,之后复用 整个事务内看到的数据保持一致,避免不可重复读

MVCC 是底层机制,RC 和 RR 是它暴露出来的两种"快照策略":

  • RC 每次快照读都生成新的 ReadView,看到最新已提交数据

  • RR 只在第一次快照读时生成 ReadView,之后复用该快照 ,保证可重复读

简单而言,MVCC 通过 Undo 日志保存多版本数据,ReadView 控制"哪个版本可见"。
RC 每次查询都新建 ReadView,保证"读已提交";RR 只建一次并复用,保证"可重复读"

相关推荐
devilnumber几秒前
MySQL 部门表:树结构 (自关联) vs 非树结构 (扁平化 / 冗余字段)
数据库·mysql
fengxin_rou14 分钟前
【MySQL 三大日志深度解析】:redo log、undo log、binlog 作用与两阶段提交原理
数据库·mysql·日志·redo log
ECT-OS-JiuHuaShan15 分钟前
存在是微分张量积,标量是参数但不可能是本质。还原论泛化,是语义劫持和以偏概全的逻辑谋杀伪科学庞氏骗局
数据库·人工智能·算法·机器学习·数学建模
IT策士19 分钟前
Django 从 0 到 1 打造完整电商平台:使用 Django 消息框架与用户权限初步
数据库·django·sqlite
星河耀银海24 分钟前
JAVA 注解(Annotation):从原理到实战应用
java·开发语言·数据库
lzp079127 分钟前
基于多模态视觉模型和图文向量模型的工业图像知识库研究与应用(伍)
数据库·学习·neo4j
sunshine88532 分钟前
合并报表自动化:数据治理如何助力集团企业突破成本与合规瓶颈?
大数据·数据库·人工智能
云边有个稻草人35 分钟前
金仓数据库KingbaseES自动创建表空间目录:简化运维,适配国产生态
数据库·数据加密·kingbasees·信创适配·国产化数据库·表空间自动创建
imuliuliang1 小时前
Laravel5.x核心特性全解析
android·运维·数据库·nginx
Miss roro1 小时前
企业合同管理系统选型的核心维度:功能完整性、协作效率与安全合规
java·数据库·安全·法律科技