V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
whatevers
V2EX  ›  MySQL

innodb RR 隔离级别下的小问题

  •  
  •   whatevers · 2021-02-05 10:27:19 +08:00 · 2296 次点击
    这是一个创建于 1379 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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 算法加锁来阻止其他事务的插入呢

    求大佬解惑

    9 条回复    2021-02-06 14:16:50 +08:00
    XiLemon
        1
    XiLemon  
       2021-02-05 10:50:53 +08:00
    mvcc 可以解决快照读的幻读,当前读还是要用 Next-key lock 吧
    radiocontroller
        2
    radiocontroller  
       2021-02-05 10:54:49 +08:00
    RR 隔离级别下是读取不到其他事务插入的数据的
    radiocontroller
        3
    radiocontroller  
       2021-02-05 10:56:46 +08:00
    @radiocontroller RR 隔离级别下是读取不到其他事务插入的数据的,这里是快照读。那为什么还需要 next-key lock 算法加锁来阻止其他事务的插入呢,这里是当前读
    bringyou
        4
    bringyou  
       2021-02-05 10:59:06 +08:00
    我感觉是为了解决幻读
    xixihaha1
        5
    xixihaha1  
       2021-02-05 11:00:06 +08:00
    mvcc 可以解决“快照读”的幻读问题,但是解决不了“当前读”的幻读问题
    whatevers
        6
    whatevers  
    OP
       2021-02-05 11:00:57 +08:00
    @XiLemon @radiocontroller 恍然大悟,忽略了读的上下文,多谢两位大佬
    awanganddong
        7
    awanganddong  
       2021-02-05 11:37:04 +08:00
    备注下:

    当前读
    当前读是基于 临键锁(行锁 + 间歇锁)来实现的,适用于 insert,update,delete,select ... for update,select ... lock in share mode 语句,以及加锁了的 select 语句。

    更新数据时,都是先读后写,而这个读,就是当前读。读取数据时,读取该条数据的已经提交的最新的事务,生成的 readView 。
    YouLMAO
        8
    YouLMAO  
       2021-02-05 14:52:16 +08:00
    like share and Subscribe
    zzkde
        9
    zzkde  
       2021-02-06 14:16:50 +08:00
    low_limit_id 指的不是系统中活跃事务的最大 ID,应该是系统要生成的下一个事务 ID 。可以试想这种情况:ReadView 创建时,系统中活跃的最大事务 ID 可能已经存在很久了,这期间也会提交事务(在 ReadView 创建时就已提交),这些提交了的事务应该是可见的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   991 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 20:15 · PVG 04:15 · LAX 12:15 · JFK 15:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.