MySQL -update語句流程總結

努力的碼農發表於2019-03-04

廢話不多說先來張圖解釋

update T set value = value+1 where ID =2
複製程式碼

MySQL -update語句流程總結

我想可能大部分人看完這圖,思考片刻,接下來的就不需要在繼續看了,但是考慮到部分朋友還是新手(包括自己)以及後面複習,還是稍微嘮叨一段。

update過程

首先,上圖中深色背景的表示在執行器中執行,也就是Server層,淺色的是在InnoDB引擎中執行。
由於很多朋友並不是專業的DBA或者對MySQL內部原理並不是特別清晰,所以先對redologbinlog做簡單的介紹。

  • redolog

    重做日誌,屬於物理日誌,上面儲存的是資料庫中最終的內容,有固定的大小,可以迴圈讀寫,一般設定innodb_flush_log_at_trx_commit為1,表示commit事務時將redolog上面的資料刷入到磁碟(具體的可以自行研究redolog file 和redolog buffer)。具有兩個狀態分別是preparecommit,在MySQL重啟恢復時會根據commit狀態恢復資料。

  • binlog

    歸檔日誌,屬於邏輯日誌,上面儲存的是最初的修改邏輯可以簡單的理解為sql語句,可以追加寫,一般設定sync_binlog為1,表示commit事務時將binlog上面的資料刷入到磁碟進行歸檔。資料恢復和同步都是通過binlog來實現的。

下面以文字的方式再次描述一下update T set value = value+1 where ID =2的過程。

  1. 詞法分析器識別出事update語句;
  2. 執行器去InnoDB中進行查詢,找到滿足ID = 2 的資料;
  3. 執行器將value的值加1;
  4. 執行器讓InnoDB將剛剛的新值寫入到InnoDB的記憶體中;
  5. InnoDB在redolog中加入一條記錄,並把該記錄的狀態設定為prepare;
  6. 執行器經“update T set value = value+1 where ID =2” 寫入到binlog中;
  7. 此時提交事務,將redolog中prepare的的記錄狀態設為commit,並且將記憶體中的新資料刷入磁碟。

以上就是比較簡單的過程理解,那麼為啥要分開寫redolog呢?即傳說中的兩階段提交?這裡再做個簡單的分析。

首先對這種方式的好處做個總結:保證以上所有的過程如果出現MySQL例項奔潰都不會導致事務的丟失或異常。

接下來分析一下這麼做的具體原因:

  1. 如果是第5步之前crash,就是還沒寫任何日誌,那麼事務就不存在,在恢復後從redolog和binlog中都不會有任何的問題;
  2. 如果寫完redolog 的prepare出現了crash,那麼恢復時,通過redolog和binlog的對比,會發現只要一個prepare的日誌,那麼會將事務進行回滾,保證redolog和binlog的統一;
  3. 如果寫完binlog後出現crash,那麼恢復時,會進行根據binlog日誌對redolog進行補償,對redolog之前prepare的記錄修改為commit狀態,事務得到保證;
  4. 最後commit後crash,redolog和binlog都是正常的。

redolog只出現在InnDB中,而且是迴圈寫的,不能持久儲存,所以暫時不能用redolog來做主從或者資料備份

以上的是總結了很多部落格和書上的內容,並不是完全的原創,自己也是在整理,希望大家能指正不對之處。

相關文章