成功自己定义 发表于 2024-1-21 11:20:02

mysql之MVCC


1、概念
mvcc作用在于解决并发条件下,读写冲突的问题。一般用于RC和RR隔离级别,解决脏读和不可重复读的问题。
(1)当前读
读取的是记录的最新版本,读取时还要保证其他事务不能修改当前记录,会对读取的记录进行加锁。对于我们日常的操作,如:select ... lock in share mode(共享锁),select ... for update、update、insert、delete(排他锁)都是一种当前读。
(2)快照读
简单的select 就是快照读,读取的是记录的可见版本, 有可能是历史数据,不加锁,不阻塞

[*]Read Committed:每次select,都会生成一个快照读
[*]Repeatable Read:开启事务后第一个select语句才是快照读的地方。
[*]Serializable:快照读会退化为当前读。
2、MVCC的条件
要实现MVCC,需要3个条件:3个隐藏字段,undo log以及readview。
(1)隐藏字段
表结构中除了行数据以外,还有3个隐藏字段:

[*]DB_TRX_ID:最新修改的事务ID,记录插入和修改最后一次的事务ID
[*]DB_ROLL_PTR :回滚指针,指向上一个版本记录
[*]DB_ROW_ID:隐藏主键,如果表结构没有指定主键,将会生成该隐藏字段。
(2)undo log
回滚日志,在insert update delete语句执行时保存回滚的日志。
当insert的时候,产生的undo log日志只在回滚时需要,在事务提交后,可被立即删除。
而update、delete的时候,产生的undo log日志不仅在回滚时需要,在快照读时也需要,不会立即 被删除。
不同事务对同一条记录进行修改后,会生成一条版本连,下图为undo log中记录的版本链。

(3)readview
ReadView(读视图)是 快照读 SQL执行时MVCC提取数据的依据。
readView包含四个核心字段:

[*]m_ids:当前活跃的事务ID集合
[*]min_trx_id:最小活跃事务ID
[*]max_trx_id:预分配事务ID,当前最大事务ID+1(因为事务ID是自增的)
[*]creator_trx_id:ReadView创建者的事务ID
在readview中就规定了版本链数据的访问规则:
<ul>trx_id == creator_trx_id:可以访问该版本 成立,说明数据是当前这个事 务更改的。
trx_id < min_trx_id :可以访问该版本  成立,说明数据已经提交了。
trx_id > max_trx_id:不可以访问该版本 成立,说明该事务是在 ReadView生成后才开启。

min_trx_id
页: [1]
查看完整版本: mysql之MVCC