15.幻讀是什么?幻讀有什么問(wèn)題2022-03-02

一、幻讀是什么?

在MySQL的隔離級(jí)別RR下,幻讀是指讀到了新增的數(shù)據(jù)。

1.幻讀問(wèn)題一:只給某一行加鎖

for update就會(huì)給該條sql加上行鎖,但是一定就不會(huì)有問(wèn)題了嗎?


問(wèn)題一

統(tǒng)一放一起就是這樣的

update t set d=5 where id=0; /*(0,0,5)*/
update t set c=5 where id=0; /*(0,5,5)*/

insert into t values(1,1,5); /*(1,1,5)*/
update t set c=5 where id=1; /*(1,5,5)*/

update t set d=100 where d=5;/*所有d=5的行,d改成100*/

原因:“select * from t where d=5 for update 這條語(yǔ)句只給 d=5 這一行,也就是 id=5 的這一行加鎖”導(dǎo)致的。

2.幻讀問(wèn)題二:新增的加不了鎖
問(wèn)題二

可以看到,按照日志順序執(zhí)行,id=0 這一行的最終結(jié)果也是 (0,5,5)。所以,id=0 這一行的問(wèn)題解決了。但同時(shí)你也可以看到,id=1 這一行,在數(shù)據(jù)庫(kù)里面的結(jié)果是 (1,5,5),而根據(jù) binlog 的執(zhí)行結(jié)果是 (1,5,100),也就是說(shuō)幻讀的問(wèn)題還是沒有解決。為什么我們已經(jīng)這么“兇殘”地,把所有的記錄都上了鎖,還是阻止不了 id=1 這一行的插入和更新呢?原因很簡(jiǎn)單。在 T3 時(shí)刻,我們給所有行加鎖的時(shí)候,id=1 這一行還不存在,不存在也就加不上鎖。
也就是說(shuō),即使把所有的記錄都加上鎖,還是阻止不了新插入的記錄

二、怎么解決幻讀?

用間隙鎖(Gap lock)+行鎖
間隙鎖和行鎖合稱 next-key lock,是一個(gè)左開右閉區(qū)間。
例如:0,5,6三行分別是 (-∞,0]、(0,5]、(5,6]、(6, +supremum]。
間隙鎖之間的兼容關(guān)系是怎樣的?
在同時(shí)插入不存在的行時(shí),關(guān)系如下

image.png

三、next-key lock一定是安全的嗎?

不一定,因?yàn)槿绻瑫r(shí)對(duì)一個(gè)間隙進(jìn)行插入操作的時(shí)候可能會(huì)出現(xiàn)死鎖,間隙鎖只存在可重復(fù)讀的隔離級(jí)別下。

四、讀提交+把binlog的格式改成row

binlog_format=row

1.這樣會(huì)有問(wèn)題嗎?
2.在備份期間,備份線程用的是可重復(fù)讀,而業(yè)務(wù)線程用的是讀提交。同時(shí)存在兩種事務(wù)隔離級(jí)別,會(huì)不會(huì)有問(wèn)題?
3.這兩個(gè)不同的隔離級(jí)別現(xiàn)象有什么不一樣的,關(guān)于我們的業(yè)務(wù),“用讀提交就夠了”這個(gè)結(jié)論是怎么得到的?

五、思考題

思考題

如果你之前沒有了解過(guò)本篇文章的相關(guān)內(nèi)容,一定覺得這三個(gè)語(yǔ)句簡(jiǎn)直是風(fēng)馬牛不相及。但實(shí)際上,這里 session B 和 session C 的 insert 語(yǔ)句都會(huì)進(jìn)入鎖等待狀態(tài)。你可以試著分析一下,出現(xiàn)這種情況的原因是什么?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容