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語句的寫可串行化,保證了主從一致。

 

參考文章:https://blog.csdn.net/zhangyingjie09/article/details/103484181


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM