Mysql的MVCC机制

发布于:2025-04-14 ⋅ 阅读:(24) ⋅ 点赞:(0)

MySQL 的 **MVCC(Multi-Version Concurrency Control,多版本并发控制)**是一种实现数据库高并发访问的核心机制,主要用于解决读写冲突,避免事务之间的阻塞,同时保证不同隔离级别下的数据一致性(如READ COMMITTEDREPEATABLE READ)。以下是其核心原理和实现细节:


一、MVCC 的核心思想

  1. 数据多版本:每个数据行在修改时,不会直接覆盖原数据,而是生成一个历史版本链。
  2. 快照读:事务在读取数据时,只能看到在它启动时已经提交的版本,或自身修改的版本,其他未提交的修改不可见。
  3. 无锁读:读操作不阻塞写操作,写操作也不阻塞读操作(仅针对快照读)。

二、MVCC 的实现依赖

1. 隐藏字段

InnoDB 每行数据包含三个隐藏字段:
DB_TRX_ID(6字节):最近修改该行的事务ID。
DB_ROLL_PTR(7字节):回滚指针,指向 undo log 中的旧版本数据。
DB_ROW_ID(6字节):隐含的自增行ID(若表无主键)。

2. Undo Log(回滚日志)

• 存储数据修改前的历史版本,用于构建多版本链。
• 事务对数据修改时,会生成对应的 undo log:
INSERT 操作生成 undo log,用于事务回滚时删除数据。
UPDATE/DELETE 操作生成 undo log,用于构建多版本链。

3. Read View(读视图)

事务在读取数据时生成的一致性视图,决定哪些版本的数据可见。其关键属性包括:
trx_ids:生成 Read View 时活跃的事务ID列表(未提交的事务)。
min_trx_idtrx_ids 中的最小事务ID。
max_trx_id:下一个将分配的事务ID(当前最大事务ID +1)。
creator_trx_id:创建该 Read View 的事务ID(当前事务的ID)。


三、MVCC 的工作流程

1. 数据版本链

每条数据通过 DB_ROLL_PTR 指向 undo log 中的旧版本,形成一个链表结构:

当前行数据(版本N) → undo log(版本N-1) → undo log(版本N-2) → ... → 初始版本
2. 可见性判断规则

事务通过 Read View 判断某数据版本是否可见:

  1. 版本的事务ID < min_trx_id:该版本已提交,可见
  2. 版本的事务ID ≥ max_trx_id:该版本由未来事务生成,不可见
  3. 版本的事务ID 在 trx_ids:该版本由未提交事务生成,不可见
  4. 版本的事务ID = creator_trx_id:该版本由当前事务自己生成,可见
  5. 其他情况:需遍历 undo log 链,找到最近的可见版本。

四、不同隔离级别的实现

1. READ COMMITTED(读已提交)

Read View 生成时机:每次执行 SELECT 语句时生成新的 Read View。
效果:能看到其他事务已提交的最新数据,但可能发生“不可重复读”。

2. REPEATABLE READ(可重复读,MySQL 默认级别)

Read View 生成时机:事务第一次执行 SELECT 时生成 Read View,后续复用。
效果:整个事务中看到的数据版本一致,避免不可重复读和部分幻读(通过 MVCC + Next-Key Lock 解决)。


五、MVCC 的写操作处理

UPDATE/DELETE:基于当前最新数据版本进行修改,生成新的 undo log。
INSERT:新插入的数据对其他事务不可见,直到当前事务提交。


六、MVCC 的优缺点

优点

• 读写不冲突,提高并发性能。
• 避免锁竞争,减少死锁概率。
• 支持快照读,适合读多写少场景。

缺点

• 需要维护多个数据版本,占用额外存储空间。
• 频繁更新可能导致 undo log 链过长,影响查询性能。
• 需要定期清理旧版本数据(Purge 机制)。


网站公告

今日签到

点亮在社区的每一天
去签到