当前位置: 首页 > news >正文

MySQL MVCC(多版本并发控制)详解

1. 什么是MVCC?

MVCC(Multi-Version Concurrency Control,多版本并发控制) 是 MySQL(InnoDB引擎)实现高并发访问的核心机制之一。它通过在同一时刻保存数据的多个版本,使得:

  • 读操作不阻塞写操作
  • 写操作不阻塞读操作
  • 提高数据库的并发性能

📌 对比锁机制

  • 传统锁(如行锁)会导致读写冲突
  • MVCC 通过数据多版本实现非阻塞读

2. MVCC 核心原理

2.1 版本链与隐藏字段

InnoDB 每行记录包含3个隐藏字段

  1. DB_TRX_ID(6字节):最近修改该行的事务ID
  2. DB_ROLL_PTR(7字节):回滚指针,指向Undo Log中的旧版本
  3. DB_ROW_ID(6字节):行ID(无主键时自动生成)
-- 实际存储结构(伪代码)
row = {id: 1, name: "Alice",DB_TRX_ID: 100, DB_ROLL_PTR: 0x123456, DB_ROW_ID: 1
}

2.2 Undo Log(回滚日志)

  • 存储数据被修改前的历史版本,形成版本链
  • 用于:
    • 事务回滚(ROLLBACK)
    • MVCC 读一致性视图
DB_ROLL_PTR
roll_ptr
当前行
Undo Log v1
Undo Log v2

2.3 ReadView(一致性视图)

决定事务能看到哪个版本的数据,包含:

  • creator_trx_id:创建该ReadView的事务ID
  • m_ids:生成ReadView时活跃的事务ID列表
  • min_trx_id:m_ids中的最小ID
  • max_trx_id:系统下一个待分配的事务ID

3. MVCC 工作流程

3.1 读操作(SELECT)

通过 ReadView 判断数据可见性:

  1. 如果 DB_TRX_ID < min_trx_id:说明数据在ReadView创建前已提交 → 可见
  2. 如果 DB_TRX_ID >= max_trx_id:说明数据在ReadView创建后修改 → 不可见
  3. 如果 min_trx_id <= DB_TRX_ID < max_trx_id
    • DB_TRX_ID ∈ m_ids:说明事务未提交 → 不可见
    • 否则 → 可见

3.2 写操作(UPDATE/DELETE)

  1. 新数据写入时,旧数据进入 Undo Log
  2. 更新 DB_TRX_ID 为当前事务ID
  3. 更新 DB_ROLL_PTR 指向旧版本

4. MVCC 与隔离级别

不同隔离级别下 MVCC 的行为:

隔离级别MVCC 行为
READ UNCOMMITTED直接读最新数据(不适用MVCC)
READ COMMITTED (RC)每次SELECT生成新ReadView,能看到其他事务已提交的修改
REPEATABLE READ (RR)第一次SELECT时生成ReadView,后续沿用该视图(避免不可重复读)
SERIALIZABLE退化为加锁(不适用MVCC)

5. 实战案例分析

场景:事务并发修改同一条数据

-- 初始数据
INSERT INTO users (id, name) VALUES (1, 'Alice');-- 事务1(TRX_ID=100)
BEGIN;
UPDATE users SET name = 'Bob' WHERE id = 1;-- 事务2(TRX_ID=200,在RC隔离级别下)
BEGIN;
SELECT name FROM users WHERE id = 1; -- 看到 'Alice'(ReadView在事务1提交前生成)
COMMIT;-- 事务1提交后
COMMIT;-- 事务3(TRX_ID=300)
BEGIN;
SELECT name FROM users WHERE id = 1; -- 看到 'Bob'(事务1已提交)

6. MVCC 的优缺点

优点

高并发:读写不互相阻塞
避免锁竞争:减少死锁概率
快照读:支持一致性非锁定读

缺点

额外存储:需维护Undo Log和历史版本
清理成本:需要Purge线程清理旧版本数据


7. 关键参数优化

-- 查看InnoDB MVCC相关状态
SHOW ENGINE INNODB STATUS;-- 控制Undo Log保留时间(默认0,表示由purge线程自动管理)
SET GLOBAL innodb_undo_log_truncate = ON;
SET GLOBAL innodb_undo_retention = 3600; -- 保留1小时

总结

  1. MVCC 通过版本链 + ReadView 实现非阻塞读
  2. RC/RR 隔离级别依赖 MVCC 实现不同的一致性视图
  3. Undo Log 是 MVCC 的基石,存储历史版本数据
  4. 合理设置隔离级别和undo保留时间可优化性能

理解 MVCC 能帮助你设计更高并发的数据库应用! 🚀

http://www.lqws.cn/news/508051.html

相关文章:

  • 华为云Flexus+DeepSeek征文|DeepSeek-V3与R1的差异化体验
  • iwebsec靶场-文件上传漏洞
  • Vue 3 和 Ant Design 版本3.2.20 Table解析
  • OSS阿里云
  • 实现OFD转换PDF文件的实用方法
  • Joblib库多进程/线程使用(一):使用generator参数实现边响应边使用
  • RISC-V三级流水线项目:总体概述和取指模块
  • 借助antd-design-x-vue实现接入通义千问大语言模型的对话功能(二) 新增思考内容展示
  • 使用 PyFluent 自动化 CFD
  • Reactor框架介绍,和使用示例
  • 内存泄漏和内存溢出的区别
  • ubuntu22.04修改IP地址
  • Camera Api 2 和 OPEN GL ES 使用(显示滤镜效果)
  • 【网络安全】从IP头部看网络通信:IPv4、IPv6与抓包工具 Wireshark 实战
  • 基于单片机的语音控制设计(论文)
  • 618风控战升级,瑞数信息“动态安全+AI”利剑出鞘
  • 09-StarRocks安全配置FAQ
  • 03-StarRocks查询优化FAQ
  • 服务器安装指南
  • PYTHON从入门到实践2-环境配置与字符串打印用法
  • 黑马Day01-03集开始
  • 轻量化实物建模革命:WebGL如何实现复杂模型的高效加载与交互
  • 增刊第2章:模型API封装与安全
  • 从虚拟机角度解释python3相对导入问题(下)
  • CasaOS中Docker部署SyncThing结合Cpolar实现公网文件同步方案
  • MemcacheRedis--缓存服务器理论
  • 解锁阿里云AnalyticDB:数据仓库的革新利器
  • 较大项目 git(gitee, github) 拉取失败解决方法
  • 想考华为HCIA-AI,应该怎么入门?
  • Python 数据分析与可视化 Day 6 - 可视化整合报告实战