MySQL中隔離級別的使用詳解
引言
在MySQL中,事務(wù)隔離級別和二進(jìn)制日志(binlog)的格式密切相關(guān),直接影響數(shù)據(jù)的一致性和復(fù)制的正確性。
尤其是在“已提交讀”(Read Committed)隔離級別下,由于沒有使用間隙鎖,某些并發(fā)操作在執(zhí)行過程中不會產(chǎn)生阻塞,但在采用基于語句(statement-based)的binlog格式時,可能導(dǎo)致主從復(fù)制中數(shù)據(jù)順序和一致性的問題。
例如,某些事務(wù)雖然在執(zhí)行順序上先后提交,但在binlog中記錄的順序未必反映真實執(zhí)行順序,進(jìn)而引發(fā)數(shù)據(jù)異常刪除等情況。
本文將圍繞已提交讀隔離級別與statement格式binlog的兼容性問題展開探討,揭示其潛在風(fēng)險及影響,幫助讀者更好地理解MySQL事務(wù)隔離與復(fù)制機制的細(xì)節(jié)。
undo log的作用
- 事務(wù)發(fā)生錯誤時回滾rollback,數(shù)據(jù)更新之前,會把原始數(shù)據(jù)保存在undo log中,保證事務(wù)出錯回滾或者我們手動回滾的時候,能夠在undo log中找到最初的數(shù)據(jù)。
- 提供了MVCC的非鎖定讀(快照讀),依賴undo log實現(xiàn)。
MVCC的實現(xiàn)有以下幾個重要因素
- 數(shù)據(jù)行的兩個隱藏字段,db_trx_id(事務(wù)id)、db_roll_ptr(回滾指針),回滾指針指向拷貝的undo log副本記錄。

- 活躍事務(wù)數(shù)組,針對可重復(fù)讀隔離級別,活躍事務(wù)列表是在事務(wù)啟動瞬間,當(dāng)前正在“活躍”的所有事務(wù) ID,也即事務(wù)啟動瞬間未提交的事務(wù)。
- 活躍事務(wù)數(shù)組最小值為低水位,活躍事務(wù)數(shù)組最大值加1為高水位。
例如:
活躍事務(wù)數(shù)組:【20,23,31】,低水位:20,高水位:32。
如何根據(jù)這些因素判斷數(shù)據(jù)值?
已數(shù)據(jù)行的db_trx_id為起始點,延著回滾鏈取出db_trx_id按照下面規(guī)則判斷是否可見,直到找到可見的數(shù)據(jù)才停止查找:
- db_trx_id <= 低水位,表示當(dāng)前事務(wù)早已經(jīng)提交,可見。
- db_trx_id >= 高水位,表示當(dāng)前事務(wù)還未提交,不可見。
- db_trx_id能在活躍事務(wù)列表找到,表示當(dāng)前事務(wù)還未提交,不可見。
- db_trx_id不能在活躍事務(wù)列表找到,表示當(dāng)前事務(wù)已提交,可見。
可重復(fù)讀和已提交讀區(qū)別?
可重復(fù)讀是在事務(wù)啟動時創(chuàng)建視圖,已提交讀是在每條查詢SQL執(zhí)行時創(chuàng)建視圖。
視圖主要是用于記錄活躍(未提交)的事務(wù)ID列表。
串行化隔離級別的實現(xiàn)
讀的時候加共享鎖,也就是其他事務(wù)可以并發(fā)讀,寫的時候加排它鎖,其他事務(wù)不能并發(fā)寫也不能并發(fā)讀。
幻讀和可重復(fù)讀的區(qū)別?
都是在一個事務(wù)內(nèi)用相同的條件查詢兩次,但兩次的結(jié)果不一樣。差異在于,對不可重復(fù)讀來說,第二次的結(jié)果集相對第一次,有些記錄被修改(Update)或刪除(Delete)了。而幻讀是第二次結(jié)果集里出現(xiàn)了第一次結(jié)果集沒有的記錄(Insert)。
一個更加形象的說法,幻讀是在第一次結(jié)果集的記錄“間隙”中增加了新的記錄。所以,MySQL將防止出現(xiàn)幻讀在可重復(fù)讀隔離級別下新增了間隙鎖(GapLock)。
為什么已提交讀隔離級別不能和statement格式binlog一起使用?
由于已提交讀隔離級別沒有間隙鎖,下面SQL不會存在阻塞。
tx1 begin; tx1 delete id>5 and id<10; tx2 begin; tx2 insert into values(6)(7); tx2 commit; tx1 commit;
tx2先提交到binlog,tx1后提交到binlog,binlog按照順序執(zhí)行日志時,會把[6, 7]兩行數(shù)據(jù)也刪除掉。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
MySql總彈出mySqlInstallerConsole窗口的解決方法
這篇文章主要介紹了MySql總彈出mySqlInstallerConsole窗口的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-09-09
mysql ERROR 1045 (28000)問題的解決方法
這篇文章主要介紹了mysql ERROR 1045 (28000)問題的解決方法,文中步驟介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-10-10

