1. 程式人生 > >半同步複製中可能出現的異常情況以及應該如何應對?

半同步複製中可能出現的異常情況以及應該如何應對?

文章目錄

半同步複製如何應對各種異常情況?

全篇以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之前宕機

等等。