MySQL-MVCC(多版本并发控制)

MVCC

MVCC(Multi-Version concurency Control,多版本并发控制 )是一种并发控制机制,允许多个事务同时读取和写入数据库,而无需互相等待,从而提高数据库的并发性能。

首先需要先了解当前读快照读两个概念

当前读

读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。对于我们日常的操作,如:select ... lock in share mode(共享锁),select ... for update、update、insert、delete(排他锁)都是一种当前读。

快照读

简单的select(不加锁)就是快照读,快照读,读取的是记录数据的可见版本,有可能是历史数据,不加锁,是非阻塞读。

  • Read committed(RC读已提交):每次select,都生成一个快照读。
  • Repeatable Read(RR可重复读 ):开启事务后第一个select语句才是快照读的地方。
  • Serializable(串行化 ):快照读会退化为当前读。

--

MVCC基本原理

在 MVCC 中,数据库为每个事务创建一个数据快照 。每当数据被修改时,MySQL不会立即覆盖原有数据,而是生成新版本的记录。每个记录都保留了对应的版本号或时间戳。

多版本之间串联起来就形成了一条版本链 ,这样不同时刻启动的事务可以无锁地获得不同版本的数据(普通读)

此时读(普通读)写操作不会阻塞写操作可以继续写,无非就是会创建新的数据版本(但只有在事务提交后,新版本才会对其他事务可见。未提交的事务修改不会影响其他事务的读取),历史版本记录可供已经启动的事务读取。

--

MVCC主要由:隐藏字段、undo log、readView组成

隐藏字段:
  • DB _TRX_ID(事务id),记录每一次操作的事务id,是自增的
  • DB_ROLL_PTR(回滚指针),指向上一个版本的事务版本记录地址
  • DB_ROW_ID(隐藏主键),如果没有主键,则后会生成该隐藏字段
undo log:
  • 回滚日志:存储老版本数据

  • 版本链:不同事务或相同事务对同一条记录进行修改,会导致该记录的undo log生成一条记录版本链表,表的头部是最新的旧记录,链表尾部是最早癿撄耧的旧记录。

readView(读视图)

ReadView(读视图)是 快照读 SQL执行时MVCC提取数据的依据,记录并维护系统当前活跃的事务(未提交的)id。

  • 根据readView的匹配规则和当前的一些事务id判断该访问那个版本的数据
  • 不同的隔离级别快照读是不一样的,最终的访问的结果不一样
    • RC:每一次执行快照读时生成ReadView
    • RR:仅在事务中第一次执行快照读时生成ReadView,后续复用

ReadView中包含了四个核心字段:

字段 含义
m_ids 当前活跃的事务ID集合
min_trx_id 最小活跃事务ID
max_trx_id 预分配事务ID,当前最大事务ID+1(因为事务ID是自增的)
creator_trx_id ReadView创建者的事务ID
相关推荐
零雲17 分钟前
除了缓存,我们还可以用redis做什么?
数据库·redis·缓存
cyforkk30 分钟前
MySQL 唯一约束:从基础到实战,解决数据重复的核心工具
数据库·mysql
不想被吃掉氩1 小时前
MySQL的事务特性和高可用架构
数据库·oracle
快乐肚皮1 小时前
SQL调优全攻略:从原理到实战
mysql
万添裁1 小时前
关系模型的数据结构
数据库
「QT(C++)开发工程师」2 小时前
UML | 最好的类图设计工具结合CSDN天启呈现-领路架构师
数据库·uml·类视图
Damon小智2 小时前
玩转ClaudeCode:用Database-MCP实现自然语言操作数据库
数据库·ai编程·claude·vibe coding·claude code
相与还2 小时前
godot+c#使用godot-sqlite连接数据库
数据库·c#·godot
ZHOU_World2 小时前
数据库主从同步
数据库·mysql
茉莉玫瑰花茶2 小时前
MySQL 用户管理
数据库·mysql