一、 MHA概述
-
概念
MHA(Master High Availability)事由日本人DeNA開發的一套MySQL高可用性環境下故障切換和主從提升的軟件,目前在MySQL高可用方面是一個相對成熟的解決方案。在MySQL故障切換過程中,MHA能做到在0~30秒之內自動完成數據庫的故障切換操作,並且在進行故障切換的過程中,MHA能在最大程度上保證數據的一致性,以達到真正意義上的高可用。 -
MHA的主要功能
-
自動故障檢測和自動故障轉移
-
交互式(手動)故障轉移
-
在線切換Master到不同的主機
- MHA的優勢
-
自動故障轉移快
-
主庫崩潰不存在數據一致性問題
-
配置不需要對當前mysql環境做重大修改
-
不需要添加額外的服務器(僅一臺manager就可管理上百個replication)
-
性能優秀,可工作在半同步複製和異步複製
-
只要replication支持的存儲引擎,MHA都支持,不會侷限於innodb
- MHA的組成部分
MHA由Manager節點和Node節點組成;MHA Manager可以單獨部署在一臺獨立的機器上管理多個master-slave集羣,也可以部署在一臺slave節點上。MHA Node運行在每臺MySQL服務器上。
- MHA工作原理
-
MHA Manager會定時探測集羣中的master節點
-
當master出現故障時,從宕機崩潰的master保存二進制日誌事件(binlog events);
-
識別含有最新更新的slave;
-
應用差異的中繼日誌(relay log)到其他的slave;
-
應用從master保存的二進制日誌事件(binlog events);
-
提升一個slave爲新的master,使其他的slave連接新的master進行復制;
二、MHA部署
- 服務器規劃
主機名 | IP地址 | 節點信息 | 數據庫版本 | 系統版本 |
---|---|---|---|---|
manager | 192.168.1.112 | mha manager | Centos 7.4.1708 | |
mysql01 | 192.168.1.103 | mysql主節點 | mysql 5.7.25 | Centos 7.4.1708 |
mysql02 | 192.168.1.111 | mysql從節點 | mysql 5.7.25 | Centos 7.4.1708 |
mysql03 | 192.168.1.127 | mysql從節點 | mysql 5.7.25 | Centos 7.4.1708 |
- 拓撲結構
- 三個mysql節點上安裝mysql 5.7
(1)安裝數據庫
# wget http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm
# yum -y install mysql57-community-release-el7-10.noarch.rpm
# yum -y install mysql-community-server
(2)修改初始密碼
安裝完成後改密碼
[root@mysql02 ~]# cat /var/log/mysqld.log | grep password
2019-03-04T14:04:44.194031Z 1 [Note] A temporary password is generated for root@localhost: qId8M?Arkglb
[root@mysql02 ~]# mysql -u root -p'qId8M?Arkglb'
這個時候你會發現如果設置成123456 顯然不成功,因爲mysql5.7 設置有密碼安全機制,不可以設置成肩帶的密碼,如下圖所示
默認是1,即MEDIUM,所以剛開始設置的密碼必須符合長度,且必須含有數字,小寫或大寫字母,特殊字符。有時候,只是爲了自己測試,不想密碼設置得那麼複雜,譬如說,我只想設置root的密碼爲123456。
必須修改兩個全局參數:
mysql> set global validate_password_policy=0;
Query OK, 0 rows affected (0.00 sec)
密碼默認長度爲8 改爲1
mysql> set global validate_password_length=1;
Query OK, 0 rows affected (0.00 sec)
sql> alter user 'root'@'localhost' identified by '123456';
Query OK, 0 rows affected (0.01 sec)
(3)mysql節點1 創建數據庫 用於之後備份數據
mysql> create database course;
Query OK, 1 row affected (0.01 sec)
mysql> create table one(id int);
Query OK, 1 row affected (0.01 sec)
mysqldump -uroot -p course > /root/course.sql
scp /root/course.sql mysql02:/root
scp /root/course.sql mysql03:/root
- 編輯hosts文件 並傳輸給其他節點
manager節點編輯並傳給其他節點
vim /etc/hosts
192.168.1.112 manager
192.168.1.103 mysql01
192.168.1.111 mysql02
192.168.1.127 mysql03
scp /etc/hosts mysql01:/etc/
scp /etc/hosts mysql02:/etc/
scp /etc/hosts mysql03:/etc/
- 做免密登錄
由於MHA manager通過SSH訪問所有的node節點,各個node節點也同樣通過SSH來相互發送不同的relay log 文件,所以要在每一個node和manager上配置SSH無密碼登陸。
每個節點都生成密鑰對,並把公鑰傳給其他三臺主機
manager主機的操作
20 ssh-keygen
21 ssh-copy-id -i /root/.ssh/id_rsa.pub mysql01
22 ssh-copy-id -i /root/.ssh/id_rsa.pub mysql02
23 ssh-copy-id -i /root/.ssh/id_rsa.pub mysql03
其他三臺主機操作類似,自己操作即可,不再演示
- 配置mysql主從環境
(1)mysql主節點配置
[mysqld]
log-bin=mysql-bin
server-id=1
binlog-do-db=course
binlog-ignore-db=mysql
character-set-server=utf8
init_connect='SET AUTOCOMMIT=0;set names utf8' #設置客戶端不自動提交事務(需手動提交) 且字符集爲utf8
gtid_mode = on
enforce_gtid_consistency = 1
log_slave_updates = 1
plugin_load = "rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"
loose_rpl_semi_sync_master_enabled = 1
loose_rpl_semi_sync_slave_enabled = 1
loose_rpl_semi_sync_master_timeout = 5000 #半同步複製的超時時間
關於配置的說明
GTID是MySQL 5.6的新特性,其全稱是Global Transaction Identifier,可簡化MySQL的主從切換以及Failover。GTID用於在binlog中唯一標識一個事務。當事務提交時,MySQL Server在寫binlog的時候,會先寫一個特殊的Binlog Event,類型爲GTID_Event,指定下一個事務的GTID,然後再寫事務的Binlog。主從同步時GTID_Event和事務的Binlog都會傳遞到從庫,從庫在執行的時候也是用同樣的GTID寫binlog,這樣主從同步以後,就可通過GTID確定從庫同步到的位置了。也就是說,無論是級聯情況,還是一主多從情況,都可以通過GTID自動找點兒,而無需像之前那樣通過File_name和File_position找點兒了。
log_slave_updates=1
該選項告訴從服務器將其SQL線程執行的更新記入到從服務器自己的二進制日誌
最後幾項爲開啓mysql半同步複製
異步複製(Asynchronous replication)
MySQL默認的複製即是異步的,主庫在執行完客戶端提交的事務後會立即將結果返給給客戶端,並不關心從庫是否已經接收並處理,這樣就會有一個問題,主如果crash掉了,此時主上已經提交的事務可能並沒有傳到從上,如果此時,強行將從提升爲主,可能導致新主上的數據不完整。
全同步複製(Fully synchronous replication)
指當主庫執行完一個事務,所有的從庫都執行了該事務才返回給客戶端。因爲需要等待所有從庫執行完該事務才能返回,所以全同步複製的性能必然會收到嚴重的影響。
半同步複製(Semisynchronous replication)
介於異步複製和全同步複製之間,主庫在執行完客戶端提交的事務後不是立刻返回給客戶端,而是等待至少一個從庫接收到並寫到relay log中才返回給客戶端。相對於異步複製,半同步複製提高了數據的安全性,同時它也造成了一定程度的延遲,這個延遲最少是一個TCP/IP往返的時間。所以,半同步複製最好在低延時的網絡中使用。
(2)兩臺從節點的配置如下
[mysqld]
log-bin=mysql-bin
server-id=2
binlog-do-db=course
binlog-ignore-db=mysql
character-set-server=utf8
init_connect='SET AUTOCOMMIT=0;set names utf8'
gtid_mode = on
enforce_gtid_consistency = 1
log_slave_updates = 1
plugin_load = "rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"
loose_rpl_semi_sync_master_enabled = 1
loose_rpl_semi_sync_slave_enabled = 1
loose_rpl_semi_sync_master_timeout = 5000
mysql> create database course;
Query OK, 1 row affected (0.11 sec)
mysql> use course
Database changed
mysql> source /root/course.sql
(3)同步數據
獲取主庫的bin log信息 並備份主庫
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000005 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
在從庫上導入數據並開啓主從複製
mysql> stop slave;
mysql> change master to
-> master_host='192.168.1.103',
-> master_user='repl',
-> master_password='replication',
-> master_port=3306,
-> master_log_file='mysql-bin.000005',
-> master_log_pos=154;
Query OK, 0 rows affected, 2 warnings (0.10 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
(4)創建數據同步用戶和監控用戶,三臺數據庫都執行
grant replication slave on *.* to 'repl'@'192.168.1.%' identified by '123456';
grant all privileges on *.* to 'root'@'192.168.1.%' identified by '123456';
- 安裝MHA
(0) 安裝依賴環境
yum install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker perl-CPAN
yum -y install 'perl(Module::Install)'
(1) 在各節點上安裝mha4mysql-node
mha4mysql-node下載地址:https://github.com/yoshinorim/mha4mysql-node/releases/tag/v0.58
mha4mysql-manager下載地址:https://github.com/yoshinorim/mha4mysql-manager/releases/tag/v0.58
tar xf mha4mysql-node-0.57.tar.gz
cd mha4mysql-node-0.57
perl Makefile.PL
make && make install
(2) 在管理節點上安裝manager
tar xf mha4mysql-manager-0.57.tar.gz
cd mha4mysql-manager-0.57
perl Makefile.PL
make && make install
(3)manager管理工具
在manager節點安裝完成後會生成一些管理工具,manager的主要管理工具有:
masterha_check_ssh:檢查MHA的SSH配置狀況
masterha_check_repl:檢查MySQL複製狀況
masterha_manger:啓動MHA
masterha_check_status:檢測當前MHA運行狀態
masterha_master_monitor:檢測master是否宕機
masterha_master_switch:控制故障轉移(自動或者手動)
masterha_conf_host:添加或刪除配置的server信息
(4)管理節點工具包
save_binary_logs 保存和複製master的二進制日誌
apply_diff_relay_logs 識別差異的中繼日誌事件並將其差異的事件應用於其他的slave
filter_mysqlbinlog 去除不必要的ROLLBACK事件(MHA已不再使用這個工具)
purge_relay_logs 清除中繼日誌(不會阻塞SQL線程)
- 配置MHA
(1)MHA管理端和客戶端安裝完成後,在管理端需要創建MHA的配置文件,配置文件內容如下:
cp /root/mha4mysql-manager-0.58/samples/conf/masterha_default.cnf /etc
/etc/masterha_default.cnf文件的修改可以參照app1.cnf中default server部分進行修改
cp -ra /root/mha4mysql-manager-0.58/samples/scripts/* /usr/local/bin/
master_ip_failover #自動切換時vip管理的腳本,不是必須,如果我們使用keepalived的,我們可以自己編寫腳本完成對vip的管理,比如監控mysql,如果mysql異常,我們停止keepalived就行,這樣vip就會自動漂移
master_ip_online_change #在線切換時vip的管理,不是必須,同樣可以可以自行編寫簡單的shell完成
power_manager #故障發生後關閉主機的腳本,不是必須
send_report #因故障切換後發送報警的腳本,不是必須,可自行編寫簡單的shell完成。
mkdir -p /etc/masterha
mkdir /var/log/masterha/app1
cp /root/mha4mysql-manager-0.57/samples/conf/app1.cnf /etc/masterha/
vim /etc/masterha/app1.cnf
[server default]
manager_workdir=/var/log/masterha/app1
manager_log=/var/log/masterha/app1/manager.log
master_binlog_dir=/var/log
master_ip_failover_script= /usr/local/bin/master_ip_failover
master_ip_online_change_script= /usr/local/bin/master_ip_online_change
password=123456
user=root
ping_interval=1
remote_workdir=/tmp
repl_password=123456
repl_user=repl
report_script=/usr/local/send_report
secondary_check_script= /usr/local/bin/masterha_secondary_check -s 192.168.1.132 -s 192.168.1.177
shutdown_script=""
ssh_user=root
[server1]
hostname=192.168.1.167
port=3306
[server2]
port=3306
hostname=192.168.1.132
candidate_master=1
check_repl_delay=0
[server3]
port=3306
hostname=192.168.1.177
(2)MHA主要配置文件說明
secondary_check_script //
一般來說,它是強烈建議有兩個或多個網絡線路檢查MySQL主服務器的可用性。默認情況下,只有單一的路線 MHA Manager檢查:從Manager to Master。但這是不可取的。MHA實際上可以有兩個或兩個以上的檢查路線通過調用外部腳本定義二次檢查腳本參數
shutdown_script="" //設置故障發生後關閉故障主機腳本(該腳本的主要作用是關閉主機放在發生腦裂,這裏沒有使用)
candidate_master=1:設置爲候選master,如果設置該參數以後,發生主從切換以後將會將此從庫提升爲主庫,即使這個主庫不是集羣中事件最新的slave
check_repl_delay=0 //默認情況下如果一個slave落後master 100M的relay logs的話,MHA將不會選擇該slave作爲一個新的master,因爲對於這個slave的恢復需要花費很長時間,通過設置check_repl_delay=0,MHA觸發切換在選擇一個新的master的時候將會忽略複製延時,這個參數對於設置了candidate_master=1的主機非常有用,因爲這個候選主在切換的過程中一定是新的master
(3)修改/usr/local/bin/master_ip_failover,這裏使用腳本管理vip
vim /usr/local/bin/master_ip_failover
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;
my (
$command, $ssh_user, $orig_master_host, $orig_master_ip,
$orig_master_port, $new_master_host, $new_master_ip, $new_master_port
);
my $vip = '192.168.1.188/24'; #此處爲你要設置的虛擬ip
my $key = '1';
my $ssh_start_vip = "/usr/sbin/ifconfig ens32:$key $vip"; #此處改爲你的網卡名稱
my $ssh_stop_vip = "/usr/sbin/ifconfig ens32:$key down";
在文件最後的sub useage{} 上添加內容
sub start_vip() {
`/usr/bin/ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
sub stop_vip() {
return 0 unless ($ssh_user);
`/usr/bin/ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}
註釋 掉這一行 FIXME_xxx;
- 檢查MHA的環境是否工作正常
(1)通過masterha_check_ssh腳本檢測SSH連接是否配置正常
[root@localhost ~]# masterha_check_ssh --conf=/etc/manager.cnf
Warning: Permanently added '192.168.1.176' (ECDSA) to the list of known hosts.
Wed Mar 6 15:34:28 2019 - [debug] ok.
Wed Mar 6 15:34:29 2019 - [info] All SSH connection tests passed successfully.
(2)在管理節點檢查複製配置
爲了讓MHA正常工作,所有的master和slave必須在配置文件中正確配置,MHA可通過masterha_check_repl 腳本檢測複製是否正確配置。
[root@localhost etc]# masterha_check_repl --conf=/etc/masterha/app1.cnf
Sun Mar 10 16:47:58 2019 - [info]
192.168.1.167(192.168.1.167:3306) (current master)
+--192.168.1.132(192.168.1.132:3306)
+--192.168.1.177(192.168.1.177:3306)
Checking the Status of the script.. OK
Sun Mar 10 16:47:58 2019 - [info] OK.
Sun Mar 10 16:47:58 2019 - [warning] shutdown_script is not defined.
Sun Mar 10 16:47:58 2019 - [info] Got exit code 0 (Not master dead).
MySQL Replication Health is OK.
(3)檢查MHA狀態
masterha_check_status --conf=/etc/masterha/app1.cnf
(4)啓動MHA
nohup masterha_manager --conf=/etc/masterha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1 &
啓動參數說明
--remove_dead_master_conf 該參數代表當發生主從切換後,老的主庫的ip將會從配置文件中移除。
--manger_log 日誌存放位置
--ignore_last_failover 在缺省情況下,如果MHA檢測到連續發生宕機,且兩次宕機間隔不足8小時的話,則不會進行
Failover,之所以這樣限制是爲了避免ping-pong效應。該參數代表忽略上次MHA觸發切換產生的文件,默認情況下,
MHA發生切換後會在日誌目錄,也就是上面我設置的/data產生app1.failover.complete文件,下次再次切換的時候
如果發現該目錄下存在該文件將不允許觸發切換,除非在第一次切換後收到刪除該文件,爲了方便,這裏設置
爲--ignore_last_failover。
(5)停止MHA
masterha_stop –conf=/etc/masterha/app1.cnf
(6)檢查MHA啓動狀態
[root@localhost etc]# tail /var/log/masterha/app1/manager.log
IN SCRIPT TEST====/usr/sbin/ifconfig ens32:2 down==/usr/sbin/ifconfig ens32:2 192.168.1.188/24===
Checking the Status of the script.. OK
Sun Mar 10 16:55:32 2019 - [info] OK.
Sun Mar 10 16:55:32 2019 - [warning] shutdown_script is not defined.
Sun Mar 10 16:55:32 2019 - [info] Set master ping interval 1 seconds.
Sun Mar 10 16:55:32 2019 - [info] Set secondary check script: /usr/local/bin/masterha_secondary_check -s 192.168.1.132 -s 192.168.1.177
Sun Mar 10 16:55:32 2019 - [info] Starting ping health check on 192.168.1.167(192.168.1.167:3306)..
Sun Mar 10 16:55:32 2019 - [info] Ping(SELECT) succeeded, waiting until MySQL doesn't respond..
如上表示啓動成功
(7)使用 ip a 可以在mysql主庫上看到設置的漂移ip,殺死master後,slave1和slave2成爲主從結構
----- Failover Report -----
app1: MySQL Master failover 192.168.1.167(192.168.1.167:3306) to 192.168.1.132(192.168.1.132:3306) succeeded
Master 192.168.1.167(192.168.1.167:3306) is down!
Check MHA Manager logs at manager:/var/log/masterha/app1/manager.log for details.
Started automated(non-interactive) failover.
Invalidated master IP address on 192.168.1.167(192.168.1.167:3306)
Selected 192.168.1.132(192.168.1.132:3306) as a new master.
192.168.1.132(192.168.1.132:3306): OK: Applying all logs succeeded.
192.168.1.132(192.168.1.132:3306): OK: Activated master IP address.
192.168.1.177(192.168.1.177:3306): OK: Slave started, replicating from 192.168.1.132(192.168.1.132:3306)
192.168.1.132(192.168.1.132:3306): Resetting slave info succeeded.
Master failover to 192.168.1.132(192.168.1.132:3306) completed successfully.
Sun Mar 10 17:24:59 2019 - [info] Sending mail..
sh: /usr/local/send_report: No such file or directory
Sun Mar 10 17:24:59 2019 - [error][/usr/local/share/perl5/MHA/MasterFailover.pm, ln2089] Failed to send mail with return code 127:0
在新的主庫上查看ip地址 也可以看得到漂移ip188 如下
ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:32:26:97 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.132/24 brd 192.168.1.255 scope global dynamic ens32
valid_lft 65194sec preferred_lft 65194sec
inet 192.168.1.188/24 brd 192.168.1.255 scope global secondary ens32:2
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe32:2697/64 scope link
valid_lft forever preferred_lft forever
舊的master修復之可以繼續當做從庫使用,只需要在舊的master執行以下命令
stop slave;
CHANGE MASTER TO MASTER_HOST='192.168.1.132', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123456';
start slave;
show slave status\G
(8)特殊情況下也可以手動切換主
masterha_master_switch --master_state=dead --conf=/etc/masterha/app1.cnf --dead_master_host=192.168.1.167 --dead_master_port=3306 --new_master_host=192.168.1.132 --new_master_port=3306 --ignore_last_failover
MHA配置文件中所有參數的詳細文檔請參考
https://github.com/yoshinorim/mha4mysql-manager/wiki/Parameters
https://blog.csdn.net/dayi_123/article/details/83690608
https://blog.csdn.net/qq_34605594/article/details/77387872