mysql數據庫的默認隔離級別爲什麼是可重複讀

 

目錄

一 mysql的主從複製

二 當mysql數據庫的隔離級別爲“讀提交”時:

三 當mysql默認隔離級別爲可重複讀時

總結:


一 mysql的主從複製

  • 1 主服務器上面的任何操作都會通過自己的 I/O tread(I/O 線程)保存在二進制日誌 Binary log 裏面。

  • 2 從服務器上面也啓動一個 I/O thread,通過配置好的用戶名和密碼, 連接到主服務器上面請求讀取二進制日誌,然後把讀取到的二進制日誌寫到本地的一個Realy log(中繼日誌)裏面。

  • 3 從服務器上面同時開啓一個 SQL thread 定時檢查 Realy log(這個文件也是二進制的),如果發現有更新立即把更新的內容在本機的數據庫上面執行一遍。(鏈接:https://www.jianshu.com/p/faf0127f1cb2)

二 當mysql數據庫的隔離級別爲“讀提交”時:

首先通過命令,查詢一下默認隔離級別。

show variables like 'transaction_isolation';

設置session隔離級別爲“讀提交”

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

在讀提交的隔離級別下開啓兩個會話:按上面的順序執行命令。最後得到的數據庫中有一條記錄。

在mysql5.1以前mysql的邏輯操作日誌binlog默認的是statement模式,用於恢復和複製。主從複製的binlog的採用的事statement方式。主庫就是將每次數據庫的sql修改(增刪改)在提交前以二進制編碼的形式保存到日誌文件中。從庫定時從主庫的日誌文件複製到本地日誌,從庫根據本地日誌(繼中日誌)的變化執行sql語句。


根據上面的情況,當命令提交前,纔會向日志文件中寫入。所以日誌文件的sql語句順序是先增加後刪除,所以在從庫中數據庫是沒有數據的。而主庫中有數據,這就造成了主從不一致的問題。

mysql5.1的binlog又提供了兩種格式row、和fixed。mysql會根據情況擇優選擇使用哪種格式。就算是這樣也不能避免主從不一致的問題。就像前面的例子如果刪除大量數據的時候保存binlog日誌採用statement格式,未提交;插入大量數據的時候也採用了statement。(爲什麼採用statement格式,可看推薦文章《mysql主服務器 binlog_format 的 statement,row, mixed 三種格式對比。》),那麼就可能造成主從不一致的問題。只有將修改的語句串行化才能解決這個問題。將隔離級別提升爲可重複讀就能將寫入binlog的語句串行化。從庫是根據binlog日誌執行了的。binlog保證了與主庫相同的執行順序,那麼也就保證了主從的一致性。

三 當mysql默認隔離級別爲可重複讀時

開啓兩個會話,左邊爲session1,右邊爲session2,按數字所示順序執行。

隔離級別設爲可重複讀(Repeatable Read),在該隔離級別下引入間隙鎖。當Session 1執行delete語句時,會鎖住間隙。那麼,Ssession 2執行插入語句就會阻塞住,無法繼續執行。只有到session1 提交(commit)了之後。才能執行。實現了寫入binlog的語句串行化。解決了主從不一致的問題。

總結:

MySQL使用可重複讀來作爲默認隔離級別的主要原因是語句級的Binlog。可重複讀能提供SQL語句的寫可串行化,保證了主從一致。

個人的見解,如有問題,歡迎指正。

參考文章:

爲什麼mysql默認隔離級別設置爲可重複讀 

mysql主服務器 binlog_format 的 statement,row, mixed 三種格式對比。(通俗易懂)

MySQL使用可重複讀作爲默認隔離級別的原因

發佈了118 篇原創文章 · 獲贊 78 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章