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
相关推荐
doubt。22 分钟前
【BUUCTF】[RCTF2015]EasySQL1
网络·数据库·笔记·mysql·安全·web安全
Maybe_ch1 小时前
群晖部署-Calibreweb
数据库·群晖·nas
小辛学西嘎嘎1 小时前
MVCC在MySQL中实现无锁的原理
数据库·mysql
CC呢1 小时前
基于STM32单片机火灾安全监测一氧化碳火灾
数据库·mongodb
MasterNeverDown2 小时前
解决 PostgreSQL 中创建 TimescaleDB 扩展的字符串错误
数据库·postgresql·oracle
limts2 小时前
Oracle之开窗函数使用
数据库·oracle
拾荒的小海螺4 小时前
JAVA:Spring WebClient 的应用指南
java·数据库·spring
LuckyRich14 小时前
2024年博客之星主题创作|2024年度感想与新技术Redis学习
数据库·redis·缓存
重整旗鼓~4 小时前
4.flask-SQLAlchemy,表Model定义、增删查改操作
数据库·python·flask
咩咩大主教4 小时前
Go语言通过Casbin配合MySQL和Gorm实现RBAC访问控制模型
mysql·golang·鉴权·go语言·rbac·abac·casbin