mysql 為什麼很多網際網路公司選擇了讀可提交

敖毛毛發表於2024-08-04

前言

在預設環境下,mysql 是可重複讀,為什麼預設可重複讀呢?

一般情況下感覺讀可提交就行,可重複讀解決幻讀的問題,但是大多情況下沒有幻讀的問題,所以也沒有必要可重複讀。

那麼為什麼mysql 要把預設配置設定為可重複讀呢?

正文

歷史原因:

這種圖,如果是在可提交讀的情況下,會發生什麼呢?

當執行完後,那麼進行查詢:

那麼在從庫執行,那麼就是:

為什麼會這樣呢?因為binlog 記錄的是提交順序:首先session B 先提交的,那麼從庫執行的時候就會出現sessionB的語句再執行sessionA的語句。

這樣就造成了主從資料不一致的問題。

那麼這個問題是否能解決呢?如果這個問題不解決,那麼可提交讀這個是否就沒法做主從了。

這就不得不提及一下binary log,簡稱bin log了。

現在bin log 有三種格式:

  1. statement

  2. row

  3. mixed

  4. Statement-based replication (SBR): 在SBR中,MySQL伺服器將每個執行的SQL語句記錄到binlog中。當從主伺服器複製到從伺服器時,從伺服器會執行相同的SQL語句來保持資料同步。這種方法簡單且高效,但可能會導致一些複製不一致的問題。

  5. Row-based replication (RBR): 在RBR中,MySQL伺服器將每次資料更改的行的副本記錄到binlog中。當從主伺服器複製到從伺服器時,從伺服器會根據這些行的副本來進行相同的資料更改。這種方法可以確保資料一致性,但會增加binlog的大小。

  6. Mixed-based replication (MBR): MBR結合了SBR和RBR的優點。MySQL伺服器根據情況選擇使用SBR或RBR來記錄binlog。通常對於不同型別的SQL語句會採用不同的複製方式,以達到效率和資料一致性的平衡。

之所以產生問題呢? 那麼就是由於第一種,因為儲存的是sql 語句,那麼執行的就是sql語句了,順序不同,那麼結果就不同了。

那麼要解決這個問題呢? 可以使用row這種模式,這種模式就是將資料的結果寫下來,那麼同步過去也就是從新同步資料了,也就是同步結果,這個時候就沒有問題。

那麼這個時候應該也是有更多的開銷的,因為row要把結果記錄下了,那麼肯定是需要更多的磁碟io和磁碟空間了。

但是網際網路公司依然選擇讀提交的原因是什麼呢?

  1. 原因一就是間隙鎖的問題,因為存在間隙鎖,那麼死鎖機率就大,同樣的間隙鎖的原因,鎖的範圍就大了。

  2. 再rr隔離級別下面,沒有命中的索引會鎖表:

update test set color = 'blue' where color = 'white'; 

試想一下update 要避免color = 'white' 被插入,這個時候只能鎖表了。

而讀提交,那麼就只會鎖住兩行:

主要的原因是因為讀提交的鎖範圍,併發高,然後需要可重複讀場景中的解決幻讀問題的比較少。

下一節mvcc。

相關文章