對(duì)“幻讀”做一個(gè)說(shuō)明:
- 在可重復(fù)讀隔離級(jí)別下,普通的查詢(xún)是快照讀溪椎,是不會(huì)看到別的事務(wù)插入的數(shù)據(jù)的。因此恬口,幻讀在“當(dāng)前讀”下才會(huì)出現(xiàn)校读。
- 上面session B的修改結(jié)果,被session A之后的select語(yǔ)句用“當(dāng)前讀”看到祖能,不能稱(chēng)為幻讀歉秫。幻讀僅專(zhuān)指“新插入的行”。
產(chǎn)生幻讀的原因是养铸,行鎖只能鎖住行雁芙,但是新插入記錄這個(gè)動(dòng)作,要更新的是記錄之間的“間隙”钞螟。因此兔甘,為了解決幻讀問(wèn)題,InnoDB只好引入新的鎖鳞滨,也就是間隙鎖(Gap Lock)洞焙。
跟行鎖有沖突關(guān)系的是“另外一個(gè)行鎖”。
但是間隙鎖不一樣拯啦,跟間隙鎖存在沖突關(guān)系的澡匪,是“往這個(gè)間隙中插入一個(gè)記錄”這個(gè)操作。間隙鎖之間都不存在沖突關(guān)系褒链。
間隙鎖和行鎖合稱(chēng)next-key lock唁情,每個(gè)next-key lock是前開(kāi)后閉區(qū)間。也就是說(shuō)碱蒙,我們的表t初始化以后荠瘪,如果用select * from t for update要把整個(gè)表所有記錄鎖起來(lái),就形成了7個(gè)next-key lock赛惩,分別是 (-∞,0]哀墓、(0,5]、(5,10]喷兼、(10,15]篮绰、(15,20]、(20, 25]季惯、(25, +suprenum]吠各。
間隙鎖的引入臀突,可能會(huì)導(dǎo)致同樣的語(yǔ)句鎖住更大的范圍,這其實(shí)是影響了并發(fā)度的贾漏。
間隙鎖是在可重復(fù)讀隔離級(jí)別下才會(huì)生效的候学。所以,你如果把隔離級(jí)別設(shè)置為讀提交的話纵散,就沒(méi)有間隙鎖了梳码。
要解決可能出現(xiàn)的數(shù)據(jù)和日志不一致問(wèn)題,需要把binlog格式設(shè)置為row伍掀。這掰茶,也是現(xiàn)在不少公司使用的配置組合。
其實(shí)我想說(shuō)的是蜜笤,配置是否合理濒蒋,跟業(yè)務(wù)場(chǎng)景有關(guān),需要具體問(wèn)題具體分析
如果讀提交隔離級(jí)別夠用把兔,也就是說(shuō)沪伙,業(yè)務(wù)不需要可重復(fù)讀的保證,這樣考慮到讀提交下操作數(shù)據(jù)的鎖范圍更邢睾谩(沒(méi)有間隙鎖)焰坪,這個(gè)選擇是合理的。
讀提交隔離級(jí)別加binlog_format=row的組合聘惦。
Q1: 大家都用讀提交某饰,可是邏輯備份的時(shí)候,mysqldump為什么要把備份線程設(shè)置成可重復(fù)讀呢善绎?