MySQL 為什么需要兩階段提交?

      網友投稿 876 2025-04-04

      文章目錄


      1. 什么是兩階段提交

      1.1 binlog 與 redolog

      binlog

      redo log

      1.2 兩階段提交

      2. 為什么需要兩階段提交

      3. 小結

      小伙伴們知道,Mysql 中的事務是兩階段提交,我們見到的很多分布式事務也都是兩階段提交的,例如 Seata,那么為什么要兩階段提交呢?一次直接提交了不行嗎?今天我們來聊聊這個話題。

      關于分布式事務 seata,不懂的小伙伴可以參考松哥之前的文章,傳送門:

      五分鐘帶你體驗一把分布式事務!so easy!

      看了那么多博客,還是不懂 TCC,不妨看看這個案例!

      XA 事務水很深,小伙子我怕你把握不住!

      你這 Saga 事務保“隔離性”嗎?

      1. 什么是兩階段提交

      1.1 binlog 與 redolog

      binlog 我們中文一般稱作歸檔日志,如果大家看過松哥之前發的 Mysql 主從搭建,應該對這個日志有印象,當我們搭建 MySQL 主從的時候就離不開 binlog(傳送門:MySQL8 主從復制踩坑指南)。

      binlog 是 MySQL Server 層的日志,而不是存儲引擎自帶的日志,它記錄了所有的 DDL 和 DML(不包含數據查詢語句)語句,而且是以事件形式記錄,還包含語句所執行的消耗的時間等,需要注意的是:

      binlog 是一種邏輯日志,他里邊所記錄的是一條 SQL 語句的原始邏輯,例如給某一個字段 +1,注意這個區別于 redo log 的物理日志(在某個數據頁上做了什么修改)。

      binlog 文件寫滿后,會自動切換到下一個日志文件繼續寫,而不會覆蓋以前的日志,這個也區別于 redo log,redo log 是循環寫入的,即后面寫入的可能會覆蓋前面寫入的。

      一般來說,我們在配置 binlog 的時候,可以指定 binlog 文件的有效期,這樣在到期后,日志文件會自動刪除,這樣避免占用較多存儲空間。

      根據 MySQL 官方文檔的介紹,開啟 binlog 之后,大概會有 1% 的性能損耗,不過這還是可以接受的,一般來說,binlog 有兩個重要的使用場景:

      MySQL 主從復制時:在主機上開啟 binlog,主機將 binlog 同步給從機,從機通過 binlog 來同步數據,進而實現主機和從機的數據同步。

      MySQL 數據恢復,通過使用 mysqlbinlog 工具再結合 binlog 文件,可以將數據恢復到過去的某一時刻。

      前面我們說的 binlog 是 MySQL 自己提供的,在 MySQL 的 server 層,而 redo log 則不是 MySQL 提供的,是存儲引擎 InnoDB 自己提供的。所以在 MySQL 中就存在兩類日志 binlog 和 redo log,存在兩類日志既有歷史原因(InnoDB 最早不是 MySQL 官方存儲引擎)也有技術原因,這個咱們以后再細聊。

      我們都知道,事務的四大特性里面有一個是持久性,即只要事務提交成功,那么對數據庫做的修改就被永久保存下來了,寫到磁盤中了,怎么做到的呢?其實我們很容易想到是在每次事務提交的時候,將該事務涉及修改的數據頁全部刷新到磁盤中,一旦寫到磁盤中,就不怕數據丟失了。

      但是要是每次都這么搞,數據庫就不知道慢到哪里去了!因為 Innodb 是以頁為單位進行磁盤交互的,而一個事務很可能只修改一個數據頁里面的幾個字節,這個時候將完整的數據頁刷到磁盤的話,不僅效率低,也浪費資源。效率低是因為這些數據頁在物理上并不連續,將數據頁刷到磁盤會涉及到隨機 IO。

      有鑒于此,MySQL 設計了 redo log,在 redo log 中只記錄事務對數據頁做了哪些修改。那有人說,寫 redo log 不就是磁盤 IO 嗎?而寫數據到磁盤也是磁盤 IO,既然都是磁盤 IO,那干嘛不把直接把數據寫到磁盤呢?還費這事!

      此言差矣。

      寫 redo log 跟寫數據有一個很大的差異,那就是 redo log 是順序 IO,而寫數據涉及到隨機 IO,寫數據需要尋址,找到對應的位置,然后更新/添加/刪除,而寫 redo log 則是在一個固定的位置循環寫入,是順序 IO,所以速度要高于寫數據。

      redo log 本身又分為:

      日志緩沖(redo log buffer),該部分日志是易失性的。

      重做日志(redo log file),這是磁盤上的日志文件,該部分日志是持久的。

      MySQL 每執行一條 DML 語句,先將記錄寫入 redo log buffer,后續在某個時間點再一次性將多個操作記錄寫到 redo log file,這種先寫日志再寫磁盤的技術就是 MySQL 里經常說到的 WAL(Write-Ahead Logging) 技術(預寫日志)。

      1.2 兩階段提交

      在 MySQL 中,兩階段提交的主角就是 binlog 和 redolog,我們來看一個兩階段提交的流程圖:

      從上圖中可以看出,在最后提交事務的時候,有 3 個步驟:

      寫入 redo log,處于 prepare 狀態。

      寫 binlog。

      修改 redo log 狀態變為 commit。

      由于 redo log 的提交分為 prepare 和 commit 兩個階段,所以稱之為兩階段提交。

      2. 為什么需要兩階段提交

      如果沒有兩階段提交,那么 binlog 和 redolog 的提交,無非就是兩種形式:

      先寫 binlog 再寫 redolog。

      先寫 redolog 再寫 binlog。

      這兩種情況我們分別來看。

      假設我們要向表中插入一條記錄 R,如果是先寫 binlog 再寫 redolog,那么假設 binlog 寫完后崩潰了,此時 redolog 還沒寫。那么重啟恢復的時候就會出問題:binlog 中已經有 R 的記錄了,當從機從主機同步數據的時候或者我們使用 binlog 恢復數據的時候,就會同步到 R 這條記錄;但是 redolog 中沒有關于 R 的記錄,所以崩潰恢復之后,插入 R 記錄的這個事務是無效的,即數據庫中沒有該行記錄,這就造成了數據不一致。

      相反,假設我們要向表中插入一條記錄 R,如果是先寫 redolog 再寫 binlog,那么假設 redolog 寫完后崩潰了,此時 binlog 還沒寫。那么重啟恢復的時候也會出問題:redolog 中已經有 R 的記錄了,所以崩潰恢復之后,插入 R 記錄的這個事務是有效的,通過該記錄將數據恢復到數據庫中;但是 binlog 中還沒有關于 R 的記錄,所以當從機從主機同步數據的時候或者我們使用 binlog 恢復數據的時候,就不會同步到 R 這條記錄,這就造成了數據不一致。

      那么按照前面說的兩階段提交就能解決問題嗎?

      我們來看如下三種情況:

      **情況一:**一階段提交之后崩潰了,即寫入 redo log,處于 prepare 狀態 的時候崩潰了,此時:

      由于 binlog 還沒寫,redo log 處于 prepare 狀態還沒提交,所以崩潰恢復的時候,這個事務會回滾,此時 binlog 還沒寫,所以也不會傳到備庫。

      **情況二:**假設寫完 binlog 之后崩潰了,此時:

      redolog 中的日志是不完整的,處于 prepare 狀態,還沒有提交,那么恢復的時候,首先檢查 binlog 中的事務是否存在并且完整,如果存在且完整,則直接提交事務,如果不存在或者不完整,則回滾事務。

      MySQL 為什么需要兩階段提交?

      **情況三:**假設 redolog 處于 commit 狀態的時候崩潰了,那么重啟后的處理方案同情況二。

      由此可見,兩階段提交能夠確保數據的一致性。

      3. 小結

      好啦,今天和小伙伴們簡單聊了一下 MySQL 中的兩階段提交,有問題歡迎留言討論。

      MySQL 數據庫

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:訂餐系統解決方案(14秒之前已更新)
      下一篇:wps2019怎么自動備份文檔到云端?
      相關文章
      亚洲短视频男人的影院| 亚洲手机中文字幕| 亚洲卡一卡二卡乱码新区| 中文字幕亚洲综合精品一区| 久久久久亚洲AV成人网人人软件| 亚洲成a人片在线观看日本麻豆| 亚洲av日韩专区在线观看| 亚洲第一第二第三第四第五第六 | 亚洲午夜成人精品无码色欲| 亚洲乱码日产精品BD在线观看| 91亚洲精品第一综合不卡播放| 亚洲色图综合网站| 亚洲成a人片毛片在线| 亚洲国产成人久久| 亚洲欧洲日韩在线电影| 亚洲成AV人片久久| 亚洲AV无码乱码在线观看代蜜桃| 亚洲一区二区三区精品视频 | 亚洲一区二区三区亚瑟| 亚洲av无码一区二区三区观看| 亚洲a∨无码男人的天堂| 国产91在线|亚洲| 亚洲精品国产摄像头| 亚洲Av无码国产一区二区| 成人精品国产亚洲欧洲| 亚洲最大av无码网址| 亚洲人成精品久久久久| 久久精品亚洲一区二区| 亚洲精品不卡视频| 国产成人精品日本亚洲网址| 亚洲AV一区二区三区四区| 成人伊人亚洲人综合网站222| 亚洲一区无码精品色| 亚洲午夜久久久久妓女影院| 国产V亚洲V天堂A无码| 亚洲高清中文字幕综合网| 亚洲一区二区三区91| 亚洲av永久无码精品秋霞电影秋| 国产AV无码专区亚洲AV琪琪| 中文国产成人精品久久亚洲精品AⅤ无码精品| 亚洲日韩av无码|