1 、read_view 中维护了系统中活跃事务集合的快照,这些活跃事务 ID 的最小值为 up_limit_id,最大值为 low_limit_id ; SELECT 操作返回结果的可见性是由以下规则决定的:
DB_TRX_ID < up_limit_id -> 此记录的最后一次修改在 read_view 创建之前,可见
DB_TRX_ID > low_limit_id -> 此记录的最后一次修改在 read_view 创建之后,不可见 -> 需要用 DB_ROLL_PTR 查找 undo log(此记录的上一次修改),然后根据 undo log 的 DB_TRX_ID 再计算一次可见性
up_limit_id <= DB_TRX_ID <= low_limit_id -> 需要进一步检查 read_view 中是否含有 DB_TRX_ID
DB_TRX_ID ∉ read_view -> 此记录的最后一次修改在 read_view 创建之前,可见
DB_TRX_ID ∈ read_view -> 此记录的最后一次修改在 read_view 创建时尚未保存,不可见 -> 需要用 DB_ROLL_PTR 查找 undo log(此记录的上一次修改),然后根据 undo log 的 DB_TRX_ID 再从头计算一次可见性
2 、RR 隔离级别下:read view 是在 first touch read 时创建的,也就是执行事务中的第一条 SELECT 语句的瞬间,后续所有的 SELECT 都是复用这个 read view,所以能保证每次读取的一致性(可重复读的语义)
按照这个说法,RR 隔离级别下是读取不到其他事务插入的数据的,那为什么还需要 next-key lock 算法加锁来阻止其他事务的插入呢
求大佬解惑
1
XiLemon 2021-02-05 10:50:53 +08:00
mvcc 可以解决快照读的幻读,当前读还是要用 Next-key lock 吧
|
2
radiocontroller 2021-02-05 10:54:49 +08:00
RR 隔离级别下是读取不到其他事务插入的数据的
|
3
radiocontroller 2021-02-05 10:56:46 +08:00
@radiocontroller RR 隔离级别下是读取不到其他事务插入的数据的,这里是快照读。那为什么还需要 next-key lock 算法加锁来阻止其他事务的插入呢,这里是当前读
|
4
bringyou 2021-02-05 10:59:06 +08:00
我感觉是为了解决幻读
|
5
xixihaha1 2021-02-05 11:00:06 +08:00
mvcc 可以解决“快照读”的幻读问题,但是解决不了“当前读”的幻读问题
|
6
whatevers OP @XiLemon @radiocontroller 恍然大悟,忽略了读的上下文,多谢两位大佬
|
7
awanganddong 2021-02-05 11:37:04 +08:00
备注下:
当前读 当前读是基于 临键锁(行锁 + 间歇锁)来实现的,适用于 insert,update,delete,select ... for update,select ... lock in share mode 语句,以及加锁了的 select 语句。 更新数据时,都是先读后写,而这个读,就是当前读。读取数据时,读取该条数据的已经提交的最新的事务,生成的 readView 。 |
8
YouLMAO 2021-02-05 14:52:16 +08:00
like share and Subscribe
|
9
zzkde 2021-02-06 14:16:50 +08:00
low_limit_id 指的不是系统中活跃事务的最大 ID,应该是系统要生成的下一个事务 ID 。可以试想这种情况:ReadView 创建时,系统中活跃的最大事务 ID 可能已经存在很久了,这期间也会提交事务(在 ReadView 创建时就已提交),这些提交了的事务应该是可见的。
|