
mysql半同步復制和異步復制的差別如上述架構圖所示:在mysql異步復制的情況下,Mysql Master Server將自己的Binary Log通過復制線程傳輸出去以后,Mysql Master Sever就自動返回數據給客戶端,而不管slave上是否接受到了這個二進制日志。在半同步復制的架構下,當master在將自己binlog發給slave上的時候,要確保slave已經接受到了這個二進制日志以后,才會返回數據給客戶端。對比兩種架構:異步復制對于用戶來說,可以確保得到快速的響應結構,但是不能確保二進制日志確實到達了slave上;半同步復制對于客戶的請求響應稍微慢點,但是他可以保證二進制日志的完整性。
1.問題背景
默認情況下,線上的mysql復制都是異步復制,因此在極端情況下,主備切換時,會有一定的概率備庫比主庫數據少,因此切換后,我們會通過工具進行回滾回補,確保數據不丟失。半同步復制則要求主庫執行每一個事務,都要求至少一個備庫成功接收后,才真正執行完成,因此可以保持主備庫的強一致性。為了確保主備庫數據強一致,減少數據丟失,嘗試在生產環境中開啟mysql的復制的半同步(semi-sync)特性。實際操作過程中,發現大部分實例半同步都可以正常運行,但有少部分實例始終開不起來(只能以普通復制方式運行),更奇葩的是同一個主機的兩個實例,一個能開啟,一個不能。最終定位的問題也很簡單,但排查出來還是花了一番功夫,下文將描述整個問題的排查過程。
2.半同步復制原理
mysql的主備庫通過binlog日志保持一致,主庫本地執行完事務,binlog日志落盤后即返回給用戶;備庫通過拉取主庫binlog日志來同步主庫的操作。默認情況下,主庫與備庫并沒有嚴格的同步,因此存在一定的概率備庫與主庫的數據是不對等的。半同步特性的出現,就是為了保證在任何時刻主備數據一致的問題。相對于異步復制,半同步復制要求執行的每一個事務,都要求至少有一個備庫成功接收后,才返回給用戶。實現原理也很簡單,主庫本地執行完畢后,等待備庫的響應消息(包含最新備庫接收到的binlog(file,pos)),接收到備庫響應消息后,再返回給用戶,這樣一個事務才算真正完成。在主庫實例上,有一個專門的線程(ack_receiver)接收備庫的響應消息,并以通知機制告知主庫備庫已經接收的日志,可以繼續執行。有關半同步的具體實現,可以參考另外一篇文章,mysql半同步(semi-sync)源碼實現。
3.問題分析
前面簡單介紹了半同步復制的原理,現在來看看具體問題。在主備庫打開半同步開關后,問題實例的狀態變量"Rpl_semi_sync_master_status"始終是OFF,表示復制一直運行在普通復制的狀態。
新聞熱點
疑難解答