半同步複製中可能出現的異常情況以及應該如何應對?
阿新 • • 發佈:2018-11-21
文章目錄
半同步複製如何應對各種異常情況?
全篇以MySQL-5.7 after_sync模式半同步為背景,sync_binlog=1.
對外承諾的資料零丟失,通過半同步複製究竟能實現嗎?為了能夠回答這個問題,我們必須對半同步複製中可能出現的任何異常情況進行描述,並且瞭解故障時的master-slave資料狀態。
一、準備知識
事務提交會經歷哪些階段
- flush binlog
將每一個執行緒中快取的binlog檔案寫到binlog cache中(binlog_cache_size)
- sync redo
根據innodb_flush_log_at_trx_commit=1的設定,事務提交時,redo必須落盤。
- sync binlog
將binlog cache 寫入磁碟檔案
- send binlog
觸發dump執行緒傳送binlog給slave
- read ack
讀取slave返回的ACK資訊
- commit
在Innodb儲存引擎中進行提交,包括釋放undo,釋放鎖資源等。
- 返回給客戶端提交結果
何為半同步複製
以MySQL-5.7 semisync after_sync為例,半同步複製解釋為如下:
master端事務提交時,在binlog落盤之後,必須等待slave返回ack資訊,才可以繼續下面的操作。至於什麼ACK,ACK具體包含了什麼,其他地方有講到。sync binlog是事務提交過程其中的一個階段。
二、可能出現哪些異常以及如何解決
事務提交過程的各個階段以及時間順序如下圖,根據下圖,可以假設出一系列的故障場景,以及面對這些場景,應該如何解決?
master 在flush binlog之前宕機
-
宕機瞬間情況描述:
- master在flush binlog之前宕機,客戶端未收到commit成功的資訊。
- binlog未落盤
- redo可能落盤,也可能沒有,因為存在一個後臺執行緒,在沒間隔innodb_flush_log_at_timeout之後,進行redo的刷盤操作。
- slave未收到此事務的binlog,slave中不會存在此資料。
-
假設只有一個半同步slave,並且rpl_semi_sync_master_wait_for_slave_count=1,那麼對應的切換邏輯如下:
- 檢視relay log是否被消費完成
- 切換為master(通過域名或者SIP,入口改變應該注意的事項不在本次討論範圍之內,比如說arp,DNS快取等等)
-
切換後的master修復
- binlog中不存在對應的提交失敗的事務
- redo中可能有,也可能沒有
- MySQL會回滾掉相關提交失敗的事務
- 資料和半同步 slave保持一致。
自己可以嘗試分析下面這些場景,並進行描述。明天再更新
master 在flush binlog 之後,send binlog之前宕機
master 在send binlog之後,收到ack之前宕機
等等。