1. 程式人生 > 其它 >MySQL之MHA高可用配置及故障切換

MySQL之MHA高可用配置及故障切換

一、MHA的概述

1、 MHA的概念

2.MHA 的組成

3.MHA 的特點

二、搭建 MySQL MHA的操作步驟

1、實驗思路

2、環境準備

3、修改 Master、Slave1、Slave2 節點的主機名

4、修改 Master、Slave1、Slave2 節點的 Mysql主配置檔案/etc/my.cnf

5、在 Master、Slave1、Slave2 節點上都建立兩個軟連結

6、配置 mysql 一主兩從

7、安裝 MHA 軟體

8.在所有伺服器上配置無密碼認證

9.在 manager 節點上配置 MHA

10.第一次配置需要在 Master 節點上手動開啟虛擬IP

11、在 manager 節點上測試 ssh 無密碼認證

12、在 manager 節點上測試 mysql 主從連線情況

13.在 manager 節點上啟動 MHA

14、檢視 MHA 狀態,可以看到當前的 master 是 Mysql1 節點。

15. 檢視 MHA 日誌,也以看到當前的 master 是 192.168.229.90

16.、檢視 Mysql1 的 VIP 地址 192.168.229.200 是否存在

三、故障模擬以及故障恢復的步驟

1、故障模擬

2、故障切換備選主庫的演算法

3、故障修復步驟

一、MHA的概述

1、 MHA的概念

MHA(MasterHigh Availability)是一套優秀的MySQL高可用環境下故障切換和主從複製的軟體。

MHA 的出現就是解決MySQL 單點的問題。

MySQL故障切換過程中,MHA能做到0-30秒內自動完成故障切換操作。

MHA能在故障切換的過程中最大程度上保證資料的一致性,以達到真正意義上的高可用。

2.MHA 的組成

MHA Node(資料節點)

MHA Node 執行在每臺 MySQL 伺服器上。

MHA Manager(管理節點)

MHA Manager 可以單獨部署在一臺獨立的機器上,管理多個 master-slave 叢集;也可以部署在一臺 slave 節點上。

MHA Manager 會定時探測叢集中的 master 節點。當 master 出現故障時,它可以自動將最新資料的 slave 提升為新的 master, 然後將所有其他的 slave 重新指向新的 master。整個故障轉移過程對應用程式完全透明。

3.MHA 的特點

自動故障切換過程中,MHA試圖從宕機的主伺服器上儲存二進位制日誌,最大程度的保證資料不丟失

使用半同步複製,可以大大降低資料丟失的風險,如果只有一個slave已經收到了最新的二進位制日誌,MHA可以將最新的二進位制日誌應用於其他所有的slave伺服器上,因此可以保證所有節點的資料一致性

目前MHA支援一主多從架構,最少三臺服務,即一主兩從

二、搭建 MySQL MHA的操作步驟

1、實驗思路:

1.1、MHA架構

1)資料庫安裝

2)一主兩從

3)MHA搭建

1.2、故障模擬

1)主庫失效

2)備選主庫成為主庫

3)原故障主庫恢復重新加入到MHA成為從庫

2、環境準備

MHA manager 節點伺服器:CentOS7.4(64 位) manager/192.168.229.50,安裝MHA node 和 manager 元件

Master 節點伺服器:CentOS7.4(64 位) mysql1/192.168.229.90,安裝mysql5.7、MHA node 元件

Slave1 節點伺服器:CentOS7.4(64 位) mysql2/192.168.229.80,安裝mysql5.7、MHA node 元件

Slave2 節點伺服器:CentOS7.4(64 位) mysql3/192.168.229.70,安裝mysql5.7、MHA node 元件

systemctl stop firewalld
systemctl disable firewalld
setenforce 0  
關閉防火牆

3、修改 Master、Slave1、Slave2 節點的主機名

Master、Slave1、Slave2 節點上安裝 mysql5.7

hostnamectl set-hostname Mysql1
hostnamectl set-hostname Mysql2
hostnamectl set-hostname Mysql3  
改名

4、修改 Master、Slave1、Slave2 節點的 Mysql主配置檔案/etc/my.cnf

Master 節點

vim /etc/my.cnf
[mysqld]
server-id = 1
log_bin = master-bin
log-slave-updates = true
 
systemctl restart mysqld 

Slave1、Slave2 節點

vim /etc/my.cnf
server-id = 2 #三臺伺服器的 server-id 不能一樣
log_bin = master-bin
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.index
 
systemctl restart mysqld  

5、在 Master、Slave1、Slave2 節點上都建立兩個軟連結

ln -s /usr/local/mysql/bin/mysql /usr/sbin/
ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/ 

6、配置 mysql 一主兩從

(1)所有資料庫節點進行 mysql 授權

mysql -uroot -p
grant replication slave on *.* to 'myslave'@'192.168.229.%' identified by '12345';  #從資料庫同步使用
grant all privileges on *.* to 'mha'@'192.168.229.%' identified by 'manager';   #manager 使用
 
grant all privileges on *.* to 'mha'@'Mysql1' identified by 'manager';  #防止從庫通過主機名連線不上主庫
grant all privileges on *.* to 'mha'@'Mysql2' identified by 'manager';
grant all privileges on *.* to 'mha'@'Mysql3' identified by 'manager';
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.229.90',master_user='myslave',master_password='12345',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 test_db;
use test_db;
create table test(id int);
insert into test(id) values (1);

7、安裝 MHA 軟體

(1)所有伺服器上都安裝 MHA 依賴的環境,首先安裝 epel 源

yum install epel-release --nogpgcheck -y
 
yum install -y perl-DBD-MySQL \
perl-Config-Tiny \
perl-Log-Dispatch \
perl-Parallel-ForkManager \
perl-ExtUtils-CBuilder \
perl-ExtUtils-MakeMaker \
perl-CPAN  

(2)安裝 MHA 軟體包,先在所有伺服器上必須先安裝 node 元件

對於每個作業系統版本不一樣,這裡 CentOS7.4 必須選擇 0.57 版本。

在所有伺服器上必須先安裝 node 元件,最後在 MHA-manager 節點上安裝 manager 元件,因為 manager 依賴 node 元件。

cd /opt
tar zxvf mha4mysql-node-0.57.tar.gz
cd mha4mysql-node-0.57
perl Makefile.PL
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  

#manager 元件安裝後在/usr/local/bin 下面會生成幾個工具,主要包括以下幾個:

masterha_check_ssh 檢查 MHA 的 SSH 配置狀況

masterha_check_repl 檢查 MySQL 複製狀況

masterha_manger 啟動 manager的指令碼

masterha_check_status 檢測當前 MHA 執行狀態

masterha_master_monitor 檢測 master 是否宕機

masterha_master_switch 控制故障轉移(自動或者手動)

masterha_conf_host 新增或刪除配置的 server 資訊

masterha_stop 關閉manager

#node 元件安裝後也會在/usr/local/bin 下面會生成幾個指令碼(這些工具通常由 MHAManager 的指令碼觸發,無需人為操作)主要如下:

save_binary_logs 儲存和複製 master 的二進位制日誌

apply_diff_relay_logs 識別差異的中繼日誌事件並將其差異的事件應用於其他的 slave

filter_mysqlbinlog 去除不必要的 ROLLBACK 事件(MHA 已不再使用這個工具)

purge_relay_logs 清除中繼日誌(不會阻塞 SQL 執行緒)

8.在所有伺服器上配置無密碼認證

(1)在 manager 節點上配置到所有資料庫節點的無密碼認證

ssh-keygen -t rsa #一路按回車鍵
ssh-copy-id 192.168.229.80
ssh-copy-id 192.168.229.70
ssh-copy-id 192.168.229.90

(2)在 mysql1 上配置到資料庫節點 mysql2 和 mysql3 的無密碼認證

ssh-keygen -t rsa
ssh-copy-id 192.168.229.80
ssh-copy-id 192.168.229.70  

(3)在 mysql2 上配置到資料庫節點 mysql1 和 mysql3 的無密碼認證

ssh-keygen -t rsa
ssh-copy-id 192.168.229.90
ssh-copy-id 192.168.229.80 

(4)在 mysql3 上配置到資料庫節點 mysql1 和 mysql2 的無密碼認證

ssh-keygen -t rsa
ssh-copy-id 192.168.229.90
ssh-copy-id 192.168.229.80

9.在 manager 節點上配置 MHA

(1)在 manager 節點上覆制相關指令碼到/usr/local/bin 目錄

cp -rp /opt/mha4mysql-manager-0.57/samples/scripts /usr/local/bin 

//拷貝後會有四個執行檔案ll /usr/local/bin/scripts/

master_ip_failover #自動切換時 VIP 管理的指令碼

master_ip_online_change #線上切換時 vip 的管理

power_manager #故障發生後關閉主機的指令碼

send_report #因故障切換後傳送報警的指令碼

(2)複製上述的自動切換時 VIP 管理的指令碼到 /usr/local/bin 目錄,這裡使用master_ip_failover指令碼來管理 VIP 和故障切換

cp /usr/local/bin/scripts/master_ip_failover /usr/local/bin

(3)修改內容如下:(刪除原有內容,直接複製並修改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.229.200';    #指定vip的地址
my $brdc = '192.168.229.255';   #指定vip的廣播地址
my $ifdev = 'ens33';    #指定vip繫結的網絡卡
my $key = '1';  #指定vip繫結的虛擬網絡卡序列號
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";   #代表此變數值為ifconfig ens33:1 192.168.229.200
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down";    #代表此變數值為ifconfig ens33:1 192.168.229.200 down
my $exit_code = 0;  #指定退出狀態碼為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 節點伺服器

mkdir /etc/masterha
cp /opt/mha4mysql-manager-0.57/samples/conf/app1.cnf /etc/masterha
 
vim /etc/masterha/app1.cnf  #刪除原有內容,直接複製並修改節點伺服器的IP地址
[server default]
manager_log=/var/log/masterha/app1/manager.log
manager_workdir=/var/log/masterha/app1
master_binlog_dir=/usr/local/mysql/data
master_ip_failover_script=/usr/local/bin/master_ip_failover
master_ip_online_change_script=/usr/local/bin/master_ip_online_change
password=manager
ping_interval=1
remote_workdir=/tmp
repl_password=12345
repl_user=myslave
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.229.80 -s 192.168.229.70
shutdown_script=""
ssh_user=root
user=mha
 
[server1]
hostname=192.168.229.90
port=3306
 
[server2]
candidate_master=1
check_repl_delay=0
hostname=192.168.229.80
port=3306
 
[server3]
hostname=192.168.229.70
port=3306

解釋:

[server default]
manager_log=/var/log/masterha/app1/manager.log                         #manager日誌
manager_workdir=/var/log/masterha/app1.log                            #manager工作目錄
master_binlog_dir=/usr/local/mysql/data/                             #master儲存binlog的位置,這裡的路徑要與master裡配置的binlog的路徑一致,以便MHA能找到
master_ip_failover_script=/usr/local/bin/master_ip_failover              #設定自動failover時候的切換指令碼,也就是上面的那個指令碼
master_ip_online_change_script=/usr/local/bin/master_ip_online_change    #設定手動切換時候的切換指令碼
password=manager                                                       #設定mysql中root使用者的密碼,這個密碼是前文中建立監控使用者的那個密碼
ping_interval=1                                                            #設定監控主庫,傳送ping包的時間間隔,預設是3秒,嘗試三次沒有迴應的時候自動進行failover
remote_workdir=/tmp                                                    #設定遠端mysql在發生切換時binlog的儲存位置
repl_password=12345                                                    #設定複製使用者的密碼
repl_user=myslave                                                      #設定複製使用者的使用者
report_script=/usr/local/send_report                                    #設定發生切換後傳送的報警的指令碼
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.229.80 -s 192.168.229.70  #指定檢查的從伺服器IP地址
shutdown_script=""                                                      #設定故障發生後關閉故障主機指令碼(該指令碼的主要作用是關閉主機防止發生腦裂,這裡沒有使用)
ssh_user=root                                                               #設定ssh的登入使用者名稱
user=mha                                                                #設定監控使用者root
 
[server1]
hostname=192.168.229.90
port=3306
 
[server2]
hostname=192.168.229.80
port=3306
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
 
[server3]
hostname=192.168.229.70
port=3306

10.第一次配置需要在 Master 節點上手動開啟虛擬IP

/sbin/ifconfig ens33:1 192.168.229.200/24 

11、在 manager 節點上測試 ssh 無密碼認證,如果正常最後會輸出 successfully,如下所示。

masterha_check_ssh -conf=/etc/masterha/app1.cnf
 
Tue Nov 26 23:09:45 2020 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Tue Nov 26 23:09:45 2020 - [info] Reading application default configuration from /etc/masterha/app1.cnf..
Tue Nov 26 23:09:45 2020 - [info] Reading server configuration from /etc/masterha/app1.cnf..
Tue Nov 26 23:09:45 2020 - [info] Starting SSH connection tests..
Tue Nov 26 23:09:46 2020 - [debug]
Tue Nov 26 23:09:45 2020 - [debug] Connecting via SSH from root@192.168.229.80(192.168.229.80:22) to root@192.168.229.70(192.168.229.70:22)..
Tue Nov 26 23:09:46 2020 - [debug] ok.
Tue Nov 26 23:09:47 2020 - [debug]
Tue Nov 26 23:09:46 2020 - [debug] Connecting via SSH from root@192.168.229.80(192.168.229.80:22) to root@192.168.229.70(192.168.229.70:22)..
Tue Nov 26 23:09:47 2020 - [debug] ok.
Tue Nov 26 23:09:47 2020 - [info] All SSH connection tests passed successfully.

12、在 manager 節點上測試 mysql 主從連線情況,最後出現 MySQL Replication Health is OK 字樣說明正常。如下所示。

masterha_check_repl -conf=/etc/masterha/app1.cnf
[root@192 masterha]# masterha_check_ssh -conf=/etc/masterha/app1.cnf
Tue Sep  7 12:51:38 2021 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Tue Sep  7 12:51:38 2021 - [info] Reading application default configuration from /etc/masterha/app1.cnf..
Tue Sep  7 12:51:38 2021 - [info] Reading server configuration from /etc/masterha/app1.cnf..
Tue Sep  7 12:51:38 2021 - [info] Starting SSH connection tests..
Tue Sep  7 12:51:39 2021 - [debug]
Tue Sep  7 12:51:38 2021 - [debug]  Connecting via SSH from root@192.168.229.90(192.168.229.90:22) to root@192.168.229.80(192.168.229.80:22)..
Tue Sep  7 12:51:38 2021 - [debug]   ok.
Tue Sep  7 12:51:38 2021 - [debug]  Connecting via SSH from root@192.168.229.90(192.168.229.90:22) to root@192.168.229.70(192.168.229.70:22)..
Tue Sep  7 12:51:38 2021 - [debug]   ok.
Tue Sep  7 12:51:39 2021 - [debug]
Tue Sep  7 12:51:38 2021 - [debug]  Connecting via SSH from root@192.168.229.80(192.168.229.80:22) to root@192.168.229.90(192.168.229.90:22)..
Tue Sep  7 12:51:38 2021 - [debug]   ok.
Tue Sep  7 12:51:38 2021 - [debug]  Connecting via SSH from root@192.168.229.80(192.168.229.80:22) to root@192.168.229.70(192.168.229.70:22)..
Tue Sep  7 12:51:39 2021 - [debug]   ok.
Tue Sep  7 12:51:40 2021 - [debug]
Tue Sep  7 12:51:39 2021 - [debug]  Connecting via SSH from root@192.168.229.70(192.168.229.70:22) to root@192.168.229.90(192.168.229.90:22)..
Tue Sep  7 12:51:39 2021 - [debug]   ok.
Tue Sep  7 12:51:39 2021 - [debug]  Connecting via SSH from root@192.168.229.70(192.168.229.70:22) to root@192.168.229.80(192.168.229.80:22)..
Tue Sep  7 12:51:39 2021 - [debug]   ok.
Tue Sep  7 12:51:40 2021 - [info] All SSH connection tests passed successfully. 

13.在 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 & 

解釋

--remove_dead_master_conf:該引數代表當發生主從切換後,老的主庫的 ip 將會從配置檔案中移除。
--manger_log:日誌存放位置。
--ignore_last_failover:在預設情況下,如果 MHA 檢測到連續發生宕機,且兩次宕機間隔不足 8 小時的話,則不會進行 Failover, 之所以這樣限制是為了避免 ping-pong 效應。該引數代表忽略上次 MHA 觸發切換產生的檔案,預設情況下,MHA 發生切換後會在日誌記目錄,也就是上面設定的日誌app1.failover.complete檔案,下次再次切換的時候如果發現該目錄下存在該檔案將不允許觸發切換,除非在第一次切換後收到刪除該檔案,為了方便,這裡設定為--ignore_last_failover。

14、檢視 MHA 狀態,可以看到當前的 master 是 Mysql1 節點。

masterha_check_status --conf=/etc/masterha/app1.cnf  

15. 檢視 MHA 日誌,也以看到當前的 master 是 192.168.229.90,如下所示。

cat /var/log/masterha/app1/manager.log | grep "current master" 

16.檢視 Mysql1 的 VIP 地址 192.168.229.200 是否存在,這個 VIP 地址不會因為 manager 節點停止 MHA 服務而消失。

ifconfig

//若要關閉 manager 服務,可以使用如下命令。

masterha_stop --conf=/etc/masterha/app1.cnf

或者可以直接採用 kill 程序 ID 的方式關閉。

三、故障模擬以及故障恢復的步驟

1、故障模擬

#在 manager 節點上監控觀察日誌記錄

tail -f /var/log/masterha/app1/manager.log 

#在 Master 節點 Mysql1 上停止mysql服務

systemctl stop mysqld或pkill -9 mysql

#正常自動切換一次後,MHA 程序會退出。HMA 會自動修改 app1.cnf 檔案內容,將宕機的 mysql1 節點刪除。檢視 mysql2 是否接管 VIP

ifconfig

2、故障切換備選主庫的演算法:

一般判斷從庫的是從(position/GTID)判斷優劣,資料有差異,最接近於master的slave,成為備選主。

資料一致的情況下,按照配置檔案順序,選擇備選主庫。

設定有權重(candidate_master=1),按照權重強制指定備選主。

(1)預設情況下如果一個slave落後master 100M的relay logs的話,即使有權重,也會失效。

(2)如果check_repl_delay=0的話,即使落後很多日誌,也強制選擇其為備選主

3、故障修復步驟:

3.1.修復mysql

systemctl restart mysqld 

3.2.修復主從

#在現主庫伺服器 Mysql2 檢視二進位制檔案和同步點

show master status; 

#在原主庫伺服器 mysql1 執行同步操作

change master to master_host='192.168.229.80',master_user='myslave',master_password='12345',master_log_file='master-bin.000001',master_log_pos=1745;
 
start slave; 

3.3.在 manager 節點上修改配置檔案app1.cnf(再把這個記錄新增進去,因為它檢測掉失效時候會自動消失)

vi /etc/masterha/app1.cnf
......
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.229.90 -s 192.168.229.70
......
[server1]
hostname=192.168.229.80
port=3306
 
[server2]
candidate_master=1
check_repl_delay=0
hostname=192.168.229.90
port=3306
 
[server3]
hostname=192.168.229.70
port=3306  

3.4.在 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 & 

#解決中英字不相容報錯的問題

dos2unix /usr/local/bin/master_ip_failover