mysql 高可用之mha實現
一
mha簡介
mha是由日本DeNA公司youshimaton(現就職於Facebook公司)開發,是一套MySQL環境下故障切換和主從提升的高可用軟體。據說可以在0~30秒內完成主從切換,
並且在切換過程中可以最大限度的保持資料一致性,當然本人認為保持資料一致性這個問題,一定程度依賴於所搭建的主從複製的工作模式
##實際檢驗時 做過不同主從複製模式下的mha高可用 結論是在經典方式下 似乎mha工作更加穩定
二
mha工作模式
mha在master宕機時的工作過程大致如下
(1)從宕機崩潰的master儲存二進位制日誌事件(binlog events);
(2)識別含有最新更新的slave;
(3)應用差異的中繼日誌(relay log) 到其他slave;
(4)應用從master儲存的二進位制日誌事件(binlog events);
(5)提升一個slave為新master;
(6)使用其他的slave連線新的master進行復制。
三mha工作原理
mha是完全由perl語言編寫開發的 大致結構分為manager & node兩部分 manager和node分別包含不同的perl指令碼 但是核心功能依賴於node部分的指令碼
所以所有的節點都應有node部分的指令碼 而manager部分的指令碼只需要在manager節點上有即可
並且 所有的perl指令碼執行都依賴於同一個cnf檔案 也就是說 mha的大體結構就是一堆的perl指令碼 然後他們執行時都要以這個cnf 作為引數 讀取其中的配置資訊
來保證自己的正常執行
四
實驗環境
首先 所有節點要安裝perl直譯器 以及mysql對應的perl模組 (DBD:mysql)
並且 至少擁有三個節點 也就是三個mysql節點 並且實現一主兩從的複製
這裡筆者使用的是經典複製模式 關於如何配置經典複製模式 可以參考筆者以前的部落格 mysql 5.7 主從複製
所以這裡不再贅述
並且 系統版本 Redhat6.5 mysql版本5.7 mha版本0.56 rpm格式
主從環境:
172.25.44.3 master
172.25.44.4 備用master
172.25.44.1 slave以及manger #(實在是記憶體有限 一旦開啟很多虛擬化節點就很影響實驗體驗 \尬 所以把manager和slave配置在同一節點)
五
配置開始
首先在所有節點yum install mha4mysql-node-0.56 -y
並在manger節點安裝 mha4mysql-manager-0.56 注意此時應該已經配置好主從複製
這裡筆者的rpm安裝過後 所有的指令碼都放在/usr/bin/ 目錄下 只要找到指令碼 vim檢視內容即可發現 指令碼要求的通用cnf檔案位置以及名稱 這個檔案不是rpm包自帶的 沒有預設示範
需要自行建立目錄 並自己手寫這個檔案 或者更改所有指令碼 改所有指令碼豈不是很麻煩 所以這裡我還是mkdir老老實實滿足指令碼所需的目錄
然後這個app1.cnf內容如下
manager _log #manager程序啟動後生成的日誌位置
manager_workdir #manager程序的工作空間
master_binlog_dir #master節點binglog存放位置 即 mysql的資料目錄
master_ip_failover_script #master down之後 監控自動執行的change master 管理vip漂移指令碼
master_ip_online_change_script #master down 手動failover切換master 管理vip指令碼
user & password #監控使用者以及密碼 在所有節點上都要授權該使用者以及監控許可權
ping intervial #manager 用來 ping master節點的頻率
remote_workdir #從遠端的節點發生切換時 binlog儲存位置
repl_user&repl_password #複製使用者 使用者名稱及密碼 所有節點授權 複製許可權
ssh_user #ssh使用者名稱密碼
report_script #master 宕機時傳送郵件警告所用的指令碼
shutdown_script #類似於fence機制的強制PowerOff故障節點的指令碼
接下來就說說mha正常啟動的流程吧
首先要有上文所說的app1.cnf
然後我們就要迎來比較恐怖的三次check
分別是mha的三個check指令碼 masterha_check_ssh masterha_check_repl masterha_check_status
其實坑比較多的是第二個repl的check 檢查各種情況下的主從同步 這個最難搞
並且只有三個check 全部通過 mha才能正常執行
首先是第一個ssh的check 他要求 manager節點對所有節點免密ssh登陸 以及其他node節點之間相互免密ssh登陸
我們再這裡要在各個節點執行 ssh-keygen -t rsa 以及多次執行ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected] 來實現該節點到172.25.44.x節點的ssh免密
完成之後執行 masterha_check_ssh --conf=/usr/local/masterha/app1.cnf
驗證ssh是否通過
ssh check通過 接下來我們 執行 masterha_check_repl --conf=/usr/local/masterha/app1.cnf 模擬各種情況下的複製
果不其然有報錯 但是mha雖然結構很簡單 就是一堆的perl指令碼 但是不得不說報錯這點上 作者還是相當用心 基本從報錯中就可以清楚的看到為什麼沒有通過 十分的詳細
他這裡說我們有兩個節點的slave是沒有正常執行的 那麼我們進入mysql解決
eg:這裡筆者已經做過repl使用者(複製使用者)以及look使用者(監控使用者)的授權 如果是新建環境 必須先做這兩個使用者的授權 切記!!
這裡有一個關鍵的坑點 所有的從庫必須設定read_only 因為mha是在主從同步基礎上的 所以一定要防止手動方式或其他外力方式修改從庫內容 導致從庫複製過來的binlog
在自己本地無法執行 那麼 slave的sql執行緒就會掛掉 無法實現同步 也就是說 所有的slave資料變更完全由同步機制實現 不允許其他實現
這裡我們看到兩個yes 說明change master成功 主從複製開啟
再次check repl 成功
然後這裡我是手動給master節點上了一個vip 因為是指令碼實現failover 所以要手動上一個vip
而且這裡還有一個小坑點 必須是 ifconfig eth0:1 172.25.44.100/24 這樣的命令 加上去的 如果ip addr後沒有eth0:1 那麼將來他宕機以後 指令碼不能down掉他的vip
因為我進去看了他的指令碼 指令碼就是在你的master節點的bash上執行 一個ifconfig ethx:1 172.25.x.100 down 這個命令 如果不是一模一樣的vip 命令就無法生效
就會發生兩個節點爭搶vip的情況
下面我們要執行最後一個check status之前 應當先把監控開啟 因為他mha預設是監控自動failover的
使用nohup masterha_manager + 各種引數 + & 打入後臺 執行
--remove_dead_master_conf #將宕機的master從app1.cnf中剔除
--ignore_last_failover #忽略最近的failover日誌 這裡也有一個小坑點 mha的預設是兩次檢測到宕機的時間間隔如過不超過8小時 那麼不執行failover
切換master vip漂移 實驗環境沒有那麼長的時間間隔 它每次完成切換後會在 manager程序的工作目錄留下一個 failover_complete檔案 如果檢測到這個檔案存在
那麼即使檢測到宕機 也預設不切換 為了防止ping-pong 所以我們要手動加引數忽略這個檔案
之後我們檢視 /usr/local/masterha/manager.log 管理程序的檔案 裡面對當前整個manager-node點中的各個節點的狀態都有檢測 主要還是檢測master
節點 如果我們看到末尾的 ping (select) succeed ,waiting until mysql doesn't response 那麼說明整個點的監控已經正常運行了
我們可以看到在manager程序的工作目錄下 有failover.complete的檔案 以及master狀態的master_status.health檔案 還有從宕機master中搶救過來的binlog檔案
然後我們stop掉master的mysql 模擬宕機
然後繼續監控manager程序的日誌檔案 可以發現manager程序已經檢測到宕機 並迅速的執行比對資料 搶救binlog 選舉新master vip漂移 並在slave上
重新change master以及relaylog 同步資料等等一系列操作 不得不說日誌真是詳細 mha很強大
這時我們切到宕機的master上 發現我們手動新增的vip已經飄走
新master上的slave狀態被reset
存活的slave上的slave狀態已經被重新 change master 並且已經完成了relaylog(這裡截圖有限 已經看不到了)
下面就是mha的一些源指令碼內容 可以看到全域性配置檔案的指定(在document塊中)
以及我所使用的的master_ip_failover指令碼內容 (這個在各大神的日誌或部落格中均可以找到)