MySQL Binlog 技術原理和業務應用案例分析
導語
本文將從實際應用角度出發理解 MySQL中的相關技術原理,從技術原理和工作實踐相結合,幫助大家以及在相關設計中存在的潛在問題,希望能給大家有所幫助和啟發,共同進步。
作者介紹:作者帆叔目前主要負責愛奇藝會員交易系統的技術和架構工作,專注非同步程式設計、服務治理、程式碼重構等領域,熱愛技術,樂於分享。
Binlog 是 MySQL 中一個很重要的日誌,主要用於 MySQL 主從間的資料同步複製。正是因為 Binlog 的這項功用,它也被用於 MySQL 向其它型別資料庫同步資料,以及業務流程的事件驅動設計。透過研究分析,我們發現使用 MySQL Binlog 實現事件驅動設計並沒有想象中那麼簡單,所以接下來帶大家瞭解 MySQL 的 Binlog、Redo Log、資料更新內部流程,並透過對這些技術原理的介紹,來分析對業務流程可能造成的問題,以及如何避免這些問題。希望透過本文的解析,能夠幫助大家瞭解到 MySQL 的一些原理,從而幫助大家能夠更順利地使用 MySQL 這個流行的資料庫技術。
基於 Binlog 的事件驅動
首先介紹一下會員訂單系統的設計,訂單系統直接向 MQ 傳送訊息,透過非同步訊息驅動後續業務流程,以實現訊息驅動的設計。大致的業務流程示意圖如下:
圖1:直接傳送訊息的訂單事件驅動
圖2:基於 Binlog 的訂單事件驅動
暗 藏 問 題
上文提到,雖然基於 Binlog 的訂單事件驅動設計存在諸多優點,但後來發現其實暗藏問題。經過實驗,我們發現偶爾會有訂單履約延遲的現象。
在正常流程中,訂單履約服務收到訂單支付事件後,會檢查訂單狀態,如果此時訂單狀態為已支付,則進行履約流程的處理。但對於有履約延遲的訂單,訂單履約服務收到此訂單的支付事件後,查詢資料庫發現此訂單並非支付狀態。經過調查,我們排除了資料併發覆蓋問題,並且訂單狀態查詢是發生在主庫上,也不存在主從同步延遲問題。
那究竟是什麼原因導致業務系統收到根據 Binlog 生成的訂單支付事件後,再查詢主庫得到的訂單資料卻是未支付狀態的?
對於此問題的原因我們先放下不談,先來看看 MySQL 在更新資料時的內部原理。
MySQL 資料更新相關原理
Redo Log | Binlog | |
日誌型別 | 物理日誌,即資料頁中的真實二級制資料,恢復速度快 | 邏輯日誌,SQL 語句 (statement) 或資料邏輯變化 (row),恢復速度慢 |
儲存格式 | 基於 InnoDB 資料頁格式進行儲存 | SQL 語句或資料變化內容 |
用途 | 重做資料頁 | 資料複製 |
層級 | InnoDB 儲存引擎層 | MySQL Server 層 |
記錄方式 | 迴圈寫 | 追加寫 |
>>>> 兩階段提交
如果 Redo Log 有 Commit 標識,說明 Redo Log 其實已經 Commit 成功。這時直接提交事務; 如果 Redo Log 沒有 Commit 標識,則使用 XID(事務 ID)查詢 Binlog 相應日誌,並檢查日誌的完整。如果 Binlog 是完整的,則提交事務,否則回滾;
>>>> MySQL 資料更新流程
執行器先找引擎取 ID=2 這一行。ID 是主鍵,引擎直接用樹搜尋找到這一行。如果 ID=2 這一行所在的資料頁本來就在記憶體中,就直接返回給執行器;否則,需要先從磁碟讀入記憶體,然後再返回。 執行器拿到引擎給的行資料,把這個值加上1,比如原來是 N,現在就是 N+1,得到新的一行資料,再呼叫引擎介面寫入這行新資料。 引擎將這行新資料更新到記憶體中。然後將對記憶體資料頁的更新內容記錄在 Redo Log Buffer 中(這裡不詳細介紹 Redo Log Buffer。只需知道對 Redo Log 的操作並不會直接寫在檔案上,而是先記錄在記憶體中,然後在特定時刻才會寫入磁碟)。此時完成了資料更新操作。 接下來要進行事務提交的操作。事務提交時,Redo Log 被標記為 Prepare 狀態。通常此時,Redo Log 會從 Buffer 寫入磁碟(innodb_flush_log_at_trx_commit,值為1時,每次提交事務 Redo Log 都會寫入磁碟)。然後 InnoDB 告知執行器執行完成,可以提交事務。 執行器生成本次操作的 Binlog,並把 Binlog 寫入磁碟。 執行器呼叫引擎的提交事務介面,引擎把剛剛寫入的 Redo Log 改成提交 Commit 狀態,更新完成。
圖中描述了 update 語句執行過程中 MySQL 執行器、InnoDB,以及 Binlog、Redo Log 互動過程(圖中深綠底色的是 MySQL 執行器負責的階段,淺綠底色是 InnoDB 負責的階段)
問題解析
從上面對 MySQL 原理的介紹我們得知,寫 Binlog 發生在事務提交階段,但是 MySQL 因為在 Server 層和儲存引擎層都引入了不同的日誌結構,從而引入了兩階段提交。Binlog 的寫入發生在儲存引擎真正提交事務之前,這導致理論上透過 Binlog 同步資料的系統(MySQL 從庫、其它資料庫或業務系統)有可能早於 MySQL 主庫使最新提交的資料生效。
所以上面提到的訂單履約服務在收到基於 Binlog 的訂單支付事件後卻查到相應訂單是未支付的,原因很可能是訂單履約服務在查詢資料時,訂單支付資料更新操作在 MySQL 內部尚未徹底完成事務的提交。
我們透過開發驗證程式重現了這一現象。驗證程式接收到事務提交完成後的完整 Binlog 時會再次在 MySQL 主庫上查詢對應的記錄,結果會有一定概覽獲得事務提交前的資料。
另外經過了解,也有同行反映遇到過從庫早於主庫看到資料提交的問題。
問題的解決方法
在瞭解問題背後的原因之後,我們需要思考如何解決此問題。目前解決此問題有兩個方法:重試和直接使用 Binlog 資料。
重試這種做法簡單粗暴,既然問題原因是 Binlog 早於事務提交,那等一下再重試查詢自然就解決了。但在實踐中,需要考慮重試的實現方法、以及是否會因為重試過多甚至無限重試導致服務異常。對於重試的實現,可使用的方法有執行緒 Sleep 大法和訊息重投等方式。執行緒 Sleep 大法通常是不被推薦的,因為它會導致執行緒利用率降低,甚至導致服務無法響應。但考慮到本次問題出現機率較低,我們認為執行緒 Sleep 大法是可以使用的,並且此方式簡單易行,可用於問題的快速修復。
第二種重試方式是訊息重投,比如 RocketMQ 中 Consumer 返回 ConsumeConcurrentlyStatus.RECONSUME_LATER 即可觸發訊息重投。但這種重試方法成本較前一種方法高,另外重試間隔也相對較大,對時間敏感的業務影響也較大,因此是否採用此方法需從業務和技術兩個角度綜合考慮。
除了考慮用何種方式重試,還要考慮 ABA 問題,即狀態變化按照 A->B->A 的方式進行。業務系統期待的狀態是 B,但實際可能沒辦法再變成 B 了。因此在用重試解決此問題之前,需要先排除業務系統存在 ABA 問題的可能。對於狀態 ABA 問題,可用狀態機等方式解決,這裡不再展開討論。
除了重試,另一種方法就是直接使用 Binlog。因為 Binlog (row 格式) 直接反映了資料的變化情況,其中可以記錄事務提交涉及到的完整資料,因此可直接用作業務處理。這樣還可以降低資料庫 QPS。如果是新設計的系統,我認為這樣做法比較理想。但對於已有系統,這種方式改動可能較大,是否採用需權衡成本和收益。
招聘資訊
愛奇藝會員開發團隊誠招 Java 資深工程師/技術專家。會員業務是愛奇藝核心業務之一,我們致力於透過技術手段服務核心業務,研發通用化、高可用的業務系統,同時我們也需要擅長如資料庫、服務治理、MQ 等技術的人才。歡迎感興趣的同學傳送簡歷至:luodi@qiyi.com(郵件標題請註明:會員開發)
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69945252/viewspace-2704743/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 快應用技術架構及業務分析架構
- XML Web 服務技術解析:WSDL 與 SOAP 原理、應用案例一覽XMLWeb
- Mysql的binlog原理MySql
- 音影片技術原理及應用
- MySQL資料庫binlog解析神器-binlog2sql應用MySql資料庫
- 萬字長文解析AI Agent技術原理和應用AI
- 應用架構之道:分離業務邏輯和技術細節應用架構
- MySQL閃回技術之binlog2sql恢復binlog中的SQLMySql
- 技術分享丨 關於MySQL binlog解析那些事MySql
- 大資料技術原理與應用大資料
- 【Mysql核心技術】聊聊事務的實現原理MySql
- WebView快取原理分析和應用WebView快取
- Session工作原理和典型應用分析Session
- 【應用技術】AM335x串列埠技術分析串列埠
- GPU在AI業務中的核心技術與應用GPUAI
- 分析技術在PMP中的應用
- HTML程式碼混淆技術:原理、應用和實現方法詳解HTML
- Mysql的redolog和binlogMySql
- RPA案例 | 某汽車金融公司應用RPA技術使業務處理時間縮短90%
- Oracle、Mysql 專業技術服務(兼職)OracleMySql
- 多程序程式設計:原理、技術與應用程式設計
- 10-入侵檢測技術原理與應用
- Dart編譯技術在服務端的探索和應用Dart編譯服務端
- [應用案例]onethink開發個人技術部落格
- 教你MySQL Binlog實用攻略MySql
- 安全沙箱技術的原理、應用程式的安全性和穩定性
- 大資料建模、分析、挖掘技術應用大資料
- Elasticsearch 技術分析(九):Elasticsearch的使用和原理總結Elasticsearch
- 業務應用小程式化,企業降本增效技術趨勢
- defi質押挖礦dapp系統開發原理技術分析(案例演示)APP
- 《大型網站技術架構:核心原理與案例分析》讀書筆記 - 第3篇 案例網站架構筆記
- 虛擬機器遷移技術原理與應用虛擬機
- iOS應用重簽名ipa技術原理及流程iOS
- 活體生物發光成像技術原理及應用
- MySQL binlog超過binlog_expire_logs_seconds閾值沒有刪除案例MySql
- 工業網際網路內外網的技術與應用分析
- 分析一個企業CRM系統應用的案例
- 大模型基礎應用框架(ReACTSFTRAG)技術創新及零售業務落地應用大模型框架React