MySQL MHA高可用叢集部署及故障切換
一、MHA概念
MHA(MasterHigh Availability)是一套優秀的MySQL高可用環境下故障切換和主從複製的軟體。
MHA 的出現就是解決MySQL 單點的問題。
MySQL故障切換過程中,MHA能做到0-30秒內自動完成故障切換操作。
MHA能在故障切換的過程中最大程度上保證資料的一致性,以達到真正意義上的高可用。
1、MHA 的組成
●MHA Node(資料節點)
MHA Node 執行在每臺 MySQL 伺服器上。
●MHA Manager(管理節點)
MHA Manager 可以單獨部署在一臺獨立的機器上,管理多個 master-slave 叢集;也可以部署在一臺 slave 節點上。
MHA Manager 會定時探測叢集中的 master 節點。當 master 出現故障時,它可以自動將最新資料的 slave 提升為新的 master, 然後將所有其他的 slave 重新指向新的 master。整個故障轉移過程對應用程式完全透明。
2、MHA 的特點
- 自動故障切換過程中,MHA試圖從宕機的主伺服器上儲存二進位制日誌,最大程度的保證資料不丟失
- 使用半同步複製,可以大大降低資料丟失的風險,如果只有一個slave已經收到了最新的二進位制日誌,MHA可以將最新的二進位制日誌應用於其他所有的slave伺服器上,因此可以保證所有節點的資料一致性
- 目前MHA支援一主多從架構,最少三臺服務,即一主兩從
二、搭建MySQL MHA
實驗思路:
1.MHA架構
- 資料庫安裝
- 一主兩從
- MHA搭建
2.故障模擬
- 主庫失效
- 備選主庫成為主庫
- 原故障主庫恢復重新加入到MHA成為從庫
1、環境準備
1 MHA manager 節點伺服器:CentOS7.4(64 位) manager/192.168.91.20 ,安裝MHA node 和 manager 元件 2 Master 節點伺服器:CentOS7.4(64 位) mysql1/192.168.91.5 ,安裝mysql5.7、MHA node 元件 3 Slave1 節點伺服器:CentOS7.4(64 位) mysql2/192.168.91.10,安裝mysql5.7、MHA node 元件 4 Slave2 節點伺服器:CentOS7.4(64 位) mysql3/192.168.91.15 ,安裝mysql5.7、MHA node 元件 5 6 systemctl stop firewalld7 systemctl disable firewalld 8 setenforce 0
2、修改 Master、Slave1、Slave2 節點的主機名
hostnamectl set-hostname Mysql1 hostnamectl set-hostname Mysql2 hostnamectl set-hostname Mysql3
3、修改 Master、Slave1、Slave2 節點的 Mysql主配置檔案/etc/my.cnf
1 ##Master 節點## 2 vim /etc/my.cnf 3 [mysqld] 4 server-id = 1 5 log_bin = master-bin 6 log-slave-updates = true 7 8 systemctl restart mysqld 9 10 ##Slave1、Slave2 節點## 11 vim /etc/my.cnf 12 server-id = 2 #三臺伺服器的 server-id 不能一樣 13 log_bin = master-bin 14 relay-log = relay-log-bin 15 relay-log-index = slave-relay-bin.index 16 17 systemctl restart mysqld
master節點
slave1/2節點
4、在 Master、Slave1、Slave2 節點上都建立兩個軟連結
ln -s /usr/local/mysql/bin/mysql /usr/sbin/ ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/
5、配置 mysql 一主兩從
(1)所有資料庫節點進行 mysql 授權
1 mysql -uroot -p 2 grant replication slave on *.* to 'myslave'@'192.168.91.%' identified by '411526'; #從資料庫同步使用 3 grant all privileges on *.* to 'mha'@'192.168.91.%' identified by '411526'; #manager 使用 4 5 grant all privileges on *.* to 'mha'@'Mysql1' identified by '411526'; #防止從庫通過主機名連線不上主庫 6 grant all privileges on *.* to 'mha'@'Mysql2' identified by '411526'; 7 grant all privileges on *.* to 'mha'@'Mysql3' identified by '411526'; 8 flush privileges;
(2)在 Master 節點檢視二進位制檔案和同步點
show master status; +-------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +-------------------+----------+--------------+------------------+-------------------+ | master-bin.000001 | 1215 | | | | +-------------------+----------+--------------+------------------+-------------------+
(3)在 Slave1、Slave2 節點執行同步操作
change master to master_host='192.168.80.10',master_user='myslave',master_password='123',master_log_file='master-bin.000001',master_log_pos=1215; start slave; #開啟同步
(4)在 Slave1、Slave2 節點檢視資料同步結果
show slave status\G //確保 IO 和 SQL 執行緒都是 Yes,代表同步正常。 Slave_IO_Running: Yes Slave_SQL_Running: Yes
(5)兩個從庫必須設定為只讀模式
set global read_only=1;
(6)插入資料測試資料庫同步
##在 Master 主庫插入條資料,測試是否同步## create database big; use big; create table test(id int); insert into test(id) values (1);
6、安裝 MHA 軟體
(1)所有伺服器上都安裝 MHA 依賴的環境,首先安裝 epel 源
1 yum install epel-release --nogpgcheck -y 2 3 yum install -y perl-DBD-MySQL \ 4 perl-Config-Tiny \ 5 perl-Log-Dispatch \ 6 perl-Parallel-ForkManager \ 7 perl-ExtUtils-CBuilder \ 8 perl-ExtUtils-MakeMaker \ 9 perl-CPAN
(2)安裝 MHA 軟體包,所有伺服器上必須先安裝 node 元件
1 對於每個作業系統版本不一樣,這裡 CentOS7.4 必須選擇 0.57 版本。 2 在所有伺服器上必須先安裝 node 元件,最後在 MHA-manager 節點上安裝 manager 元件,因為 manager 依賴 node 元件。 3 cd /opt 4 tar zxvf mha4mysql-node-0.57.tar.gz 5 cd mha4mysql-node-0.57 6 perl Makefile.PL 7 make && make install
(3)在 MHA manager 節點上安裝 manager 元件
cd /opt tar zxvf mha4mysql-manager-0.57.tar.gz cd mha4mysql-manager-0.57 perl Makefile.PL make && make install
1 #manager 元件安裝後在/usr/local/bin 下面會生成幾個工具,主要包括以下幾個: 2 masterha_check_ssh 檢查 MHA 的 SSH 配置狀況 3 masterha_check_repl 檢查 MySQL 複製狀況 4 masterha_manger 啟動 manager的指令碼 5 masterha_check_status 檢測當前 MHA 執行狀態 6 masterha_master_monitor 檢測 master 是否宕機 7 masterha_master_switch 控制故障轉移(自動或者手動) 8 masterha_conf_host 新增或刪除配置的 server 資訊 9 masterha_stop 關閉manager 10 11 #node 元件安裝後也會在/usr/local/bin 下面會生成幾個指令碼(這些工具通常由 MHAManager 的指令碼觸發,無需人為操作)主要如下: 12 save_binary_logs 儲存和複製 master 的二進位制日誌 13 apply_diff_relay_logs 識別差異的中繼日誌事件並將其差異的事件應用於其他的 slave 14 filter_mysqlbinlog 去除不必要的 ROLLBACK 事件(MHA 已不再使用這個工具) 15 purge_relay_logs 清除中繼日誌(不會阻塞 SQL 執行緒)
7、在所有伺服器上配置無密碼認證
(1)在 manager 節點上配置到所有資料庫節點的無密碼認證
ssh-keygen -t rsa #一路按回車鍵 ssh-copy-id 192.168.91.5 ssh-copy-id 192.168.91.10 ssh-copy-id 192.168.91.15
(2)在 mysql1 上配置到資料庫節點 mysql2 和 mysql3 的無密碼認證
ssh-keygen -t rsa ssh-copy-id 192.168.91.10 ssh-copy-id 192.168.91.15
(3)在 mysql2 上配置到資料庫節點 mysql1 和 mysql3 的無密碼認證
ssh-keygen -t rsa ssh-copy-id 192.168.91.5 ssh-copy-id 192.168.91.15
(4)在 mysql3 上配置到資料庫節點 mysql1 和 mysql2 的無密碼認證
ssh-keygen -t rsa ssh-copy-id 192.168.91.5 ssh-copy-id 192.168.91.10
8、在 manager 節點上配置 MHA
(1)在 manager 節點上覆制相關指令碼到/usr/local/bin 目錄
1 cp -rp /opt/mha4mysql-manager-0.57/samples/scripts /usr/local/bin 2 //拷貝後會有四個執行檔案 3 ll /usr/local/bin/scripts/ 4 ---------------------------------------------------------------------------------------------------------- 5 master_ip_failover #自動切換時 VIP 管理的指令碼 6 master_ip_online_change #線上切換時 vip 的管理 7 power_manager #故障發生後關閉主機的指令碼 8 send_report #因故障切換後傳送報警的指令碼 9 ----------------------------------------------------------------------------------------------------------
(2)複製上述的自動切換時 VIP 管理的指令碼到 /usr/local/bin 目錄,這裡使用master_ip_failover指令碼來管理 VIP 和故障切換
cp /usr/local/bin/scripts/master_ip_failover /usr/local/bin #也可以全部複製過來
(3)修改內容如下:(刪除原有內容,直接複製並修改vip相關引數)
#!/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.91.123'; my $brdc = '192.168.91.255'; my $ifdev = 'ens33'; my $key = '1'; my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip"; my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down"; my $exit_code = 0; #my $ssh_start_vip = "/usr/sbin/ip addr add $vip/24 brd $brdc dev $ifdev label $ifdev:$key;/usr/sbin/arping -q -A -c 1 -I $ifdev $vip;iptables -F;"; #my $ssh_stop_vip = "/usr/sbin/ip addr del $vip/24 dev $ifdev label $ifdev:$key"; ################################################################################## GetOptions( 'command=s' => \$command, 'ssh_user=s' => \$ssh_user, 'orig_master_host=s' => \$orig_master_host, 'orig_master_ip=s' => \$orig_master_ip, 'orig_master_port=i' => \$orig_master_port, 'new_master_host=s' => \$new_master_host, 'new_master_ip=s' => \$new_master_ip, 'new_master_port=i' => \$new_master_port, ); exit &main(); sub main { print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n"; if ( $command eq "stop" || $command eq "stopssh" ) { my $exit_code = 1; eval { print "Disabling the VIP on old master: $orig_master_host \n"; &stop_vip(); $exit_code = 0; }; if ($@) { warn "Got Error: $@\n"; exit $exit_code; } exit $exit_code; } elsif ( $command eq "start" ) { my $exit_code = 10; eval { print "Enabling the VIP - $vip on the new master - $new_master_host \n"; &start_vip(); $exit_code = 0; }; if ($@) { warn $@; exit $exit_code; } exit $exit_code; } elsif ( $command eq "status" ) { print "Checking the Status of the script.. OK \n"; exit 0; } else { &usage(); exit 1; } } sub start_vip() { `ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`; } ## A simple system call that disable the VIP on the old_master sub stop_vip() { `ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`; } sub usage { print "Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n"; }
(4)建立 MHA 軟體目錄並拷貝配置檔案,這裡使用app1.cnf配置檔案來管理 mysql 節點伺服器
1 mkdir /etc/masterha 2 cp /opt/mha4mysql-manager-0.57/samples/conf/app1.cnf /etc/masterha 3 4 vim /etc/masterha/app1.cnf #刪除原有內容,直接複製並修改節點伺服器的IP地址 5 [server default] 6 manager_log=/var/log/masterha/app1/manager.log 7 manager_workdir=/var/log/masterha/app1 8 master_binlog_dir=/usr/local/mysql/data 9 master_ip_failover_script=/usr/local/bin/master_ip_failover 10 master_ip_online_change_script=/usr/local/bin/master_ip_online_change 11 password=411526 12 ping_interval=1 13 remote_workdir=/tmp 14 repl_password=411526 15 repl_user=sdy 16 secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.91.10 -s 192.168.91.15 17 shutdown_script="" 18 ssh_user=root 19 user=mha 20 21 [server1] 22 hostname=192.168.91.5 23 port=3306 24 25 [server2] 26 candidate_master=1 27 check_repl_delay=0 28 hostname=192.168.91.10 29 port=3306 30 31 [server3] 32 hostname=192.168.91.15 33 port=3306
9、第一次配置需要在 Master 節點上手動開啟虛擬IP
/sbin/ifconfig ens33:1 192.168.91.123/24
10、在 manager 節點上測試 ssh 無密碼認證,如果正常最後會輸出 successfully。
masterha_check_ssh -conf=/etc/masterha/app1.cnf
11、在 manager 節點上測試 mysql 主從連線情況,最後出現 MySQL Replication Health is OK 字樣說明正常。如下所示。
masterha_check_repl -conf=/etc/masterha/app1.cnf
12、在 manager 節點上啟動 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 &
13、檢視 MHA 狀態,可以看到當前的 master 是 Mysql1 節點。
masterha_check_status --conf=/etc/masterha/app1.cnf
14.、檢視 MHA 日誌,也以看到當前的 master 是 192.168.91.5,如下所示。
cat /var/log/masterha/app1/manager.log | grep "current master"
15、檢視 Mysql1 的 VIP 地址 192.168.91.123 是否存在,這個 VIP 地址不會因為 manager 節點停止 MHA 服務而消失。
ifconfig //若要關閉 manager 服務,可以使用如下命令。 masterha_stop --conf=/etc/masterha/app1.cnf 或者可以直接採用 kill 程序 ID 的方式關閉。
故障模擬
1 ---------------------- 故障模擬 -------------------------------- 2 #在 manager 節點上監控觀察日誌記錄 3 tail -f /var/log/masterha/app1/manager.log 4 5 #在 Master 節點 Mysql1 上停止mysql服務 6 systemctl stop mysqld 7 或 8 pkill -9 mysql 9 10 #正常自動切換一次後,MHA 程序會退出。HMA 會自動修改 app1.cnf 檔案內容,將宕機的 mysql1 節點刪除。檢視 mysql2 是否接管 VIP 11 ifconfig 12 13 故障切換備選主庫的演算法: 14 1.一般判斷從庫的是從(position/GTID)判斷優劣,資料有差異,最接近於master的slave,成為備選主。 15 2.資料一致的情況下,按照配置檔案順序,選擇備選主庫。 16 3.設定有權重(candidate_master=1),按照權重強制指定備選主。 17 (1)預設情況下如果一個slave落後master 100M的relay logs的話,即使有權重,也會失效。 18 (2)如果check_repl_delay=0的話,即使落後很多日誌,也強制選擇其為備選主。 19 20 故障修復步驟: 21 1.修復mysql 22 systemctl restart mysqld 23 24 2.修復主從 25 #在現主庫伺服器 Mysql2 檢視二進位制檔案和同步點 26 show master status; 27 28 #在原主庫伺服器 mysql1 執行同步操作 29 change master to master_host='192.168.91.10',master_user='sdy',master_password='411526',master_log_file='master-bin.000001',master_log_pos=1745; 30 31 start slave; 32 33 34 3.在 manager 節點上修改配置檔案app1.cnf(再把這個記錄新增進去,因為它檢測掉失效時候會自動消失) 35 vi /etc/masterha/app1.cnf 36 ...... 37 secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.91.5 -s 192.168.91.15 38 ...... 39 [server1] 40 hostname=192.168.91.10 41 port=3306 42 43 [server2] 44 candidate_master=1 45 check_repl_delay=0 46 hostname=192.168.91.5 47 port=3306 48 49 [server3] 50 hostname=192.168.91.15 51 port=3306 52 53 4.在 manager 節點上啟動 MHA 54 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 & 55 56 57 58 #解決中英字不相容報錯的問題 59 dos2unix /usr/local/bin/master_ip_failover
在 manager 節點上監控觀察日誌記錄
Mysql1 上停止mysql服務
故障修復操作
修復主從
在現主庫伺服器 Mysql2 檢視二進位制檔案和同步點
在原主庫伺服器 mysql1 執行同步操作
在 manager 節點上修改配置檔案app1.cnf(再把這個記錄新增進去,因為它檢測掉失效時候會自動消失)
在 manager 節點上啟動 MHA