MySQL 可重复读隔离级别下是否解决了幻读问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
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
gotonull
V2EX    MySQL

MySQL 可重复读隔离级别下是否解决了幻读问题

  •  
  •   gotonull Jul 23, 2020 6459 views
    This topic created in 2110 days ago, the information mentioned may be changed or developed.

    MySQL 在默认的事务隔离级别下到底有没有解决幻读问题啊

    34 replies    2020-07-24 10:20:16 +08:00
    iseki
        1
    iseki  
       Jul 23, 2020 via Android
    没有吧
    zarte
        2
    zarte  
       Jul 23, 2020
    只是事务解决不了并发
    iseki
        3
    iseki  
       Jul 23, 2020 via Android
    你看看PostgreSQL…那个没有…有谓词锁
    pingdongyi
        4
    pingdongyi  
       Jul 23, 2020 via Android
    看如何定义幻读
    iseki
        5
    iseki  
       Jul 23, 2020 via Android
    @iseki 但是 pg 默认级别好象是读提交
    nwg
        6
    nwg  
       Jul 23, 2020
    插入类型的幻读解决不了 比如:预定会议室问题
    更新类别的幻读解决了 多次查询是一个数据
    xuwei0056
        7
    xuwei0056  
       Jul 23, 2020
    解决了
    BBCCBB
        8
    BBCCBB  
       Jul 23, 2020   2
    解决了, 有 gap lock.
    birdkyle79
        10
    birdkyle79  
       Jul 23, 2020   1
    解决了。

    在非锁定读的情况下会读取一个快照数据,不会出现幻读。

    在锁定读的情况下会有间隙锁,也不会出现幻读。

    PS:推荐看一看《 MySQL 技术内幕 InnoDB 存储引擎》
    RedBeanIce
        11
    RedBeanIce  
       Jul 23, 2020
    mvcc,间隙锁(书上看的)
    huntcool001
        12
    huntcool001  
       Jul 23, 2020   3
    没有完全解决.
    StackoverFlow 上这个例子: https://stackoverflow.com/questions/5444915/how-to-produce-phantom-reads

    create table ab(a int primary key, b int);

    Tx1:
    begin;
    select * from ab; // empty set

    Tx2:
    begin;
    insert into ab values(1,1);
    commit;
    Tx1:
    select * from ab; // empty set, expected phantom read missing.
    update ab set b = 2 where a = 1; // 1 row affected.
    select * from ab; // 1 row. phantom read here!!!!
    lscexpress
        13
    lscexpress  
       Jul 23, 2020
    幻读影响你业务吗?
    hheedat
        14
    hheedat  
       Jul 23, 2020
    解决了 MVCC + gap lock
    maigebaoer
        15
    maigebaoer  
       Jul 23, 2020 via Android
    并没有
    jimmyismagic
        16
    jimmyismagic  
       Jul 23, 2020
    默认并没有解决幻读,因为只锁了行,对于批量处理,你可能在删了一批符合条件的数据后,又读到新的符合条件的数据
    F281M6Dh8DXpD1g2
        17
    F281M6Dh8DXpD1g2  
       Jul 23, 2020 via iPhone
    没有
    新增的不会看到
    update 的会有问题
    gadsavesme
        18
    gadsavesme  
       Jul 23, 2020
    快照读解决,当前读还是有问题
    pangleon
        19
    pangleon  
       Jul 23, 2020
    MYSQL 用间隙锁解决幻读问题,结果间隙锁又会引起别的 BUG,所以 RR 级别很多公司都不推荐使用。都是用 RC 了,毕竟人家 ORACLE 就是默认 RC 有谁去改了么?
    gotonull
        20
    gotonull  
    OP
       Jul 23, 2020
    @lscexpress 没有,只是面试的时候被问到了,我说没解决,面试官说解决了。所以来问问大神们。结果大家的回答还是各种说法都有,都给我整懵了!
    zy445566
        21
    zy445566  
       Jul 23, 2020
    @gotonull 确实解决了,就是楼上说间隙锁,使用的时候通过 select +for update 锁定控制范围
    mahone3297
        22
    mahone3297  
       Jul 23, 2020
    极客时间,Mysql 的课有讲,解决了。
    20 | 幻读是什么,幻读有什么问题?
    zgzhang
        23
    zgzhang  
       Jul 23, 2020   2
    在快照读读情况下,mysql 通过 mvcc 来避免幻读。
    在当前读读情况下,mysql 通过 next-key 来避免幻读。
    select * from t where a=1;属于快照读
    select * from t where a=1 lock in share mode;属于当前读

    不能把快照读和当前读得到的结果不一样这种情况认为是幻读,这是两种不同的使用。所以我认为 mysql 的 rr 级别是解决了幻读的。
    https://github.com/Yhzhtk/note/issues/42
    gotonull
        24
    gotonull  
    OP
       Jul 23, 2020
    @mahone3297 谢谢,这就去学习学习
    dxyhymn
        25
    dxyhymn  
       Jul 23, 2020
    解决了,推荐去看书,看完你就知道了,而且很透彻。
    JasonLaw
        26
    JasonLaw  
       Jul 23, 2020
    @huntcool001 #12 +1,并没有完全解决。

    https://dev.mysql.com/doc/refman/8.0/en/innodb-consistent-read.html 中也描述了这个问题。在“The snapshot of the database state applies to SELECT statements within a transaction, not necessarily to DML statements.”这段里面。
    JasonLaw
        27
    JasonLaw  
       Jul 23, 2020
    其实我不太明白为什么这么多人都是在说 gap locking,文档里明明说的是 next-key locking 。

    https://dev.mysql.com/doc/refman/8.0/en/innodb-next-key-locking.html 中说了“To prevent phantoms, InnoDB uses an algorithm called next-key locking that combines index-row locking with gap locking.”,很明显,单纯的 gap locking 是不能阻止幻读的,index-row locking 加上 gap locking 才能够解决。
    JasonLaw
        28
    JasonLaw  
       Jul 23, 2020
    @pangleon #19 “间隙锁又会引起别的 BUG”,可以详细说明一下是什么 bug 吗?谢谢。
    pws22
        29
    pws22  
       Jul 23, 2020
    没有完全解决
    daimubai
        30
    daimubai  
       Jul 23, 2020 via iPhone
    确实使用的是 Next-lock-key 算法,它包含了 row lock 和 gap lock,默认情况下是解决了幻读的,不过不能完全避免吧,因为只会锁间隙,如果不在间隙添加也可以添加成功吧
    daimubai
        31
    daimubai  
       Jul 23, 2020 via iPhone
    MVCC 并没有解决幻读,而是解决了 RC 下的脏读和 RR 下的不可重复读
    wentaoliang
        32
    wentaoliang  
       Jul 23, 2020
    默认没有开启避免幻读,但是可以通过 for update 或者 share mode 来开启避免幻读。原理楼上以及说了
    freelancher
        33
    freelancher  
       Jul 24, 2020
    讲真。我看原理的时候就解决了。这个是在隔离特性里面。自己去看一下吧。
    leapV3
        34
    leapV3  
       Jul 24, 2020
    可重复读没有解决,需要加间隙锁
    About     Help     Advertise     Blog     API     FAQ     Solana     2433 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 81ms UTC 07:49 PVG 15:49 LAX 00:49 JFK 03:49
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86