理解数据库多版本并发控制协议(MVCC)

理解数据库多版本并发控制协议(MVCC)

MVCC基本概念

多版本并发控制(Multi-Version Concurrency Control, MVCC)是一种数据库并发控制机制,它通过维护数据的多个版本来实现并发事务的隔离性,避免了传统的锁机制带来的性能问题。

MVCC核心思想

  1. 数据版本化:每次数据修改都会创建一个新版本,而不是直接覆盖旧数据
  2. 快照读:事务看到的是数据库在某个时间点的快照,而不是实时数据
  3. 无阻塞读取:读操作不会阻塞写操作,写操作也不会阻塞读操作

MVCC与事务隔离级别

MVCC在不同隔离级别下的表现:

  1. 读未提交(Read Uncommitted):不使用MVCC,直接读取最新数据
  2. 读已提交(Read Committed):每个语句看到的是语句开始时已提交的数据
  3. 可重复读(Repeatable Read):事务看到的是事务开始时已提交的数据
  4. 串行化(Serializable):通过锁机制实现,不使用MVCC

MVCC实现机制

常见实现方式

  1. 版本链:每个数据行维护一个版本链,包含创建和删除时间戳
  2. 可见性规则:根据事务ID和数据版本的时间戳决定哪些版本对当前事务可见
  3. 垃圾回收:定期清理不再被任何事务引用的旧版本数据

具体实现示例

以PostgreSQL为例:

  • 每个事务有唯一的事务ID(XID)
  • 每个数据行有xmin(创建该行的事务ID)和xmax(删除/更新该行的事务ID)
  • 通过比较事务ID和数据行的xmin/xmax决定行的可见性

MVCC案例

案例1:并发读写

bash 复制代码
事务A(事务ID=100)                事务B(事务ID=101)
BEGIN;                          BEGIN;
                                UPDATE users SET name='Bob' WHERE id=1;
SELECT name FROM users WHERE id=1;
(看到旧值'Alice')
COMMIT;                         COMMIT;

解释:

  • 事务B更新记录创建了新版本
  • 事务A的查询看到的是事务开始时的快照(包含旧值)
  • 两个事务互不阻塞

案例2:非阻塞读取

bash 复制代码
事务A(事务ID=100)                事务B(事务ID=101)
BEGIN;                          BEGIN;
                                SELECT * FROM large_table;
UPDATE large_table SET ...;
(不会被事务B阻塞)
COMMIT;                         COMMIT;

解释:

  • 事务B的长查询读取快照数据
  • 事务A的更新可以立即执行,不会被阻塞
  • 事务B看到的是它开始时的数据状态

案例3:避免幻读(在可重复读隔离级别)

bash 复制代码
事务A(事务ID=100)                事务B(事务ID=101)
BEGIN;                          BEGIN;
SELECT * FROM users WHERE age>30;
                                INSERT INTO users VALUES(...,35);
SELECT * FROM users WHERE age>30;
(两次结果相同,没有幻读)
COMMIT;                         COMMIT;

解释:

  • 在可重复读隔离级别下,事务A看到的是事务开始时的快照
  • 事务B插入的新记录对事务A不可见
  • 避免了幻读问题

MVCC的优缺点

优点

  1. 读操作不阻塞写操作,写操作不阻塞读操作
  2. 避免了大多数锁争用,提高了并发性能
  3. 提供了一致的数据视图

缺点

  1. 需要额外的存储空间来维护多个版本
  2. 需要垃圾回收机制清理旧版本数据
  3. 写操作可能需要检查多个版本,有一定开销

MVCC是现代数据库系统(如PostgreSQL、Oracle、MySQL InnoDB等)实现高并发的重要机制,通过数据多版本化实现了读写并发,大大提高了数据库系统的吞吐量。

相关推荐
云祺vinchin2 小时前
中小企业备份软件选型从恢复需求到总体成本评估
数据库·数据备份·中小企业备份·容灾备份软件
Zenova EdgeOS3 小时前
Go 工业边缘错误处理实战:用 errors 构建可追溯错误链
开发语言·数据库·golang
KKKlucifer3 小时前
国内数据安全服务的产品智能化转型:大模型赋能下的技术能力重构分析
大数据·数据库·重构
字节跳动开源4 小时前
OpenViking 上线原生 3D 内容理解模型
数据库·开源
CCIE-Yasuo6 小时前
网络安全-学习数据库-Mysql-2
数据库·学习·mysql
这个DBA有点耶6 小时前
内核级AI与多模融合:AI数据库在海外场景的落地要点
数据库·人工智能·架构
涛思数据(TDengine)6 小时前
从工业本体到 AI 原生:TDengine 出席 2026 QCon 分享工业数据基础设施路径
大数据·数据库·人工智能·tdengine·工业
Jesse_EC6 小时前
换乘次数最少的路径 SQL 查询详解与实战经验——从 WITH RECURSIVE 到 pgRouting
数据库·postgresql
工控丫丫6 小时前
帆软看板中经常使用的公式函数及经常搭的组合
前端·javascript·数据库
这个DBA有点耶7 小时前
云数据库半夜卡顿,CPU才30%?深挖云盘IOPS突发限制与内核挂起机制
数据库·mysql·云原生