当前读:
读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。对于我们日常的操作,如:select ... lock in share mode(共享锁),select ... for update、update、insert、delete(排他锁)都是一种当前读。

开启事务后,另外的事务更新、并且提交后,在事务中仍然读取不到另外事务更新的内容。
如果加上lock in share mode;
select * from stu lock in share mode; 那么就能读取到另外事务的更新,这就是当前读。

快照读
简单的select(不加锁)就是快照读,快照读,读取的是记录数据的可见版本,有可能是历史数据,不加锁,是非阻塞读。
read committed: 每次select,都生成一个快照读。
repeatable read: 开启事务后第一个select语句才是快照读的地方。
serializable: 快照读会退化为当前读。
MVCC:
全称Multi-Version concurrency Control, 多版本并发控制。指维护一个数据的多个版本,使得读写操作没有冲突,快照读为MySQL实现MVCC提供了一个非阻塞读功能。MVCC的具体实现,还需要依赖于数据库记录中的三个隐式字段、undo log日志、readview。
隐藏字段
DB_TRX_ID: 最近修改事务ID,记录插入这条记录或最后一次修改该记录的事务ID
DB_ROLL_PTR: 回滚指针,指向这条记录的上一个版本,用于配合undo log,指向上一个版本。
DB_ROW_ID: 隐藏主键,如果表结构没有指定主键,将会生成该隐藏字段。
undo log
回滚日志,在insert、update、delete的时候产生的便于数据回滚的日志。
当insert的时候,产生的undo log日志只在回滚时需要,在事务提交后,可被立即删除。
而update、delete的时候,产生的undo log日志不仅在回滚时需要,在快照读时也需要,不会立即被删除。
undo log版本链

不同事务或相同事务对同一条记录进行修改,会导致该记录的undolog生成一条记录版本链表,链表的头部是最新的旧记录,链表尾部是最早的旧记录。
readview:
ReadView(读视图)是快照读SQL执行时MVCC提取数据的依据,记录并维护系统当前活跃的事务(未提交的)id。
ReadView中包含了四个核心字段:
m_ids: 当前活跃的事务ID集合
min_trx_id: 最小活跃事务ID
max_trx_id:预分配事务ID,当前最大事务ID+1(因为事务的ID是自增的)
creator_trx_id:ReadView创建者的事务ID
readview版本链数据访问规则
(1)trx_id == creator_trx_id? 可以访问该版本--->成立,说明数据是当前这个事务更的。
(2)trx_id < min_trx_id? 可以访问该版本 --->成立,说明数据已经提交了。
(3)trx_id > max_trx_id? 不可以访问该版本--->成立,说明该事务是在readview生成后才开启。
(4)min_trx_id 成立,说明数据已经提交。
不同的隔离级别,生成readview的时机不同:
read committed: 在事务中每一次执行快照读时生成readview
repeatable read: 仅在事务中第一次执行快照读时生成readview,后续服用该readview。


950

被折叠的 条评论
为什么被折叠?



