【Mysql——MVCC】

介绍

MVCC (多版本并发控制) 是数据库(尤其是 MySQL InnoDB、Oracle、PostgreSQL)实现高并发事务的核心无锁机制 。它通过为每行数据维护多个历史版本,实现 读写互不阻塞,在保证隔离性(ACID 中的 I)的同时大幅提升并发性能。

作用

传统锁机制(悲观锁):

读加共享锁 (S),写加排他锁 (X)

读阻塞写、写阻塞读,高并发下性能瓶颈

MVCC 优势:

读不加锁(快照读),写不阻塞读,读不阻塞写

事务看到的是一致性数据快照,而非实时最新值

完美解决 脏读不可重复读 ,配合间隙锁可解决幻读

原理

InnoDB 通过 隐藏字段 + Undo Log + ReadView 实现 MVCC。

  1. 行记录隐藏字段

每行数据额外隐式存储 3 个字段(用户不可见):

DB_TRX_ID (6 字节):创建 / 最后修改该行的事务 ID(全局递增)

DB_ROLL_PTR (7 字节):回滚指针,指向 Undo Log 中的上一个历史版本

DB_ROW_ID (6 字节):隐藏主键(表无主键时自动生成)

  1. Undo Log(回滚日志)

作用:存储数据修改前的旧版本快照,用于事务回滚 & MVCC 历史读取

类型:

INSERT Undo Log:事务提交后立即删除

UPDATE/DELETE Undo Log:提交后暂存,供快照读读取历史版本,后台定时清理

版本链:

多次 UPDATE/DELETE 时,通过 DB_ROLL_PTR 把所有历史版本串成单向链表(最新版本在表中,旧版本在 Undo Log 里)。

  1. ReadView(读视图 / 一致性快照)

ReadView 是判断 "哪个版本可见" 的核心规则,在快照读(普通 SELECT)时生成。

ReadView 四要素:

m_ids:生成快照时,所有活跃未提交事务 ID 列表

min_trx_id:m_ids 中最小事务 ID

max_trx_id:系统下一个待分配的事务 ID(当前最大 ID + 1)

creator_trx_id:当前事务自己的 ID

版本可见性判断算法

沿版本链从最新到最旧遍历,用 DB_TRX_ID 与 ReadView 比对,第一个满足以下任一条件即可见:

自己修改的:trx_id == creator_trx_id → 可见

已提交的旧版本:trx_id < min_trx_id → 生成快照前已提交 → 可见

未来事务:trx_id >= max_trx_id → 不可见(快照后才创建)

活跃事务区间:min_trx_id ≤ trx_id < max_trx_id

若 trx_id 不在 m_ids → 已提交 → 可见

若 trx_id 在 m_ids → 仍活跃未提交 → 不可见

隔离级别与 ReadView 生成时机

MVCC 只在 RC 和 RR 级别生效;RU(总是读最新)、SERIALIZABLE(加锁读)不使用 MVCC。

  1. READ COMMITTED (读已提交,RC)

每次 SELECT 都生成新 ReadView

特点:总能读到其他事务已提交的最新值

问题:不可重复读(同事务内两次 SELECT 结果可能不同)

  1. REPEATABLE READ (可重复读,RR, MySQL 默认)

事务中第一次 SELECT 时生成 ReadView,后续复用

特点:整个事务内数据一致,看不到其他事务后续提交修改

解决:脏读、不可重复读;配合 Next-Key Lock(查表时不能添加数据) 解决幻读

快照读和当前读

快照读(MVCC 生效),普通 SELECT,不加锁,读取历史版本。

当前读(加锁,MVCC 不生效),读取最新版本并加锁,保证数据强一致性。

SELECT ... FOR UPDATE / LOCK IN SHARE MODE

INSERT / UPDATE / DELETE

相关推荐
XDHCOM2 小时前
ORA-31477: LogMiner会话清理失败,Oracle报错故障修复远程处理,快速解决,数据安全无忧
数据库·oracle
白毛大侠2 小时前
# MySQL InnoDB 隔离级别与 MVCC 完全解析
android·数据库·mysql
weisian1512 小时前
进阶篇-LangChain篇-10--向量数据库选型指南:本地FAISS, Chroma与云原生方案
数据库·langchain·faiss·向量数据库·chroma
草莓熊Lotso3 小时前
MySQL 从入门到实战:视图特性 + 用户权限管理全解
linux·运维·服务器·数据库·c++·mysql
Navicat中国4 小时前
如何使用 Ollama 配置 AI 助手 | Navicat 教程
数据库·人工智能·ai·navicat·ollama
小猿姐8 小时前
实测对比:哪款开源 Kubernetes MySQL Operator 最值得用?(2026 深度评测)
数据库·mysql·云原生
倔强的石头_10 小时前
从 “存得下” 到 “算得快”:工业物联网需要新一代时序数据平台
数据库
TDengine (老段)11 小时前
TDengine IDMP 可视化 —— 分享
大数据·数据库·人工智能·时序数据库·tdengine·涛思数据·时序数据
GottdesKrieges12 小时前
OceanBase数据库备份配置
数据库·oceanbase