MHA原始碼分析

kunlunzhiying發表於2017-09-01
<span style="font-size:18px;">MHA是針對MySQL由perl實現高可用方案的軟體。MHA主要分為管理節點和資料節點,管理節點主要由masterha_manager實現對資料節點的管理,而管理的實現主要透過管理節點透過建立各個節點之間的SSH互信並呼叫資料節點安裝的MHA各個指令碼。MHA的核心功能是對於mysql叢集中一旦master節點當機,如何迅速將某個slave節點提升為新的master節點。</span><br /> <span style="font-size:18px;"><br /> <p> 首先,介紹下它的一些特點。 </p> <p> 1. 10-30s實現master failover(9-12s可以檢測到主機故障,7-10s可以關閉主機,在用很短的時間應用差異日誌) </p> <p> 2. 部署簡單,無需對現有M-S結構做任何改動(至少3臺,保證切換後仍保持M-S結構) </p> <p> 3. 支援手動線上切換(主機硬體維護),downtime幾乎很短0.5-2s </p> <p> 4. 保證故障切換後多從庫資料的一致性 </p> <p> 5. 完全自動化的failover及快速複製架構恢復方案(一主多從) </p> <p> 6. 恢復過程包括:選擇新主庫、確認從庫間relay log差異、新主庫應用必要語句、其他從庫同步差異語句、重新建立複製連線 </p> <br /> <br /> </span> <div id="xunlei_com_thunder_helper_plugin_d462f475-c18e-46be-bd10-327458d045bd"> <span style="font-size:18px;">先從master_manager這個指令碼作為MHA failover功能原始碼分析的切入點:</span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">MHA::MasterMonitor::main</span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">MHA::MasterFailover::main</span><br /> <span style="font-size:18px;">上面是masterha_manager依次呼叫的另外兩塊程式碼,可見masterha_manager是先對叢集中節點進行監控,然後一旦檢測到master當機那麼將執行故障切換</span><br /> <span style="font-size:18px;"></span><br /> <span style="font-size:24px;"><span style="color:#E53333;">MasterMonitor</span></span><br /> <span style="font-size:18px;">|</span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">&nbsp;wait_until_master_is_dead()</span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">|</span><br /> <span style="font-size:18px;">wait_until_master_is_unreachable() - 此處會初始化MHA::ServerManager物件用來管理以及統計節點的狀態並做好節點的分類(dead servers,alive servers,alive slave,real_master</span><span style="font-size:18px;">...)</span><br /> <span style="font-size:18px;">|</span><br /> <span style="font-size:18px;">server_manager-&gt;connect_all_and_read_server_status()此處相對而言比較關鍵,透過對所有節點的嘗試連線和節點的狀態讀取(如show master status,show slave status,show variables like '?')來梳理servermanager的統計和管理內容</span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">|</span><br /> <span style="font-size:18px;">server_manager-&gt;validate_slaves&nbsp; (read_only(info)?相同的ip/port(error)?relay_log_purge=0(warn)?相同的複製過濾規則?)</span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">server_manager-&gt;get_bad_candidate_masters</span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">server_manager-&gt;check_repl_priv</span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">MHA::ManagerUtil::check_node_version</span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">check_binlog_servers</span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">server_manager-&gt;validate_num_alive_servers</span><br /> <span style="font-size:18px;">以上是在server_manager對節點的狀態獲取和梳理後再進行的各種結果的驗證,來檢驗slave節點配置的一致性,有無符合可切換的slave,驗證節點配置使用者是否擁有複製的許可權等</span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">|</span><br /> <span style="font-size:18px;">master_ping = new MHA::HealthCheck </span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">例項化節點健康檢測物件</span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">|</span><br /> <span style="font-size:18px;">master_ping-&gt;wait_until_unreachable</span><br /> <span style="font-size:18px;">如果並沒有master當機,那麼會一直hang在此處</span><br /> <br /> <span style="font-size:18px;"></span><br /> <span style="font-size:18px;"><span style="font-size:24px;color:#E53333;">MasterFailover</span></span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">|</span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">do_master_failover()</span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">|</span><br /> <span style="font-size:18px;">步驟1:配置檢查,說是配置檢查,實際上再次進行狀態獲取以及對監控到dead master進行校對和驗證</span><br /> <span style="font-size:18px;">check_settings()</span><br /> <span style="font-size:18px;">|</span><br /> <span style="font-size:18px;">步驟2:停掉所有slave的IO thread,然後檢查ssh互信後呼叫master節點的自己制定的關閉master指令碼</span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">force_shutdown($dead_master)</span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">|</span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">步驟3:master恢復</span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">|</span><br /> <span style="font-size:18px;">步驟3.1:獲得relaylog最新的slave以及relaylog最舊的slave</span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">|</span><br /> <span style="font-size:18px;">步驟3.2:儲存當機master的binlog-其實並不是儲存整個binlog,而是呼叫master節點的save_binary_logs命令去根據最新slave中讀取的binlog位置擷取最新的slave沒有獲取到的binlog內容,儲存到管理節點</span><br /> <span style="font-size:18px;">save_master_binlog($dead_master) </span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">|</span><br /> <span style="font-size:18px;">步驟3.3:選出新的master,在選舉過程中分為三個優先權(1.在啟動引數中設定的master 2.最新relaylog位置的slave且同步延遲在可以接受的範圍內3.配置檔案中設定為candidate_master的節點</span><span style="font-size:18px;">)</span><br /> <span style="font-size:18px;">select_new_master( $dead_master, $latest_base_slave ),在選出新的master後透過與最新的slave比較產生差異的relaylog</span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">|</span><br /> <span style="font-size:18px;">步驟3.4:對新的master提供差異binlog+差異relaylog來使得其資料與原始的master資料一致</span><br /> <span style="font-size:18px;">recover_master( $dead_master, $new_master, $latest_base_slave,$binlog_server_ref )</span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">|</span><br /> <span style="font-size:18px;">步驟4:開始恢復slaves,這裡的步驟和補齊新的master步驟差不多這裡不再贅訴,再change master重新指向新的master</span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">recover_all_slaves_relay_logs</span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">|</span><br /> <span style="font-size:18px;">步驟5:清空新的master的原始slave</span><span style="font-size:18px;">配置 reset slave</span><br /> <span style="font-size:18px;"></span><span style="font-size:18px;">reset_slave_on_new_master</span><br /> <span style="font-size:18px;"></span><br /> <span style="font-size:18px;"></span><br /> <span style="font-size:18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><br /> </div> <div id="xunlei_com_thunder_helper_plugin_d462f475-c18e-46be-bd10-327458d045bd"> </div>

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28211342/viewspace-2144407/,如需轉載,請註明出處,否則將追究法律責任。

相關文章