MySQL的InnoDB存储引擎使用多版本并发控制(MVCC,Multi-Version Concurrency Control)机制来支持高并发的读写操作,同时保证事务的隔离性和一致性。MVCC允许不同的事务看到不同的数据版本,从而减少了锁的竞争,提高了数据库的并发性能。
隐式字段
InnoDB在每行记录中添加了几个隐藏的列,包括:
DB_TRX_ID
:记录最后一次修改该行的事务ID。DB_ROLL_PTR
:指向undo log的指针,用于回滚操作。DB_ROW_ID
:行的内部ID,用于辅助排序和查找。
版本链
每当一行数据被更新时,InnoDB并不会直接修改该行,而是生成一个新的行版本,并且保留旧的行版本。这样,不同的事务就可以看到不同时间点的数据版本。
Read View
Read View是事务可见性的关键概念。当一个事务开始时,它会创建一个Read View,这个Read View包含了当前活跃事务的列表。Read View用于判断某一行是否对当前事务可见。只有那些在Read View创建之前就已经提交的事务所修改的行才会对当前事务可见。
快照读和当前读
- 快照读(Snapshot Read):快照读是非锁定读取,即SELECT查询默认的行为。它读取的是最新的可读版本,不会阻塞其他事务对同一行的读写操作。
- 当前读(Current Read):当前读是指锁定读取,通常发生在使用
FOR UPDATE
或LOCK IN SHARE MODE
时。它会读取行的最新版本,并可能产生行级锁。
隔离级别
- 读已提交(Read Committed):在这个隔离级别下,每次读操作都会看到最新的提交版本,这意味着事务间的可串行化程度较低,但并发度较高。
- 可重复读(Repeatable Read):在这个隔离级别下,一旦事务读取了某行数据,即使有其他事务更新了该行,当前事务再次读取时仍会看到第一次读取时的版本,因此可以重复读取相同的数据版本。
实现流程
- 对于快照读,InnoDB会检查行的版本是否比当前事务的Read View早,如果是,则行可见;否则,行不可见。
- 对于当前读,InnoDB会直接读取行的最新版本,并可能产生锁。
通过上述机制,InnoDB能够有效地处理并发读写操作,同时保证了事务的ACID属性。
需要注意的是,虽然MVCC提高了并发性能,但它也增加了存储空间的消耗,因为需要存储多个版本的数据,并且在某些情况下可能导致幻读(Phantom Reads)。此外,MVCC的实现也会增加一些额外的计算开销,尤其是在需要进行版本比较和Read View维护时。
标签:事务,读取,Read,MVCC,InnoDB,版本,MySQL,原理,View From: https://www.cnblogs.com/use-D/p/18290330