前言
在預設環境下,mysql 是可重複讀,為什麼預設可重複讀呢?
一般情況下感覺讀可提交就行,可重複讀解決幻讀的問題,但是大多情況下沒有幻讀的問題,所以也沒有必要可重複讀。
那麼為什麼mysql 要把預設配置設定為可重複讀呢?
正文
歷史原因:
這種圖,如果是在可提交讀的情況下,會發生什麼呢?
當執行完後,那麼進行查詢:
那麼在從庫執行,那麼就是:
為什麼會這樣呢?因為binlog 記錄的是提交順序:首先session B 先提交的,那麼從庫執行的時候就會出現sessionB的語句再執行sessionA的語句。
這樣就造成了主從資料不一致的問題。
那麼這個問題是否能解決呢?如果這個問題不解決,那麼可提交讀這個是否就沒法做主從了。
這就不得不提及一下binary log,簡稱bin log了。
現在bin log 有三種格式:
-
statement
-
row
-
mixed
-
Statement-based replication (SBR): 在SBR中,MySQL伺服器將每個執行的SQL語句記錄到binlog中。當從主伺服器複製到從伺服器時,從伺服器會執行相同的SQL語句來保持資料同步。這種方法簡單且高效,但可能會導致一些複製不一致的問題。
-
Row-based replication (RBR): 在RBR中,MySQL伺服器將每次資料更改的行的副本記錄到binlog中。當從主伺服器複製到從伺服器時,從伺服器會根據這些行的副本來進行相同的資料更改。這種方法可以確保資料一致性,但會增加binlog的大小。
-
Mixed-based replication (MBR): MBR結合了SBR和RBR的優點。MySQL伺服器根據情況選擇使用SBR或RBR來記錄binlog。通常對於不同型別的SQL語句會採用不同的複製方式,以達到效率和資料一致性的平衡。
之所以產生問題呢? 那麼就是由於第一種,因為儲存的是sql 語句,那麼執行的就是sql語句了,順序不同,那麼結果就不同了。
那麼要解決這個問題呢? 可以使用row這種模式,這種模式就是將資料的結果寫下來,那麼同步過去也就是從新同步資料了,也就是同步結果,這個時候就沒有問題。
那麼這個時候應該也是有更多的開銷的,因為row要把結果記錄下了,那麼肯定是需要更多的磁碟io和磁碟空間了。
但是網際網路公司依然選擇讀提交的原因是什麼呢?
-
原因一就是間隙鎖的問題,因為存在間隙鎖,那麼死鎖機率就大,同樣的間隙鎖的原因,鎖的範圍就大了。
-
再rr隔離級別下面,沒有命中的索引會鎖表:
update test set color = 'blue' where color = 'white';
試想一下update 要避免color = 'white' 被插入,這個時候只能鎖表了。
而讀提交,那麼就只會鎖住兩行:
主要的原因是因為讀提交的鎖範圍,併發高,然後需要可重複讀場景中的解決幻讀問題的比較少。
結
下一節mvcc。