聊一聊 MySQL 中的數據編輯過程當中涉及的兩階段提交

MySQL 數據庫中的兩階段提交,不知道您知道不?這篇文章就簡單的聊一聊 MySQL 數據庫中的兩階段提交,兩階段提交發生在數據變動期間(更新、刪除、新增等),兩階段提交過程當中涉及到了 MySQL 數據庫中的兩個日誌系統:redo 日誌和 binlog 文件mysql

redo 日誌前面已經介紹過了,就再也不介紹了,簡單的聊一聊 binlog 文件,binlog 是 MySQL server 層提供的二進制文件,所以全部的存儲引擎均可以使用 binlog 功能,binlog 是追加寫的邏輯日誌,記錄了執行語句的原始邏輯,文件寫到指定大小後會切換到下一個文件繼續寫,並不會覆蓋之前寫過的日誌文件sql

binlog 日誌文件主要用於數據恢復和集羣環境下各服務器之間的數據同步,在工做中,咱們誤刪了數據或者表之類,若是須要恢復的話都是利用 binlog 日誌來恢復的,因此 binlog 日誌是 MySQL 數據庫中比較重要的模塊。數據庫

知道這兩個日誌以後,咱們把重點回到 MySQL 數據庫兩階段提交,前面咱們說了兩階段提交發生在數據變動期間,爲了更好的理解兩階段提交,咱們用一條更新命令來加以說明,更新語句以下:服務器

mysql> update T set c=c+1 where id=2;
複製代碼

假設未更新前 id=2 的這行數據 c 的值爲 0 ,這條更新語句在 MySQL 數據庫內部是如何執行的呢?在下面這張執行流程圖:微信

update 語句執行流程

從流程圖中能夠看出,在 InnoDB 存儲引擎下,一條 update 語句在 MySQL 內部執行大概會經歷下面五個步驟:學習

  • 一、執行器先找引擎取 id=2 這一行數據,若是 ID=2 這一行所在的數據頁原本就在內存中,就直接返回給執行器;不然,須要先從磁盤讀入內存,而後再返回spa

  • 二、執行器拿到引擎給的行數據,把這個值加上 1,好比原來是 N,如今就是 N+1,獲得新的一行數據,再調用引擎接口寫入這行新數據。日誌

  • 三、引擎將這行新數據更新到內存中,同時將這個更新操做記錄到 redo log 裏面,此時 redo log 處於 prepare 狀態。而後告知執行器執行完成了,隨時能夠提交事務code

  • 四、執行器生成這個操做的 binlog,並把 binlog 寫入磁盤。cdn

  • 五、執行器調用引擎的提交事務接口,引擎把剛剛寫入的 redo log 改爲提交(commit)狀態,更新完成。

在這五步中,注意用紅顏色標出來的部分,redo 日誌被分割成 prepare 和 commit 兩個階段提交,這個過程稱爲兩階段提交,不將 redo 日誌拆分紅兩步提交行不行?

咱們能夠用反推法來證實,假設不使用兩階段提交,那麼就有兩種狀況,一種是先提交 redo 日誌再提交 binlog 日誌,另外一種是先提交 binlog 日誌再提交 redo 日誌,一塊兒來看看這兩種提交方式有什麼問題?

先寫 redo log 後寫 binlog。假設在 redo log 寫完,binlog 尚未寫完的時候,MySQL 進程異常重啓。在這個過程當中更新發生了異常,redo 日誌是能夠在數據庫發生異常是保證數據的持久性,啓動後通過 redo 日誌數據恢復後 c 的值是 1,可是 binlog 並無寫完,因此在 binlog 日誌文件中並無記錄這條更新語句,若是用這個 binlog 日誌文件來恢復臨時庫的話,恢復出來 id =2 的這行數據的 c 的值爲 0,與原庫的值就不一致了。

先寫 binlog 後寫 redo log。若是在 binlog 寫完, redo 日誌還沒寫,系統崩潰,系統重啓後,id=2 的這行數據的 c 的值仍是爲 0,可是在 binlog 日誌文件中卻記錄了此次更新,若是須要用 binlog 日誌文件來恢復臨時庫的話,那麼 id=2 的這行數據 c 的值就爲 1,這樣與原庫的值就不一致了。

從這兩個假設中,咱們能夠看出不管先提交那個日誌文件都有可能出現數據不一致的現象,日誌文件兩階段提交技術就解決了redo 日誌和 binlog 日誌文件記錄數據不一致的問題,從而保證了在數據恢復時數據的一致性。

以上就是 MySQL 數據編輯中涉及到的兩階段提交,但願這篇文章對您的學習或者工做有所幫助,若是您以爲文章有幫助,歡迎幫忙轉發,謝謝。

最後

目前互聯網上不少大佬都有 MySQL 相關文章,若有雷同,請多多包涵了。原創不易,碼字不易,還但願你們多多支持。若文中有所錯誤之處,還望提出,謝謝。

歡迎掃碼關注微信公衆號:「互聯網平頭哥」,和平頭哥一塊兒學習,一塊兒進步。

互聯網平頭哥
相關文章
相關標籤/搜索