2025-04-30 21:42

MySQL的MVCC机制详解

王姐姐

数据库

(23)

(0)

收藏

MVCC(Multi-Version Concurrency Control,多版本并发控制)是MySQL实现并发控制的核心机制之一,它使得InnoDB存储引擎在保证一定隔离级别的同时,能够提供高性能的读写并发。

一、MVCC基本概念

MVCC是一种通过数据多版本来实现并发控制的机制,其核心思想是:

- 保存数据的历史版本

- 通过比较版本号来决定数据是否对当前事务可见

- 读操作不加锁,写操作只锁定必要的行

二、MVCC实现的关键要素

1. 隐藏字段

InnoDB每行记录都包含几个隐藏字段:

- `DB_TRX_ID`(6字节):记录最近修改该行数据的事务ID

- `DB_ROLL_PTR`(7字节):回滚指针,指向该行的undo log记录

- `DB_ROW_ID`(6字节):隐藏的自增ID(如果没有主键时)

2. Undo Log

- 存储数据被修改前的值

- 用于事务回滚和MVCC读取历史版本

- 形成版本链,通过`DB_ROLL_PTR`指针连接

3. Read View

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

- `m_ids`:当前活跃(未提交)的事务ID列表

- `min_trx_id`:m_ids中的最小值

- `max_trx_id`:系统应该分配给下一个事务的ID

- `creator_trx_id`:创建该Read View的事务ID

三、MVCC工作原理

1. 数据读取流程

当执行SELECT操作时:

1. 获取当前事务的Read View

2. 遍历行记录的版本链(通过undo log)

3. 检查每行版本的`DB_TRX_ID`:

   - 如果`DB_TRX_ID` < `min_trx_id`:可见

   - 如果`DB_TRX_ID` > `max_trx_id`:不可见

   - 如果`min_trx_id` ≤ `DB_TRX_ID` ≤ `max_trx_id`:

     - 如果`DB_TRX_ID`在`m_ids`中:不可见(事务未提交)

     - 否则:可见

4. 返回第一个可见版本的数据

2. 数据修改流程

当执行UPDATE/DELETE操作时:

1. 获取行记录的排他锁(X锁)

2. 记录undo log

3. 修改行数据,更新`DB_TRX_ID`为当前事务ID

4. 将`DB_ROLL_PTR`指向undo log记录

四、MVCC与隔离级别

1. READ COMMITTED (RC)

- 每次读取前都生成新的Read View

- 能看到其他事务已提交的修改

- 可能出现不可重复读问题

2. REPEATABLE READ (RR)

- 只在第一次读取时生成Read View

- 使用同一Read View完成整个事务

- 解决不可重复读问题(MySQL通过MVCC+间隙锁解决幻读)

五、MVCC的优势与限制

优势:

1. 读不加锁,读写不冲突,提高并发性能

2. 避免脏读、不可重复读问题

3. 减少死锁概率

限制:

1. 需要额外存储空间(undo log)

2. 需要维护版本链,增加维护成本

3. 长期运行的事务可能导致undo log膨胀

六、MVCC与Purge机制

为了防止undo log无限增长,InnoDB有purge线程:

1. 删除不再需要的undo log

2. 清理已提交事务不再需要的旧版本数据

3. 基于系统中最老Read View判断哪些版本可清理

七、实际案例分析

场景:事务并发读取

```
事务A(trx_id=100)                事务B(trx_id=101)
BEGIN;                           BEGIN;
SELECT * FROM t;                 UPDATE t SET c1=20 WHERE id=1;
                                 COMMIT;
SELECT * FROM t;
```

在RR级别下:

- 事务A的两次SELECT使用同一个Read View

- 事务B的修改对事务A不可见

- 保证可重复读

八、总结

MVCC是MySQL实现高并发的重要机制,通过版本控制和Read View实现了:

- 读不加锁,提高并发性能

- 支持RC和RR隔离级别

- 避免常见的并发问题

0条评论

点击登录参与评论