本篇文章將介紹MySQL的另外一種高可用實現方案,即:MHA(MasterHigh Avaliable)。Master HA。是一個開源的高可用程式,為MySQL的主從架構提供了故障自動回復的功能。
一、基本知識介紹
1、MHA定義
Master HA。是一個開源的高可用程式,為MySQL的主從架構提供了故障自動回復的功能。主從複製期間,當MHA監測到MySQL的Master節點故障時,會自動提升複製叢集中的某個Slave節點成為新的Master節點。在切換期間,也會通過從其他節點中擷取額外資訊來避免資料一致性問題。除此之外,MHA還提供了master節點的線上故障切換功能,可以按照需要來切換Master/Slave節點。
2、MHA結構
MHA中的所有節點主要有兩種角色,即:管理節點和資料節點。
管理節點(MHA Manager):一般單獨部署在一台機器上,用來管理多個master和slave叢集,而每個master和slave組成的叢集稱之為一個application。
資料節點(MHA Node):運行在每一台MySQL伺服器上,通過監控具有解析和清理logs功能的指令碼來加速節點的容錯移轉。
3、HMA組件
(1)Manager組件
masterha_check_sh:MHA依賴的ssh環境監測工具masterha_check_repl:MySQL複製環境監測工具masterha_manager:MHA服務主程式masterha_check_status:MHA運行狀態探測工具masterha_master_monitor:MySQL master節點可用性監測工具masterha_master_switch:master節點切換工具masterha_conf_host:添加或刪除配置的節點masterha_stop:關閉MHA服務的工具
(2)Node組件
save_binary_logs:儲存和賦值master的二進位日誌apply_diff_relay_logs:識別差異的中繼日誌並應用於其他slavefilter_mysqlbinlog:去除不必要的ROLLBACK事件(MHA已經不再使用這個工具)purge_relay_logs:清除中繼日誌(不會阻塞SQL線程)
(3)自訂擴充
secondary_check_script:通過多條網路路由監測master的可用性master_ip_failover_script:更新application使用的masteripshutdown_script:強制關閉master節點report_script:發送報告init_conf_load_script:載入初始配置參數master_ip_online_change_script:更新master節點ip地址
二、MHA搭建
1、環境準備
作業系統:CentOS6.9_X86_64
MySQL版本:MySQL5.6.39通用二進位
伺服器規劃:
主節點Master:192.168.199.104(mysql-master,master)
從節點1:192.168.199.105(mysql-slave01,slave01)
從節點2:192.168.199.106(mysql-slave02,slave02)
管理節點:192.168.199.107(mysql-manager,manager)
2、搭建
(1)配置各個節點的host,在後面使用起來會比較方便,不用每次手寫IP
[root@mysql-master ~]# vim /etc/hosts#添加如下內容:127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4::1 localhost localhost.localdomain localhost6 localhost6.localdomain6192.168.199.104 mysql-master master192.168.199.105 mysql-slave01 slave01192.168.199.106 mysql-slave02 slave02192.168.199.107 mysql-manager manager
(2)將配置好的host檔案複製到其他三個節點上
[root@mysql-master ~]# scp /etc/hosts slave01:/etc/[root@mysql-master ~]# scp /etc/hosts slave02:/etc/[root@mysql-master ~]# scp /etc/hosts manager:/etc/
(3)配置主從同步,slave01和slave02為master的從庫
開啟master的二進位日誌
[root@mysql-master ~]# vim /etc/my.cnf#在[mysqld]下面添加如下內容:server-id = 104skip-name-resolvelog_bin=/mysql_data/mysql-binlog_bin_index=/mysql_data/mysql-bin.indexbinlog_format = mixed
在master上查看當前的二進位日誌點位置,並建立複製賬戶
[root@mysql-master ~]# mysql -uroot –proot#查看當前二進位日誌點的位置mysql> SHOW MASTER STATUS \G*************************** 1. row *************************** File: mysql-bin.000090 Position: 120 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 1 row in set (0.00 sec)#建立從庫的複製賬戶mysql> GRANT REPLICATION SLAVE ,REPLICATION CLIENT ON *.* TO 'repl'@'192.168.199.%' IDENTIFIED BY 'repl';#重新整理許可權mysql> FLUSH PRIVILEGES;
在slave01上開啟二進位日誌和中繼日誌,並配置為master的從庫
[root@mysql-slave01 ~]# vim /etc/my.cnf#在[mysqld]下添加如下內容:server-id = 105log_bin = /mysql_data/mysql-binlog_bin_index = /mysql_data/mysql-bin.indexrelay_log = /mysql_data/mysql-relayrelay_log_index = /mysql_data/mysql-relay.indexread_onlyrelay_log_purge = 0
參數解釋:
relay_log_purge:該參數表示不自動清理中繼日誌,因為MHA需要根據slave的中繼日誌判斷slave同步master的binlog到什麼位置了read_only:表示是唯讀,MHA需要根據這個參數來識別主從庫bin_log:開啟從庫的二進位日誌,因為在主節點出現故障時,需要將其中某個從庫提升為主庫,所以需要開啟從庫的二進位日誌
啟動slave01節點,並將需要同步的主節點資訊指向master節點:
[root@mysql-slave01 ~]# service mysqld restart[root@mysql-slave01 ~]# mysql -uroot –proot#使用change master命令將主庫指向master節點mysql> CHANGE MASTER TO MASTER_HOST = '192.168.199.104',MASTER_PORT=3306,MASTER_USER='repl',MASTER_PASSWORD='repl',MASTER_LOG_FILE='mysql-bin.000090',MASTER_LOG_POS=120;mysql> START SLAVE;#查看是否同步成功mysql> SHOW SLAVE STATUS \G看到如下資訊表示同步成功:Slave_IO_Running: YesSlave_SQL_Running: Yes
以同樣的方式配置第二台從庫,可以直接將slave01上的設定檔直接複製到第二台slave上,然後修改即可。
[root@mysql-slave01 ~]# scp /etc/my.cnf slave02:/etc/[root@mysql-slave02 ~]# vim /etc/my.cnf#修改server-id即可:server-id = 106
修改完成之後,儲存退出,並重啟mysql,然後配置slave02為master的從庫
[root@mysql-slave02 ~]# mysql -uroot –prootmysql> CHANGE MASTER TO MASTER_HOST = '192.168.199.104',MASTER_PORT=3306,MASTER_USER='repl',MASTER_PASSWORD='repl',MASTER_LOG_FILE='mysql-bin.000090',MASTER_LOG_POS=120;mysql> START SLAVE;#查看是否同步成功mysql> SHOW SLAVE STATUS \G看到如下資訊表示同步成功:Slave_IO_Running: YesSlave_SQL_Running: Yes
(4)建立具有系統管理權限的使用者帳號
#在主節點master上建立管理帳號,使其可以同步到其他連個從節點,注意:這個管理帳號需要能夠遠端連線MySQLmysql> GRANT ALL ON *.* TO 'mha'@'192.168.199.%' IDENTIFIED BY 'mha';mysql> FLUSH PRIVILEGES;
(5)由於MHA架構需要各個節點之間可以進行互信通訊,所以需要將各個節點之間配置為無秘鑰登入,由於節點比較多,單個產生並複製比較麻煩,可以在主節點上產生秘鑰對,然後讓每個主機都具有同樣的私密金鑰
#在master上產生秘鑰對[root@mysql-master ~]# ssh-keygen -t rsa -P ''#首先儲存到原生秘鑰檔案中,使得本機可以無秘鑰使用ssh方式登陸本機[root@mysql-master ~]# cat .ssh/id_rsa.pub >> .ssh/authorized_keys#使用ssh登陸本機測試,發現可以無密碼登陸[root@mysql-master ~]# ssh 192.168.199.104#修改authorized_keys檔案的許可權,只能屬主查看,同組使用者和其他使用者不可查看[root@mysql-master ~]# chmod go= .ssh/authorized_keys
將秘鑰對和私密金鑰檔案複製到其他三個節點上,注意:保證其原有的許可權
[root@mysql-master ~]# scp -p .ssh/id_rsa .ssh/authorized_keys slave01:/root/.ssh/[root@mysql-master ~]# scp -p .ssh/id_rsa .ssh/authorized_keys slave02:/root/.ssh/[root@mysql-master ~]# scp -p .ssh/id_rsa .ssh/authorized_keys manager:/root/.ssh/#測試無密碼登陸,在主節點上執行如下命令,查看slave01節點的ip地址[root@mysql-master ~]# ssh slave01 'ifconfig eth0'#能夠查看到slave01的ip地址表示無秘鑰登陸配置成功,其他倆節點可以自己驗證
(6)下載mha4mysql-manager和mha4mysql-node安裝包
此處使用的軟體包版本如下:
管理節點:mha4mysql-manager-0.56.tar.gz資料節點:mha4mysql-node-0.56.tar.gz
(7)配置epel,因為mha4mysql有的包是來自於base中,有的包是來自於epel中
[root@mysql-master ~]# rpm –ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
(8)解壓,並使用perl命令執行Makefile.PL指令碼
[root@mysql-master ~]# tar xf mha4mysql-manager-0.56.tar.gz[root@mysql-master ~]# cd mha4mysql-manager-0.56[root@mysql-master mha4mysql-manager-0.56]# perl Makefile.PL
注意:執行Makefile.PL過程中,如果出現類似於如下的錯誤,則需要安裝perl程式所依賴的庫檔案:
Can't locate ExtUtils/MakeMaker.pm in @INC (@INC contains: inc /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at inc/Module/Install/Makefile.pm line 4.BEGIN failed--compilation aborted at inc/Module/Install/Makefile.pm line 4
出現上述錯誤,則需要安裝依賴:
[root@mysql-master ~]# yum install perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker cpan perl-Time-HiRes perl-DBI perl-DBD-MySQL
(9)確保”perl MakeFile.PL”正確執行之後,使用make命令完成安裝。註:可以使用”echo $?”查看上此命令的執行結果來判斷上條命令是否正確執行完成。通常0代表正確完成。
[root@mysql-master mha4mysql-manager-0.56]# make[root@mysql-master mha4mysql-manager-0.56]# make install
(10)master上的manager安裝完成之後,按照同樣的方式編譯安裝mha4mysql-node
[root@mysql-manager ~]# tar xf mha4mysql-node-0.56.tar.gz[root@mysql-manager ~]# cd mha4mysql-node-0.56[root@mysql-manager mha4mysql-node-0.56]# perl Makefile.PL#判斷Makefile.PL是否正常執行完成[root@mysql-manager mha4mysql-node-0.56]# echo $?0[root@mysql-manager mha4mysql-node-0.56]# make && make install
(11)在其他三台伺服器上(master,slave01,slave02)上安裝mha4mysql-node
[root@mysql-slave01 ~]# tar mha4mysql-node-0.56.tar.gz[root@mysql-slave01 ~]# cd mha4mysql-node-0.56[root@mysql-slave01 mha4mysql-node-0.56]# perl Makefile.PL[root@mysql-slave01 mha4mysql-node-0.56]# make && make install
其他兩個節點安裝方式相同,此處略。
(12)安裝完成,可以看到在/usr/local/bin下有一些指令碼,就是mha4mysql產生的指令檔
(13)初始化MHA
編輯mha的設定檔,主要有以下兩類:
global配置:為各個application提供預設配置
application配置:用來指定有哪些伺服器
#建立目錄並編輯設定檔[root@mysql-manager ~]# mkdir -pv /etc/masterha/[root@mysql-manager ~]# vim /etc/masterha/app01.conf
寫入如下內容:
[server default]user=mha #系統管理使用者的使用者名稱password=mha #系統管理使用者密碼manager_workdir=/data/masterha/app01 #manager節點的工作目錄,用來存放一些二進位日誌,不存在會自動建立manager_log=/data/masterha/app01/manager.log #記錄檔位置remote_workdir=/data/masterha/app01 #遠端每一個節點的工作目錄,沒有會自動產生ssh_user=root #需要使用ssh來完成一些管理操作repl_user=repl #擁有複製許可權的使用者名稱repl_password=repl #擁有複製許可權的密碼ping_interval=1 #每隔多長時間監測一次主節點是否線上,心跳資訊監測#其他主機[server1]hostname=192.168.199.104#ssh_port=3306 #如果MySQL沒有使用預設連接埠號碼,則此處需要指定,使用預設連接埠不需要指定candidate_master=1 #表示該節點是否在主節點故障之後參與成為主節點master_binlog_dir=/mysql_data/ #指定mysql的binlog日誌路徑[server2]hostname=192.168.199.105candidate_master=1master_binlog_dir=/mysql_data/[server3]hostname=192.168.199.106#no_master=1 #表示主節點故障之後,該節點不參與成為主節點master_binlog_dir=/mysql_data/
(14)檢查各個節點之間的通訊是否正常
[root@mysql-manager ~]# masterha_check_ssh --conf=/etc/masterha/app01.conf
錯誤1:Can't locate Config/Tiny.pm in @INC (@INC contains:XXX
原因:這種錯誤是因為缺少依賴包
解決辦法:安裝提示的依賴包
如下的幾個rpm包如果作業系統本身沒有內建,需要自己從網上下載,可以從
http://rpmfind.net/ 下載所需要的rpm包。以下的rpm包都是針對CentOS6.9 X86_64的:
perl-Mail-Sender-0.8.16-3.el6.noarch.rpm perl-Log-Dispatch-2.26-1.el6.rf.noarch.rpm perl-Parallel-ForkManager-0.7.9-1.el6.noarch.rpmperl-Config-Tiny-2.12-7.1.el6.noarch.rpm
下載完成之後,使用yum命令安裝即可,因為其中可能還會依賴其他包。
錯誤2:master_check_ssh執行中的錯誤:
Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
原因:/root/.ssh/下的檔案內容不一樣或者檔案的許可權有問題,我遇到的是檔案內容有問題。
解決辦法:重新將其他主機上的秘鑰對和私密金鑰拷貝一份就正常了。
(15)檢查主從複製環境是否正常
[root@mysql-manager ~]# masterha_check_repl --conf=/etc/masterha/app01.conf
錯誤1:
Sat Jun 2 03:07:26 2018 - [error][/usr/local/share/perl5/MHA/ServerManager.pm, ln301] install_driver(mysql) failed: Can't locate DBD/mysql.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at (eval 27) line 3.Perhaps the DBD::mysql perl module hasn't been fully installed,or perhaps the capitalisation of 'mysql' isn't right.
原因:缺少perl-DBD-MySQL依賴庫
解決辦法:
[root@mysql-manager ~]# yum install -y perl-DBD-MySQL*
錯誤2:
Sat Jun 2 03:11:06 2018 - [error][/usr/local/share/perl5/MHA/ServerManager.pm, ln188] There is no alive server. We can't do failover
錯誤3:
Failed to save binary log: Binlog not found from /var/lib/mysql,/var/log/mysql! If you got this error at MHA Manager, please set "master_binlog_dir=/path/to/binlog_directory_of_the_master
原因:mysql的binlog日誌目錄沒有在預設的/var/log/mysql下,而是在其他地方,導致目錄找不到。
解決辦法:在manager節點的設定檔中每個節點下制定二進位日誌的目錄路徑。
[server1]hostname=192.168.199.105candidate_master=1master_binlog_dir=/mysql_data/ #指定二進位記錄檔目錄
錯誤4:
Can't exec "mysqlbinlog": No such file or directory at /usr/local/share/perl5/MHA/BinlogManager.pm line 106.mysqlbinlog version command failed with rc 1:0, please verify PATH, LD_LIBRARY_PATH, and client options
原因:使用ssh串連之後找不到mysqlbinlog命令
解決辦法:將/usr/local/mysql-5.6.39/目錄串連到/usr/bin下
[root@mysql-master ~]# ln –s /usr/local/mysql-5.6.39/bin /usr/bin[root@mysql-slave01 ~]# ln –s /usr/local/mysql-5.6.39/bin /usr/bin[root@mysql-slave02 ~]# ln –s /usr/local/mysql-5.6.39/bin /usr/bin
(16)啟動MHA
#前台啟動,日誌會直接列印在控制台上[root@mysql-manager app01]# masterha_manager --conf=/etc/masterha/app01.conf#後台啟動[root@mysql-manager app01]# nohup masterha_manager --conf=/etc/masterha/app01.conf &
(17)驗證高可用故障自動轉移
#停止master節點的mysqld服務[root@mysql-master ~]# killall mysqld mysqld_safe#查看原來的兩個slave節點資訊,發現已經有slave01被提升為master了mysql> SHOW SLAVE STATUS \G*************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.199.105 Master_User: repl ...#查看slave01的read_only屬性,發現已經被修改為OFF了mysql> SHOW VARIABLES LIKE 'read_only';+---------------+-------+| Variable_name | Value |+---------------+-------+| read_only | OFF |+---------------+-------+
注意:當某一個master故障之後,從庫提升為主庫,原來的manager節點上的manager服務會自動結束。需要手動重啟。
(18)故障的伺服器再次恢複時,需要使用”CHANGE MASTER”命令手動將其加入到從節點中
(19)manager節點啟動之後,可以使用masterha_check_status命令查看當前的主節點狀態資訊
[root@mysql-manager ~]# masterha_check_status --conf=/etc/masterha/app01.conf app01 (pid:20582) is running(0:PING_OK), master:192.168.199.105
MHA的其他用法,如線上主從切換等,可以自行參考官方文檔,此處不再介紹。另外還有MHA的manager節點的自動重啟功能,警示功能,故障主機徹底摘除功能等可以通過shell指令碼實現,後面有時間會繼續介紹。
至此,MySQL的MHA高可用準系統搭建完成。整個過程中有無數的坑,可能讀者在搭建過程中,還會遇到其他的深坑,最好能夠硬著頭皮一個一個去解決!篇幅較長,所有內容都是經過驗證一個字一個字敲上去的,但也難免有筆誤,如有錯誤,歡迎在下方評論指出!