MHA,即Master High Availability Manager and Tools for MySQL,是日本的一位MySQL專家采用Perl語言編寫的一個腳本管理工具,該工具僅適用於MySQL Replication(二層)環境,目的在於維持Master主庫的高可用性。
學習一個高可用小軟件,不但要熟悉其功能,還要了解其架構及工作原理。
從架構上來說,MHA分為如下兩大部分:
(1) Node
我們知道,MHA是基於MySQL Replication環境的,在該環境中,不管是Master角色,還是Slave角色,都稱為Node,是被監控管理的對象節點。
Node服務器上需要安裝MHA Node包。
(2) Manager
Manager為MHA架構中的管理者,建議部署在一台獨立的服務器上,當然也可部署在某個Slave上,但該Slave永遠不要被選擇成為新的Master,否則故障切換後的MHA架構就失去了高可用性。
Manager服務器需要安裝MHA Manager包,並完善一個主配置文件。
一個Manager可管理多套MySQL Replication環境。
相較於其它HA軟件,MHA的目的在於維持MySQL Replication中Master庫的高可用性,其最大特點是可以修復多個Slave之間的差異日志,最終使所有Slave保持數據一致,然後從中選擇一個充當新的Master,並將其它Slave指向它。
基本工作流程大致如下:
(1) Manager定期監控Master,監控時間間隔由參數ping_interval決定,缺省為3秒鐘一次;可利用其自身的監控功能,也可調用第三方軟件來監控;MHA自身提供了兩種監控方式:SELECT(執行SELECT 1)和CONNECT(創建連接/斷開連接),由於參數ping_type決定,缺省為SELECT方式。
(2) 當監測到Master故障時,調用SSH腳本對所有Node執行一次檢查,包括如下幾個方面:
――MySQL實例是否可以連接;
――Master服務器是否可以SSH連通;
――檢查SQL Thread的狀態;
――檢查哪些Server死掉了,哪些Server是活動的,以及活動的Slave實例;
――檢查Slave實例的配置及復制過濾規則;
――最後退出監控腳本並返回代表特殊意義代碼。
(3) 開始Master故障切換,包括如下幾個子階段:
――Phase 1: Configuration Check Phase
在這個階段,若某個Slave實例的SQL Thread停止了,則會自動啟動它;並再次確認活動的Servers及Slaves。
――Phase 2: Dead Master Shutdown Phase
在這個階段,首先調用master_ip_failover_script,若HA是基於VIP實現的,則關閉VIP,若是基於目錄數據庫實現的,則修改映射記錄。
然後調用shutdown_script腳本強制關閉主機,以避免服務重啟時,發生腦裂。
――Phase 3: Master Recovery Phase
又包括如下3個子階段:
Phase 3.1: Getting Latest Slaves Phase
檢查各個Slave,獲取最近的和最舊的binary log file和position,並檢查各個Slave成為Master的優先級,依賴於candidate_master、no_master、[server_xxx]順序、binary log差異量等因素。
Phase 3.2: Saving Dead Master's Binlog Phase
若dead master所在服務器依然可以通過SSH連通,則提取dead master的binary log,提取日志的起點就是上一步獲取的最新的binary log file和position,直到最後一條事件日志,並在dead master本地的工作目錄(由參數remote_workdir決定)中創建文件保存這些提取到的日志,然後將該文件拷貝到Manager服務器的工作目錄下(由參數manager_workdir決定)。
當然,若dead master系統就無法連接,也就不存在差異的binary log了。
另外,MHA還要對各個Slave節點進行健康檢查,主要是SSH連通性。
Phase 3.3: Determining New Master Phase
接下來調用apply_diff_relay_logs命令恢復Slave的差異日志,這個差異日志指的是各個Slave之間的relay log。
恢復完成後,所有的Slave數據是一致的,此時就可以根據優先級選擇New Master了。
Phase 3.3: New Master Diff Log Generation Phase
這裡是生成dead master和new master之間的差異日志,即將Phase 3.2保存的binary log拷貝到New Master的工作目錄中(remote_workdir)。
Phase 3.4: Master Log Apply Phase
將上一步拷貝的差異日志恢復到New Master上,若發生錯誤,也可手動恢復。
然後獲取New Master的binlog name和position,以便其它Slave從這個新的binlog name和position開始復制。
最後會開啟New Master的寫權限,即將read_only參數設置為0。
――Phase 4: Slaves Recovery Phase
Phase 4.1: Starting Parallel Slave Diff Log Generation Phase
生成Slave與New Slave之間的差異日志,並將該日志拷貝到各Slave的工作目錄下,這部分日志dead master和new master之間差異的那部分日志,因為各個Slave在Phase 3.3階段已經同步了。
Phase 4.2: Starting Parallel Slave Log Apply Phase
在各個Slave上應用這部分差異日志,然後通過CHANGE MASTER TO命令將這些Slave指向新的New Master,最後開始復制(start slave)。
――Phase 5: New master cleanup phase
清理New Master其實就是重置slave info,即取消原來的Slave信息。
至此整個Master故障切換過程完成。
從官方網站的介紹來看,MHA具有如下幾個功能:
(1) Master自動監控和故障轉移
基於現有的MySQL主從復制環境,MHA可以監控Master,當發現其故障時,自動進行切換。
在多個Slave環境中,如果個別Slave沒有接受到最新的relay log events,MHA則會自動從最新的那個Slave上查找差異的relay log events,並將這些差異事件應用到有延遲的Slave上,最終保持所有的Slave數據一致。通常情況下,MHA可在9-12秒內監測到Master故障,7-10秒內關閉主機以避免腦裂,然後花費幾秒時間應用差異的relay log,整個過程通常只需10-30秒即可完成。
既然MHA可以自動修復多個Slaves之間的差異日志,所以不用擔心數據一致性問題。當Master故障時,MHA會從多個Slave中隨機選擇一個充當新的Master;當然,也可在配置文件中指定某一個Slave優先成為Master。
(2) 互動(手動)Master故障轉移
可以只使用MHA的故障轉移功能,而不監控Master,當其故障時,手動調用MHA來進行故障切換。
(3)非交互式自動故障轉移
MHA還支持非交互式的Master故障切換(不監控Master,但實現自動故障切換),這個特性其實是將Master的監控和VIP接管交給第三方工具來做,比如Heartbeat,MHA只負責Master故障轉移和Slave之間的數據同步。
(4) 在線切換Master到不同的主機
在有些情況下,比如更換Raid控制器,升級主機硬件等,則需要將其上的Master實例遷移到其它主機上,MHA支持快速的Master切換和短暫的寫操作阻塞,通常只需0.5-2秒的downtime,這是可以接受的,也方便了DBA的操作。
系統環境
OS:CentOS 5.8 (x86_64) 內核:2.6.18-308.el5 DB:MySQL 5.5.17
hostname IP MySQL Role MHA Role
node1 192.168.3.27 master node
node2 192.168.3.28 slave1 (備用) node
node3 192.168.3.25 slave2 node
mmm 192.168.3.26 manager
MHA的安裝包也包括Manager和Node兩部分,其中Node包不但要在所有的Node節點上安裝,而且還需在Manager節點上安裝,因為Manager模塊內部依賴Node模塊,
Manager包則只需在Manager節點安裝即可。
從MHA官網http://code.google.com/p/mysql-master-ha/downloads/list下載合適的安裝包,可以是源碼包,也可以是RPM包,本例采用RPM包,如下:
Manager包:mha4mysql-manager-0.55-1.el5.noarch.rpm
Node包:mha4mysql-node-0.54-1.el5.noarch.rpm
MHA是采用perl語言編寫的一個腳本管理工具,所以需要安裝一系列perl依賴包。
1、在所有節點上安裝perl語言依賴包
# rpm -ivh MySQL-shared-compat-5.5.17-1.rhel5.x86_64.rpm
# rpm -ivh perl-DBI-1.52-2.el5.x86_64.rpm
# rpm -ivh perl-DBD-MySQL-3.0007-2.el5.x86_64.rpm
(以下依賴包為Manager節點需要)
# rpm -ivh perl-Params-Validate-0.95-1.el5.rf.x86_64.rpm
# rpm -ivh perl-Log-Dispatch-2.26-1.el5.rf.noarch.rpm
# rpm -ivh perl-Config-Tiny-2.12-1.el5.rf.noarch.rpm
# rpm -ivh perl-Parallel-ForkManager-0.7.5-2.2.el5.rf.noarch.rpm
在所有節點及manager上安裝node包
# rpm -ivh mha4mysql-node-0.54-1.el5.noarch.rpm
在manager節點上安裝manager包
# rpm -ivh mha4mysql-manager-0.55-1.el5.noarch.rpm
成功安裝後,會在/usr/bin目錄下生成如下一系列命令工具:
/usr/bin/masterha_check_repl
/usr/bin/masterha_conf_host
/usr/bin/masterha_master_switch
/usr/bin/masterha_check_ssh
/usr/bin/masterha_manager
/usr/bin/masterha_secondary_check
/usr/bin/masterha_check_status
/usr/bin/masterha_master_monitor
/usr/bin/masterha_stop
接下來就可以配置MHA配置文件了,只需在Manager服務器上操作;RPM包安裝時,缺省不會生成該配置文件,可手動生成,也可從MHA Manager源碼安裝包中查找配置文件模板,及一系列調用腳本。
創建工作目錄
在Node上創建一個單獨的工作目錄,用於remote_workdir參數來存放相關日志文件,缺省為/var/tmp,若未創建,MHA也會自動創建,但這需要有創建權限。
# mkdir -p /mha/appl
在Manager上創建工作目錄,用於manager_workdir參數,其中存放日志文件和一系列腳本文件等。
# mkdir -p /mha/appl
# mkdir -p /mha/scripts
配置masterha_default.cnf文件
這是全局配置文件,缺省為/etc/masterha_default.cnf,適用於一個Manager管理多套MySQL Replication的情況,在[server_default]下定義一些多套復制環境通用的Global Scope類型的參數。本例只有一套MySQL Replication,所以也可不用配置該文件,而是在對應的應用配置文件(appl.conf)下的[server_default]中定義相關參數。
執行MHA相關命令時,會在/etc目錄下搜索該配置文件,若找不到,雖然不會有什麼錯誤,但會給出一個警告,如“[warning] Global configuration file /etc/masterha_default.cnf not found.”。
為此可以在/etc目錄下創建一個名為masterha_default.cnf的空文件,本例不打算這麼做,而是在其中配置一些通用的[server_default]類參數,如下:
# vi /etc/masterha_default.cnf
[server default]
user = root
password = mysql --mysql密碼
ssh_user = root
repl_user = repl
repl_password = repl_pwd
ping_interval = 3
ping_type = SELECT
配置appl.conf文件
這是針對每一套MySQL Replication應用專門的配置文件,若管理多套MySQL Replication,可配置多個文件,其中包括[server_default]和[server_xxx]兩個項目,分別用於配置App Scope、Local Scope類型的參數。
# vi /etc/appl.cnf
[server default]
manager_workdir = /mha/appl
manager_log = /mha/appl/manager.log
remote_workdir = /mha/appl
#master_ip_failover_script=/mha/scripts/master_ip_failover
[server1]
hostname = 192.168.3.27
master_binlog_dir = /data/lib/mysql
candidate_master = 1
[server2]
hostname = 192.168.3.28
master_binlog_dir = /data/lib/mysql
candidate_master =1
[server3]
hostname = 192.168.3.25
no_master = 1
因為MHA管理節點以及各個Node節點之間需要無密碼登錄並執行相關腳本,所以需要配置各個節點之間的SSH等效性,如下:
――生成密鑰文件(各個節點均需執行)
# mkdir -p ~/.ssh
# cd .ssh
# /usr/bin/ssh-keygen -t rsa (提示處直接回車即可)
# /usr/bin/ssh-keygen -t dsa (提示處直接回車即可)
執行完成後,在/root/.ssh 目錄下會生產四個密鑰文件。
――任意一個節點執行即可(本例選擇在manager節點執行)
# ssh 192.168.3.27 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
# ssh 192.168.3.27 cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
# ssh 192.168.3.28 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
# ssh 192.168.3.28 cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
# ssh 192.168.3.25 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
# ssh 192.168.3.25 cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
# ssh 192.168.3.26 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
# ssh 192.168.3.26 cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
# scp ~/.ssh/authorized_keys 192.168.3.27:.ssh/
# scp ~/.ssh/authorized_keys 192.168.3.28:.ssh/
# scp ~/.ssh/authorized_keys 192.168.3.25:.ssh/
――修改authorized_keys文件的權限為600(所有節點均需執行)
# chmod 600 ~/.ssh/authorized_keys
――測試一下
在各節點執行如下命令,測試一下,看是否不提示密碼即可顯示,否則則說明SSH配置不成功。
# ssh 192.168.3.26 hostname
# ssh 192.168.3.26 date
另外,還可采用MHA提供的工具命令來檢查,如下:
[root@mmm .ssh]# /usr/bin/masterha_check_ssh --conf=/etc/appl.cnf
Fri Jul 18 16:52:12 2014 - [info] Reading default configuratoins from /etc/masterha_default.cnf..
Fri Jul 18 16:52:12 2014 - [info] Reading application default configurations from /etc/appl.cnf..
Fri Jul 18 16:52:12 2014 - [info] Reading server configurations from /etc/appl.cnf..
Fri Jul 18 16:52:12 2014 - [info] Starting SSH connection tests..
Fri Jul 18 16:52:13 2014 - [debug]
Fri Jul 18 16:52:12 2014 - [debug] Connecting via SSH from [email protected](192.168.3.27:22) to [email protected](192.168.3.28:22)..
Fri Jul 18 16:52:12 2014 - [debug] ok.
Fri Jul 18 16:52:12 2014 - [debug] Connecting via SSH from [email protected](192.168.3.27:22) to [email protected](192.168.3.25:22)..
Fri Jul 18 16:52:12 2014 - [debug] ok.
Fri Jul 18 16:52:13 2014 - [debug]
Fri Jul 18 16:52:12 2014 - [debug] Connecting via SSH from [email protected](192.168.3.28:22) to [email protected](192.168.3.27:22)..
Fri Jul 18 16:52:13 2014 - [debug] ok.
Fri Jul 18 16:52:13 2014 - [debug] Connecting via SSH from [email protected](192.168.3.28:22) to [email protected](192.168.3.25:22)..
Fri Jul 18 16:52:13 2014 - [debug] ok.
Fri Jul 18 16:52:13 2014 - [debug]
Fri Jul 18 16:52:13 2014 - [debug] Connecting via SSH from [email protected](192.168.3.25:22) to [email protected](192.168.3.27:22)..
Fri Jul 18 16:52:13 2014 - [debug] ok.
Fri Jul 18 16:52:13 2014 - [debug] Connecting via SSH from [email protected](192.168.3.25:22) to [email protected](192.168.3.28:22)..
Fri Jul 18 16:52:13 2014 - [debug] ok.
Fri Jul 18 16:52:13 2014 - [info] All SSH connection tests passed successfully.
從中可以看到,該命令會從應用配置文件中讀取相關信息(IP和SSH_USER),然後在各個Node之間相互驗證,保證可以通過SSH方式相互登錄(用於同步差異日志)。
這一步的目的是在hostname和ip之間提供一個解析途徑,配置方法很簡單,就是將各個節點的主機名及對應的IP地址寫入/etc/hosts文件,所有節點均需配置,且保持一致,如下:
# vi /etc/hosts
# that require network functionality will fail.
127.0.0.1 localhost.localdomain localhost
192.168.3.27 node1
192.168.3.28 node2
192.168.3.25 node3
192.168.3.26 mmm
為了省事,在一個節點配置,然後拷貝到其它節點即可;配置完成後,可以相互ping一下主機名,看能否成功解析。
按照規劃,在node1、node2、node3上安裝MySQL數據庫,並搭建成一主二從的MySQL Replication結構;具體操作不做說明了,可參考http://blog.csdn.net/dbaxiaosa/article/details/22421969 對於MHA來說,搭建MySQL Replication需要注意以下幾點:
read_only――是否限制Slave實例為只讀狀態,缺省為0,即不限制,MHA要求設置為1。
relay_log_purge――這個參數用於限制中繼日志應用完之後是否刪除,缺省為1,即應用完之後立即刪除;在MHA中,Manager就是通過這些日志來同步各個Slave之間的數據差異的,所以必須設置為0,即不刪除中繼日志。
log_bin――是否開啟二進制日志,若某個Slave可能被選擇成為新的Master,則必須開啟;若某個Slave被限制永遠不會成為新的Master,可以不用開啟。
成功搭建後,通過MHA命令檢查一下,確保無誤。
[root@mmm scripts]# /usr/bin/masterha_check_repl --conf=/etc/appl.cnf
Mon Jul 21 10:40:12 2014 - [info] Reading default configuratoins from /etc/masterha_default.cnf..
Mon Jul 21 10:40:12 2014 - [info] Reading application default configurations from /etc/appl.cnf..
Mon Jul 21 10:40:12 2014 - [info] Reading server configurations from /etc/appl.cnf..
Mon Jul 21 10:40:12 2014 - [info] MHA::MasterMonitor version 0.55.
Mon Jul 21 10:40:12 2014 - [info] Dead Servers:
Mon Jul 21 10:40:12 2014 - [info] Alive Servers:
Mon Jul 21 10:40:12 2014 - [info] 192.168.3.27(192.168.3.27:3306)
Mon Jul 21 10:40:12 2014 - [info] 192.168.3.28(192.168.3.28:3306)
Mon Jul 21 10:40:12 2014 - [info] 192.168.3.25(192.168.3.25:3306)
Mon Jul 21 10:40:12 2014 - [info] Alive Slaves:
Mon Jul 21 10:40:12 2014 - [info] 192.168.3.28(192.168.3.28:3306) Version=5.5.17-log (oldest major version between slaves) log-bin:enabled
Mon Jul 21 10:40:12 2014 - [info] Replicating from 192.168.3.27(192.168.3.27:3306)
Mon Jul 21 10:40:12 2014 - [info] Primary candidate for the new Master (candidate_master is set)
Mon Jul 21 10:40:12 2014 - [info] 192.168.3.25(192.168.3.25:3306) Version=5.5.17 (oldest major version between slaves) log-bin:disabled
Mon Jul 21 10:40:12 2014 - [info] Replicating from 192.168.3.27(192.168.3.27:3306)
Mon Jul 21 10:40:12 2014 - [info] Not candidate for the new Master (no_master is set)
Mon Jul 21 10:40:12 2014 - [info] Current Alive Master: 192.168.3.27(192.168.3.27:3306)
Mon Jul 21 10:40:12 2014 - [info] Checking slave configurations..
Mon Jul 21 10:40:12 2014 - [warning] relay_log_purge=0 is not set on slave 192.168.3.28(192.168.3.28:3306).
Mon Jul 21 10:40:12 2014 - [warning] log-bin is not set on slave 192.168.3.25(192.168.3.25:3306). This host can not be a master.
Mon Jul 21 10:40:12 2014 - [info] Checking replication filtering settings..
Mon Jul 21 10:40:12 2014 - [info] binlog_do_db= , binlog_ignore_db=
Mon Jul 21 10:40:12 2014 - [info] Replication filtering check ok.
Mon Jul 21 10:40:12 2014 - [info] Starting SSH connection tests..
Mon Jul 21 10:40:13 2014 - [info] All SSH connection tests passed successfully.
Mon Jul 21 10:40:13 2014 - [info] Checking MHA Node version..
Mon Jul 21 10:40:14 2014 - [info] Version check ok.
Mon Jul 21 10:40:14 2014 - [info] Checking SSH publickey authentication settings on the current master..
Mon Jul 21 10:40:14 2014 - [info] HealthCheck: SSH to 192.168.3.27 is reachable.
Mon Jul 21 10:40:14 2014 - [info] Master MHA Node version is 0.54.
Mon Jul 21 10:40:14 2014 - [info] Checking recovery script configurations on the current master..
Mon Jul 21 10:40:14 2014 - [info] Executing command: save_binary_logs --command=test --start_pos=4 --binlog_dir=/data/lib/mysql --output_file=/mha/appl/save_binary_logs_test --manager_version=0.55 --start_file=mysql-bin.000004
Mon Jul 21 10:40:14 2014 - [info] Connecting to [email protected](192.168.3.27)..
Creating /mha/appl if not exists.. ok.
Checking output directory is accessible or not..
ok.
Binlog found at /data/lib/mysql, up to mysql-bin.000004
Mon Jul 21 10:40:14 2014 - [info] Master setting check done.
Mon Jul 21 10:40:14 2014 - [info] Checking SSH publickey authentication and checking recovery script configurations on all alive slave servers..
Mon Jul 21 10:40:14 2014 - [info] Executing command : apply_diff_relay_logs --command=test --slave_user='root' --slave_host=192.168.3.28 --slave_ip=192.168.3.28 --slave_port=3306 --workdir=/mha/appl --target_version=5.5.17-log --manager_version=0.55 --relay_log_info=/data/lib/mysql/relay-log.info --relay_dir=/data/lib/mysql/ --slave_pass=xxx
Mon Jul 21 10:40:14 2014 - [info] Connecting to [email protected](192.168.3.28:22)..
Checking slave recovery environment settings..
Opening /data/lib/mysql/relay-log.info ... ok.
Relay log found at /data/lib/mysql, up to mysql-relay-bin.000006
Temporary relay log file is /data/lib/mysql/mysql-relay-bin.000006
Testing mysql connection and privileges.. done.
Testing mysqlbinlog output.. done.
Cleaning up test file(s).. done.
Mon Jul 21 10:40:14 2014 - [info] Executing command : apply_diff_relay_logs --command=test --slave_user='root' --slave_host=192.168.3.25 --slave_ip=192.168.3.25 --slave_port=3306 --workdir=/mha/appl --target_version=5.5.17 --manager_version=0.55 --relay_log_info=/data/lib/mysql/relay-log.info --relay_dir=/data/lib/mysql/ --slave_pass=xxx
Mon Jul 21 10:40:14 2014 - [info] Connecting to [email protected](192.168.3.25:22)..
Creating directory /mha/appl.. done.
Checking slave recovery environment settings..
Opening /data/lib/mysql/relay-log.info ... ok.
Relay log found at /data/lib/mysql, up to mysql-relay-bin.000008
Temporary relay log file is /data/lib/mysql/mysql-relay-bin.000008
Testing mysql connection and privileges.. done.
Testing mysqlbinlog output.. done.
Cleaning up test file(s).. done.
Mon Jul 21 10:40:15 2014 - [info] Slaves settings check done.
Mon Jul 21 10:40:15 2014 - [info]
192.168.3.27 (current master)
+--192.168.3.28
+--192.168.3.25
Mon Jul 21 10:40:15 2014 - [info] Checking replication health on 192.168.3.28..
Mon Jul 21 10:40:15 2014 - [info] ok.
Mon Jul 21 10:40:15 2014 - [info] Checking replication health on 192.168.3.25..
Mon Jul 21 10:40:15 2014 - [info] ok.
Mon Jul 21 10:40:15 2014 - [warning] master_ip_failover_script is not defined.
Mon Jul 21 10:40:15 2014 - [warning] shutdown_script is not defined.
Mon Jul 21 10:40:15 2014 - [info] Got exit code 0 (Not master dead).
MySQL Replication Health is OK.
注:如果有錯誤,根據檢查的錯誤提示,進行相應的修改設置()。
從中可以看出,該命令首先從主配置文件和應用配置文件中讀取相關參數,然後檢查各個Slave的狀態、參數配置、SSH連通性、執行save_binary_logs、apply_diff_relay_logs命令等操作,確保最後的提示為“MySQL Replication Health is OK”,否則需要重新檢查MySQL Replication配置。
另外,其中給出了兩個警告,提示沒有定義master_ip_failover_script、shutdown_script,這個暫且不管,在後面環節再詳細說明。
經過上面一系列步驟,成功搭建及配置了MHA,下面我們就來簡單試用一下,並進行一下功能測試。
MHA提供的命令工具包括Manager工具和Node工具,簡單介紹如下:
Manager工具
/usr/bin/masterha_check_repl ――檢查MySQL Replication是否正常;
/usr/bin/masterha_conf_host ――添加或刪除配置的Server信息;
/usr/bin/masterha_master_switch ――用於手動Master切換;
/usr/bin/masterha_check_ssh ――檢查各個Node之間SSH登錄是否正常;
/usr/bin/masterha_manager ――開啟MHA
/usr/bin/masterha_secondary_check ――檢查多路由配置;
/usr/bin/masterha_check_status ――檢查MHA是否開啟並正常運行;
/usr/bin/masterha_master_monitor ――手動開啟監控,啟動MHA時會自動啟動監控
/usr/bin/masterha_stop ――關閉MHA
Node工具
/usr/bin/save_binary_logs ――保存和復制master的二進制日志;
/usr/bin/apply_diff_relay_logs ――識別差異的中繼日志事件並應用於其它Slave;
/usr/bin/filter_mysqlbinlog ――去除不必要的Rollback事件(MHA已不再使用該工具);
/usr/bin/purge_relay_logs ――清除中繼日志(不會阻塞SQL線程);
備注:Node端工具通常由MHA Manager的腳本觸發調用,無需DBA操作。
在開啟MHA之前,可以先通過masterha_check_repl檢查一下MySQL Replication是否正常,通過masterha_check_ssh檢查一下各個node之間SSH登錄是否正常,這在前面均已試用該命令。
開啟MHA的命令為masterha_manager,其用法如下:
[root@mmm scripts]# /usr/bin/masterha_manager --help
Usage:
masterha_manager --global_conf=/etc/masterha_default.cnf
--conf=/usr/local/masterha/conf/app1.cnf
See online reference
(http://code.google.com/p/mysql-master-ha/wiki/masterha_manager) for
details.
可見其只有兩個參數,--global_conf缺省為/etc/masterha_default.cnf,本例中符合缺省要求,所以可以不指定,為了方便,通過如下命令使其後台運行。如下:
[root@mmm appl]# /usr/bin/masterha_manager --conf=/etc/appl.cnf &
[1] 5674
[root@mmm appl]# Mon Jul 21 10:56:32 2014 - [info] Reading default configuratoins from /etc/masterha_default.cnf..
Mon Jul 21 10:56:32 2014 - [info] Reading application default configurations from /etc/appl.cnf..
Mon Jul 21 10:56:32 2014 - [info] Reading server configurations from /etc/appl.cnf..
為了使MHA持續運行在服務器端,可通過如下命令使其不掛起運行在後台:
[root@mmm appl]# nohup /usr/bin/masterha_manager --conf=/etc/appl.cnf &
[1] 5905
[root@mmm appl]# nohup: appending output to `nohup.out'
MHA開啟之後,會在其工作目錄下生成如下兩個文件:
[root@mmm appl]# ls
appl.master_status.health manager.log
其中appl.master_status.health為Master實例的健康監控文件,MHA開啟時生成,關閉後消失,裡面內容如下:
[root@mmm appl]# more appl.master_status.health
5674 0:PING_OK master:192.168.3.27
而manager.log為MHA的日志文件,其內容較多,執行masterha_check_repl命令時的輸入內容類似。
可通過masterha_check_status命令檢查MHA是否在運行,比如:
[root@mmm appl]# /usr/bin/masterha_check_status --conf=/etc/appl.cnf
appl (pid:5905) is running(0:PING_OK), master:192.168.3.27
若MHA正常運行,則提示如上,否則提示:appl is stopped(2:NOT_RUNNING).
對於一個正在運行的MHA,可通過masterha_stop命令關閉,如下:
[root@mmm appl]# /usr/bin/masterha_check_status --conf=/etc/appl.cnf
appl is stopped(2:NOT_RUNNING).
》模擬復制不同步,造成數據差異
――關閉node3的復制線程,然後在Master主庫(node1)上創建一張表,以此造成node3數據不同步
mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)
mysql> use test;
Database changed
mysql> CREATE TABLE student(s_id INT,s_name VARCHAR(10),PRIMARY KEY(s_id));
Query OK, 0 rows affected (0.01 sec)
――關閉node2的復制進線程,
mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)
mysql> insert into student(s_id,s_name) values(1,'aaa');
Query OK, 1 row affected (0.01 sec)
通過這個模擬,現在node1(Master)上有一張student表,並有一條數據;node2(slave1)上有student這張表,但裡面沒有數據;node3(slave2)上還沒有student這張表,所以這套復制環境的3個節點目前是不同步的。
》關閉node1(Master)的mysqld進程,模擬MySQL實例故障
[root@node1 data]# service mysql stop;
Shutting down MySQL... [ OK ]
此時檢查node2,發現已恢復了差異數據(一條記錄),停掉了原來的復制線程,被選擇為新的Master,並賦予寫操作權限。
mysql> select * from student;
+------+--------+
| s_id | s_name |
+------+--------+
| 1 | aaa |
+------+--------+
1 row in set (0.00 sec)
mysql> show slave status \G;
Empty set (0.00 sec)
mysql> show variables like 'read_only%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| read_only | OFF |
+---------------+-------+
1 row in set (0.00 sec)
檢查node3,發現差異數據也被恢復(student表和一條記錄),並將master_host指向新的Master(node2)
mysql> use test;
Database changed
mysql> select * from student;
+------+--------+
| s_id | s_name |
+------+--------+
| 1 | aaa |
+------+--------+
1 row in set (0.00 sec)
mysql> show slave status \G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.3.28 (這裡指向了新的master:node2)
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000005
Read_Master_Log_Pos: 520069
Relay_Log_File: mysql-relay-bin.000002
Relay_Log_Pos: 253
Relay_Master_Log_File: mysql-bin.000005
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 520069
Relay_Log_Space: 409
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 28
1 row in set (0.00 sec)
從中可以看到,當MHA監控到Master實例故障時,自動恢復了Master與Slave以及Slaves之間的差異日志,然後從兩個Slave實例中選擇node2充當新的Master,並將另一個Slave實例node2重新指向到新的Master實例node2開始復制,組成新的MySQL Replication結構。而原來的Master則被排除在新的MySQL Replication結構之外,即使其恢復正常,也不會被自動加入。
開啟MHA後,自動啟動監控功能,當監測到Master故障時,自動實現切換。
另外,在沒有開啟MHA的情況下,我們還可以執行交互式的手動切換、非交互式的自動切換,及在線切換Master到不同主機等操作,這些都是通過masterha_master_switch命令工具實現的。
該命令用法如下:
[root@mmm appl]# /usr/bin/masterha_master_switch --help
Usage:
# For master failover
masterha_master_switch --master_state=dead
--global_conf=/etc/masterha_default.cnf
--conf=/usr/local/masterha/conf/app1.cnf --dead_master_host=host1
# For online master switch
masterha_master_switch --master_state=alive
--global_conf=/etc/masterha_default.cnf
--conf=/usr/local/masterha/conf/app1.cnf
See online reference
(http://code.google.com/p/mysql-master-ha/wiki/masterha_master_switch)
for details.
從中可以看到,該命令有# For master failover、# For online master switch兩個用法,區別在於前者需要指定Master的狀態為dead,後者需要指定Master的狀態為alive。
下面通過兩個示例來體會一下:
》 For master failover
現在的Master為node2,手動停止mysqld實例
[root@node2 ~]# service mysql stop
Shutting down MySQL... [ OK ]
下面手動執行Master故障切換,這個切換過程是交互式的,期間需要輸入指令來確認;另外,由於MHA沒有啟動,也就不會自動監控Master實例狀態,所以需要指定master_state為dead,並且指定dead master的host、ip、port等信息,如下:
[root@mmm ~]# /usr/bin/masterha_master_switch --master_state=dead --conf=/etc/appl.cnf --dead_master_host=node2
》 For online master switch
這個功能是指Master實例運行正常,但出於運維工作(比如:更換硬件等),需要將其上的Master切換到另一主機上。
切換過程都一樣,期間也需要交互,只不過指定master_state=alive即可,如下:
# /usr/bin/masterha_master_switch --master_state=alive --conf=/etc/appl.cnf
通過這兩個示例,我們知道,不管是自動Master故障切換,還是手動交互式Master切換,以及在線切換Master到另外主機,其切換過程和步驟都是一樣的。
至此MHA成功搭建完畢,該小節告一段落,通過前面的學習,我們了解了MHA這一高可用工具的Master故障切換功能及實現原理,但若在實際生產環境中采用它,還存在許多問題,需要進一步的改進與配置。我們先來探討一下上面這套環境中存在的問題,及MHA提供的解決辦法。
問題: 前端應用連接問題
理論上來說,後端數據庫故障切換,對前端應用應該是透明的;也就是說:當Master從一台主機切換到另一台主機上時,前端應用不需要做任何額外的操作,主要體現為數據庫連接串變化。
對於這個問題,通常有兩種解決方案:一是引入VIP,當數據庫切換時,VIP隨之切換;常用的HA軟件中,大多是采用VIP實現的,比如Oracle RAC,SQL Server群集、Heartbeat等。二是采用全局目錄數據庫,即將應用和數據庫之間的連接映射為一個列表,當數據庫切換時,更改這個映射列表。MHA並不限制用戶使用那種方式,只是通過master_ip_failover_script配置參數提供了一個接口。 若采用VIP的方式來實現,可引入第三方軟件,比如Keplived等,也可自行編寫一個VIP切換腳本。
由於篇幅問題,以上兩種方案解決方案,等有時間再繼續寫入到 MySQL高可用系列之MHA(二)