1. 程式人生 > 其它 >MySQL MHA高可用叢集部署及故障切換

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架構

  1. 資料庫安裝
  2. 一主兩從
  3. MHA搭建

2.故障模擬

  1. 主庫失效
  2. 備選主庫成為主庫
  3. 原故障主庫恢復重新加入到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 firewalld
7 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),按照權重強制指定備選主。
171)預設情況下如果一個slave落後master 100M的relay logs的話,即使有權重,也會失效。
182)如果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