6. MVCC底层原理剖析

6.1 基本概念

当前读

读取的是记录的最新版本。读取时还要保证其他的并发事务不能修改当前记录。会对读取的记录进行加锁。对于我们日常的操作,比如:

select ... lock in share mode; # 共享锁 - 当前读
select ... for update,delete,insert; # 排他锁 - 当前读

以上都是当前读。

快照读

对当前的数据生成一个快照, 后续的数据基于当前数据进行增删改查。

简单的select语句(不加锁)就是快照读。非阻塞读。

Read Committed: 每次select,都生成一个快照读
Repeatable Read:开启事务后,第一个select语句才是快照读的地方
Serializable: 快照读会升级为当前读

MVCC

全称Multi-Version Concurrency Control:多版本并发控制

指维护数据的多个版本,使得读写操作没有冲突,快照读为MySQL实现MVCC提供了一个非阻塞读的功能。

MVCC具体的实现,还需要依赖于数据库记录的二/三个隐式字段, undo log日志, readview

6.2 三个隐式字段

id name age DB_TRX_ID DB_ROLL_PTR DB_ROW_ID
1 tom 19 当前事务ID 回滚指针 隐式主键
  • DB_TRX_ID

    最近修改事务ID,记录更新这条数据记录的事务ID

  • DB_ROLL_PTR

    回滚指针,指向这条数据的上一个版本,用于配合undo log

  • DB_ROW_ID

    隐藏主键,没有指定主键,会生成该字段

6.3 undo log

回滚日志, 在insert, update, delete的时候产生的。 便于回滚数据。

对于insert操作, 产生的undo log只在回滚时需要,事务提交后,可被立即删除。

对于update和delete操作,产生的undo log不仅在回滚时需要,快照读时也需要,事务提交后不会立即删除。

6.4 Read View

Read View 是快照读SQL执行时MVCC提取数据的依据,记录并维护系统当前活跃的事务(未提交的事务)id。

Read View包含4个核心字段

  • m_ids: 当前活跃事务的id集合
  • min_trx_id:最小活跃事务id
  • max_trx_id:当前最大活跃事务id + 1
  • create_trx_id: Read View创建者的事务ID

不同隔离级别, Read View生成的规则不同。

  • READ UNCOMMITTED: 不生成

  • READ COMMITTED: 在事务中每执行一次快照读时生成Read View

  • REPEATABLE READ: 在事务中第一次执行快照读时生成Read View, 后续复用该Read View。

  • SERIALIZABLE:不生成

undo log版本链数据访问规则:

  • trx_id == create_trx_id : 可以访问该版本数据. 该条件成立说明就是当前事务更改的该数据。
  • trx_id < min_trx_id : 可以访问该版本数据。该条件成立,说明更改这条数据的事务已经提交。
  • trx_id >= max_trx_id: 不可以访问。 该条件成立, 说明这条数据是现在的Read view生成后的新开事务更改的。
  • min_trx_id <= trx_id < max_trx_id: 只有在trx_id不再m_ids的集合中时,这条数据才可以被访问。因为说明这个trx_id的事务已经提交。
posted @ 2025-09-21 20:17  飞↑  阅读(9)  评论(0)    收藏  举报