MHA 如何工做的?node
MHA是如何工做的? ======================================================================================================================= * 參見 https://code.google.com/p/mysql-master-ha/wiki/HowMHAWorks - 創始人的ppt文檔描述設計的原理 http://www.slideshare.net/matsunobu/automated-master-failover 儘管排版不是特別吸引人,可是確實涵蓋了內部設計筆記,不過可能不是最新的。 - 源碼參見 https://github.com/yoshinorim/mha4mysql-manager/tree/master/lib/MHA perl寫的操做binlog的接口 https://github.com/yoshinorim/mha4mysql-node/tree/master/lib/MHA https://github.com/ovaistariq/mha-helper python封裝的工具腳本,用來調用perl寫的命令接口。 * 如何辨別從哪一個偏移量開始進行中繼日誌補償?! 好久以前,MHA的做者使用mysqlbinlog來識別中繼日誌的偏移,但如今不用了,本身解析那個二進制文件的事件頭部 就好了,就能夠辨別事件的起始偏移量。 不適用mysqlbinlog的緣由有幾個,最主要是由於mysqlbinlog老是打印出全部事件的全部內容,不單單只是打印出事件頭部, 但咱們僅僅須要的是去分析頭部而已。由於必要的定位信息都在頭部,包括事件類型、master id、事件長度、下一個事件的偏移量。 事件體咱們並不關心,那麼,使用mysqlbinlog不只在讀取二進制日誌時增長了性能開銷,也讓咱們須要格外警戒一些與日誌中的關鍵字 「撞衫」的sql語句,好比end_log_pos\# at等等。 爲了不錯誤的識別起始偏移信息,mysqlbinlog加上--base64-output=always選項是有幫助的,可是這個選項只在mysql 5.1和mysql 5.5 中支持,5.0不支持,5.6中被移除了。並且這個選項說不定會漏掉某些事件。 上面的行不通的話,只能逆向來搜索了,rotate事件是個好的地標。 * 快速的中繼日誌定位 假定待恢復的目標從庫中的master_log_file:pos是mysqld-bin.000001:504810023,最新從庫中的io線程的讀頭在 mysqld-bin.000001:504810689, 並且最新的中繼日誌文件是mysqld-relay-bin.000001而且超過了500M。目標從庫和最新從庫的IO線程讀頭只相差幾百個字節。若是MHA從中繼日誌 頭部開始解析,那麼故障切換的時間就太長了。 $latest_mlf = Master_Log_File on the latest slave $target_mlf = Master_Log_File on the recovery target slave $latest_rmlp = Read_Master_Log_Pos on the latest slave $target_rmlp = Read_Master_Log_Pos on the recovery target slave $offset = $latest_rmlp - $target_rmlp $filesize = File size of the latest relay log file on the latest slave if ($latest_mlf eq $target_mlf) && ($filesize > $offset),那麼MHA就能夠決定下來,起始恢復點是最新從庫的最新中繼文件中的 ($filesize - $offset)偏移處, * 如何爲待恢復的目標從庫生成relaylog補償和binlog補償 總的來講,分三段來完成補償: - 目標從庫的exec_master_log_pos到目標從庫的read_master_log_pos 因爲中繼日誌中待回放的事件必須組成一個完整的事務,begin和commit之間的全部內容,若是主庫宕機前從庫並未收到完整的事務事件, 那麼exec_master_log_pos < read_master_log_pos,他們之間只是事務的一部分,沒獲得重放執行。 - 目標從庫的read_master_log_pos到最新從庫的read_master_log_pos 目標從庫的中繼日誌可能落後於最新從庫。 - 最新從庫的read_master_log_pos到崩潰主庫的binlog結尾處 以前,MHA的做者是每段都採用mysqlbinlog輸出的,這樣會帶來兩個問題: - 在每一個binlog文件開始處和每次mysqlbinlog輸出的結尾處都添加rollback語句。須要顯式過濾。 - 若是row-based event恰好被割裂到兩個文件中,那麼mysqlbinlog的輸出可能不正確。 如今,改成三段都是經過直接解析二進制文件的事件頭部來定位和搜索,接着將三段組合成一個大的二進制文件,而後再交給 mysqlbinlog來輸出,只輸出一次,方便過濾rollback,也沒有了割裂row event的問題。