MHA高可用配置及故障切換——詳細部署步驟及報錯解決辦法
https://my.oschina.net/u/4305437/blog/4630031
搭建參考文件:
==========================================================================================================================
- 一、瞭解MHA高可用叢集部署
- 二、對三臺主機(mysql1,mysql2,mysql3)安裝mysql資料庫
- 三、對mysql1,mysql2,mysql3配置主從同步
- 四、 配置無密碼認證
- 五、對所有主機manager,mysql1、mysql2、mysql3安裝cmake-2.8.6.tar.gz
- 六、安裝MHA並配置MHA
- 七、模擬故障測試
- 八,將菪機的mysql1恢復為master
-
- 1.先將mysql1設定成master(mysql2)的從伺服器,設定只讀
- 2.關掉當前master(mysql2)的同步功能,否則從伺服器會報錯
- 3.手動修改manager上的app1.cnf配置
- 4. 檢查無密碼認證和 MySQL 主從狀態是否正常,請參考之前的步驟,這裡不再列出。
- 5.檢視當前主庫master
- 6.關閉MAH
- 7.在manager上手動關閉當前master(mysql2)
- 8.再次檢視,master已經關閉
- 9.將手動切換指令碼拷貝到/usr/local/bin/下,並進行配置修改
- 10. 在manager上手動設定新的master(mysql1)
- 11.在manager上檢視master是否真的轉換
- 九、常見報錯
-
-
-
-
- 問題1:[warning] relay_log_purge=0 is not set on slave 20.0.0.22(20.0.0.22:3)
- 問題2:[warning] log-bin is not set on slave 20.0.0.23(20.0.0.23:3306)
- 問題3:mysqlbinlog: unknown variable ‘default-character-set=utf8‘
- 問題4:如果在執行過程中,有如下報錯資訊:Can't exec "mysqlbinlog": No such file or directory at /usr/lib64/perl5/vendor_perl/MHA/BinlogManager.pm line 99.
- 問題5:如果有如下報錯資訊:Bareword "FIXME_xxx" not allowed while "strict subs" in use at /usr/local/bin/master_ip_failover line 100.:
-
-
-
一、瞭解MHA高可用叢集部署
1.傳統的MySQL主從架構存在的問題
- 只有一臺主伺服器負責寫入
- 存在單點故障
2.MHA概述
- MHA (MasterHigh Availability)E前在MySQL高可用方面是一個相對成熟的解決方案,它由日本 DeNA公司youshimaton(現就職於Facebook公司)開發的
- —套優秀的MySQL高可用環境下故障切換和主從複製的軟體
- MySQL故障過程中,MHA能做到O-30秒內自動完成故障切換
- 並且在進行故障切換的過程中,MHA能在最大程度上保證資料的一致性,以達到真正意義上的高可用。
3.MHA的組成
- MHA Manager(管理節點)
- MHA Node(資料節點)
4.MHA特點
- 自動故障切換過程中,MHA試圖從宕機的主伺服器上儲存二進位制日誌,最大程度的保證資料不丟失
- 使用半同步複製,可以大大降低資料丟失的風險
- 目前MHA支援一主多從架構,最少三臺服務,即一主兩從
5.MHA工作原理
該軟體由兩部分組成:MHA Manager(管理節點)和MHA Node(資料節點)。MHAManager可以單獨部署在一臺獨立的機器上,管理多個master-slave叢集;也可以部署在一臺slave 節點上。MHA Node執行在每臺MySQL伺服器上,MHA_Manager會定時探測叢集中的master 節點。當master 出現故障時,它可以自動將最新資料的slave提升為新的master,然後將所有其他的slave重新指向新的master。整個故障轉移過程對應用程式完全透明。
在MHA自動故障切換過程中,MHA試圖從宕機的主伺服器上儲存二進位制日誌,最大程度的保證資料的不丟失,但這並不總是可行的。例如,如果主伺服器硬體故障或無法通過SSH訪問,MHA 沒法儲存二進位制日誌,就會出現只進行故障轉移但丟失了最新的資料的情況。使用MySQL5.5的半同步複製,可以大大降低資料丟失的風險。MHA可以與半同步複製結合起來。如果只有一個slave已經收到了最新的二進位制日誌,MHA可以將最新的二進位制日誌應用於其他所有的slave伺服器上,因此可以保證所有節點的資料一致性。
6.案例設計
目前MySQL已經成為市場上主流資料庫之一,考慮到業務的重要性,MySQL 資料庫單點問題已成為企業網站架構中大的隱患。隨著技術的發展,MHA的出現就是解決MySQL單點的問題。另外隨著企業資料量越來越龐大,資料庫的壓又成為企業的另一個瓶頸,MySQL多主多從架構的出現可以減輕MySQL本身的壓力。這個實驗主要闡述MHA的搭建和模擬MySQL 故障自動切換的過程。
主機 | 作業系統 | 主機名及地址 | 角色 |
---|---|---|---|
伺服器 | CentOS7.6(64位) | manager/20.0.0.11 | 管理節點,安裝manager元件和node元件 |
伺服器 | CentOS7.6(64位) | Mysql1/20.0.0.12 | Master節點,安裝node元件 |
伺服器 | CentOS7.6(64位) | Mysql2/20.0.0.18 | Slave 節點,安裝node元件 |
伺服器 | CentOS7.6(64位) | Mysql3/20.0.0.19 | Slave節點,安裝node元件 |
二、對三臺主機(mysql1,mysql2,mysql3)安裝mysql資料庫
三、對mysql1,mysql2,mysql3配置主從同步
1.配置mysql1
1.1設定主機名,便於識別
[root@localhost ~]# hostnamectl set-hostname mysql1
[root@mysql1 ~]# bash
1.2 做主機對映
[root@mysql1 ~]# vi /etc/hosts
20.0.0.12 mysql1
1.3 修改資料庫檔案/etc/my.cof配置
[root@mysql1 ~]# vi /etc/my.cnf
[mysqld]
……省略部分
server-id = 11
log-bin = master-bin
log-slave-updates = true
[root@mysql1 ~]# systemctl restart mysqld
[root@mysql1 ~]# ln -s /usr/local/mysql/bin/mysql /usr/sbin/
[root@mysql1 ~]# ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/
1.4 登入資料庫授權
[root@mysql1 ~]# mysql -uroot -p
mysql> grant replication slave on *.* to 'myslave'@'20.0.0.%' identified by '123456';
mysql> grant all privileges on *.* to 'mha'@'20.0.0.%' identified by 'manager';
#######################下面這條授權最好也做一下,防止報錯#####################
mysql>grant all privileges on *.* to 'mha'@'mysql1' identified by 'manager';
##########################################################################
mysql> flush privileges;
1.5 檢視master狀態
mysql> show master status;
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------------------+------------+---------------------+----------------------------+--------------------------+
| master-bin.000001 | 154 | | |
2. 配置mysql1
2.1設定主機名,便於識別
[root@localhost ~]# hostnamectl set-hostname mysql2
[root@mysql2 ~]# bash
2.2 做主機對映
[root@mysql2 ~]# vi /etc/hosts
20.0.0.18 mysql2
2.3 修改資料庫檔案/etc/my.cof配置
[root@mysql2 ~]# vi /etc/my.cnf
[mysqld]
……省略部分
server-id = 22
log-bin = master-bin //這條必須有,因為備選master需要有binlog日誌檔案
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.index
[root@mysql2 ~]# mysql -uroot -p -e 'set global relay_log_purge=0'
[root@mysql2 ~]# systemctl restart mysqld
[root@mysql2 ~]# ln -s /usr/local/mysql/bin/mysql /usr/sbin/
[root@mysql2 ~]# ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/
2.4 登入資料庫授權
[root@mysql2 ~]# mysql -uroot -p
mysql> grant replication slave on *.* to 'myslave'@'20.0.0.%' identified by '123456';
mysql> grant all privileges on *.* to 'mha'@'20.0.0.%' identified by 'manager';
#######################下面這條授權最好也做一下,防止報錯#####################
mysql>grant all privileges on *.* to 'mha'@'mysql2' identified by 'manager';
##########################################################################
mysql> flush privileges;
mysql> change master to master_host='20.0.0.12',
-> master_user='myslave',
-> master_password='123456',
-> master_port=3306,
-> master_log_file='master-bin.000001',
-> master_log_pos=154;
3. 配置mysql3
3.1設定主機名,便於識別
[root@localhost ~]# hostnamectl set-hostname mysql2
[root@mysql1 ~]# bash
3.2 做主機對映
[root@mysql1 ~]# vi /etc/hosts
20.0.0.19 mysql3
3.3 修改資料庫檔案/etc/my.cof配置
[root@mysql1 ~]# vi /etc/my.cnf
[mysqld]
……省略部分
server-id = 33
no_master=1 //no_master表示這個節點不能作為master
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.index
[root@mysql3 ~]# mysql -uroot -p -e 'set global relay_log_purge=0' //清除relay-log殘存
[root@mysql3 ~]# systemctl restart mysqld
[root@mysql3 ~]# ln -s /usr/local/mysql/bin/mysql /usr/sbin/
[root@mysql3 ~]# ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/
3.4 登入資料庫授權
[root@mysql1 ~]# mysql -uroot -p
mysql> grant replication slave on *.* to 'myslave'@'20.0.0.%' identified by '123456';
mysql> grant all privileges on *.* to 'mha'@'20.0.0.%' identified by 'manager';
#######################下面這條授權最好也做一下,防止報錯#####################
mysql>grant all privileges on *.* to 'mha'@'mysql3' identified by 'manager';
##########################################################################
mysql> flush privileges;
mysql> change master to master_host='20.0.0.12',
-> master_user='myslave',
-> master_port=3306,
-> master_password='123456',
-> master_log_file='master-bin.000001',
-> master_log_pos=154;
4.驗證是否同步
4.1主伺服器建庫
mysql> create database 測試庫;
Query OK, 1 row affected (0.01 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| 測試庫 |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
4.2兩臺從伺服器驗證
mysql> show databases; //同步成功
+--------------------+
| Database |
+--------------------+
| information_schema |
| 測試庫 |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
四、 配置無密碼認證
1.在 manager 上配置到所有資料庫節點的無密碼認證
[root@localhost ~]# ssh-keygen -t rsa //一直回車就可以
[root@localhost ~]# ssh-copy-id 20.0.0.18
[root@localhost ~]# ssh-copy-id 20.0.0.12
[root@localhost ~]# ssh-copy-id 20.0.0.19
2.在 mysql1 上配置到所有資料庫節點的無密碼認證
[root@mysql1 ~]# ssh-keygen -t rsa //一直回車就可以
[root@mysql1 ~]# ssh-copy-id 20.0.0.18
[root@mysql1 ~]# ssh-copy-id 20.0.0.12
[root@mysql1 ~]# ssh-copy-id 20.0.0.19
3.在 mysql2 上配置到所有資料庫節點的無密碼認證
[root@mysql2 ~]# ssh-keygen -t rsa //一直回車就可以
[root@mysql2 ~]# ssh-copy-id 20.0.0.18
[root@mysql2 ~]# ssh-copy-id 20.0.0.12
[root@mysql2 ~]# ssh-copy-id 20.0.0.19
4.在 mysql3 上配置到所有資料庫節點的無密碼認證
[root@mysql3 ~]# ssh-keygen -t rsa //一直回車就可以
[root@mysql3 ~]# ssh-copy-id 20.0.0.18
[root@mysql3 ~]# ssh-copy-id 20.0.0.12
[root@mysql3 ~]# ssh-copy-id 20.0.0.19
五、對所有主機manager,mysql1、mysql2、mysql3安裝cmake-2.8.6.tar.gz
[root@localhost ~]# yum -y install ncurses-devel gcc-c++ perl-Module-Install
[root@localhost ~]# tar zxvf cmake-2.8.6.tar.gz -C /opt
[root@localhost ~]# cd /opt/cmake-2.8.6
[root@Mysql1 cmake-2.8.6]# ./configure
[root@Mysql1 cmake-2.8.6]# gmake -j3 && gmake install
六、安裝MHA並配置MHA
1. 所有伺服器上(manager、mysql1、mysql2、mysql3)都安裝 MHA 依賴的環境,首先安裝 epel 源。
[root@localhost ~]# yum install epel-release --nogpgcheck \
perl-DBD-MySQL \
perl-Config-Tiny \
perl-Log-Dispatch \
perl-Parallel-ForkManager \
perl-ExtUtils-CBuilder \
perl-ExtUtils-MakeMaker \
perl-Mail-Sender \
perl-CPAN
2. MHA 軟體包對於每個作業系統版本不一樣,這裡 CentOS7.4 必須選擇 0.57 版本,
在<注意:所有伺服器manager、mysql1、mysql2、mysql3>上必須先安裝 node 元件,最後在 MHA-manager 節點上安裝 manager 元件。因為 manager 依賴 node 元件,下面都是在 Mysql1 上操作演示安裝 node 元件。
[root@localhost ~]# tar zxvf mha4mysql-node-0.57.tar.gz -C /opt
[root@localhost mha4mysql-node-0.57]# cd /opt/mha4mysql-node-0.57/
[root@localhost mha4mysql-node-0.57]# perl Makefile.PL
[root@localhost mha4mysql-node-0.57]# make && make install
[root@localhost mha4mysql-node-0.57]# ls /usr/local/bin
apply_diff_relay_logs filter_mysqlbinlog purge_relay_logs save_binary_logs
node 安裝後也會在/usr/local/bin 下面會生成幾個指令碼(這些工具通常由 MHA_Manager 的指令碼觸發,無需人為操作)主要如下:
save_binary_logs | 儲存和複製 master 的二進位制日誌 |
---|---|
apply_diff_relay_logs | 識別差異的中繼日誌事件並將其差異的事件應用於其他的 slave |
filter_mysqlbinlog | 去除不必要的 ROLLBACK 事件(MHA 已不再使用這個工具) |
purge_relay_logs | 清除中繼日誌(不會阻塞 SQL 執行緒) |
3.在 MHA-manager上安裝 manager 元件(!注意:一定要先安裝node 元件才能安裝manager 元件)
[root@localhost ~]# tar zxvf mha4mysql-manager-0.57.tar.gz -C /opt
[root@localhost ~]# cd /opt/mha4mysql-manager-0.57/
[root@localhost mha4mysql-manager-0.57]# perl Makefile.PL
[root@localhost mha4mysql-manager-0.57]# make && make install
[root@localhost mha4mysql-manager-0.57]# ls /usr/local/bin
masterha_check_repl masterha_check_status masterha_manager masterha_master_switch masterha_stop masterha_check_ssh
masterha_conf_host masterha_master_monitor masterha_secondary_check
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 |
4.在 manager 節點上覆制相關指令碼到/usr/local/bin 目錄
[root@localhost ~]# cp -ra /opt/mha4mysql-manager-0.57/samples/scripts/ /usr/local/bin/
[root@localhost ~]# ls /usr/local/bin/scripts/
master_ip_failover master_ip_online_change power_manager send_report
[root@localhost ~]# cp /usr/local/bin/scripts/master_ip_failover /usr/local/bin/
複製“master_ip_failover”指令碼到/usr/local/bin 目錄,這裡使用指令碼管理 VIP,也是推薦的一種方式,生產環境不建議使用 Keepalived。
指令碼具體作用如下所示:
master_ip_failover | 自動切換時 VIP 管理的指令碼 |
---|---|
master_ip_online_change | 線上切換時 vip 的管理 |
power_manager | 故障發生後關閉主機的指令碼 |
send_report | 因故障切換後傳送報警的指令碼 |
5.配置自動切換時 VIP 管理的指令碼
直接複製即可用,ip等引數自行修改
[root@localhost bin]# vi /usr/local/bin/master_ip_failover
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;
use MHA::DBHelper;
my (
$command, $ssh_user, $orig_master_host,
$orig_master_ip, $orig_master_port, $new_master_host,
$new_master_ip, $new_master_port, $new_master_user,
$new_master_password
);
##################################插入下面這部分內#################################
my $vip = '20.0.0.200';
my $brdc = '20.0.0.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_stop_vip = "/usr/sbin/ip addr del $vip/24 dev $ifdev label $ifdev:$key";
#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;";
#################################################################################
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,
'new_master_user=s' => \$new_master_user,
'new_master_password=s' => \$new_master_password,
);
exit &main();
sub main {
if ( $command eq "stop" || $command eq "stopssh" ) {
my $exit_code = 1;
eval {
$exit_code = 0;
};
if ($@) {
warn "Got Error: $@\n";
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "start" ) {
my $exit_code = 10;
eval {
my $new_master_handler = new MHA::DBHelper();
$new_master_handler->connect( $new_master_ip, $new_master_port,
$new_master_user, $new_master_password, 1 );
$new_master_handler->disable_log_bin_local();
print "Set read_only=0 on the new master.\n";
$new_master_handler->disable_read_only();
$new_master_handler->enable_log_bin_local();
$new_master_handler->disconnect();
## Update master ip on the catalog database, etc
\# FIXME_xxx; //這一條切記加註釋,刪掉有時也會報錯,註釋掉就可以了
$exit_code = 0;
};
if ($@) {
warn $@;
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "status" ) {
exit 0;
}
else {
&usage();
exit 1;
}
}
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";
}
6.建立 MHA 軟體目錄並拷貝配置檔案app1.cnf
[root@localhost ~]# mkdir /etc/masterha //建立MHA軟體存放目錄
[root@localhost ~]# cp /opt/mha4mysql-manager-0.57/samples/conf/app1.cnf /etc/masterha
[root@localhost ~]# mkdir -p /var/log/masterha/app1
[root@localhost ~]# vi /etc/masterha/app1.cnf
[server default]
manager_log=/var/log/masterha/app1/manager.log //指定manager的日誌檔案
manager_workdir=/var/log/masterha/app1 //指定manager的工作目錄
master_binlog_dir=/usr/local/mysql/data //master存放binlog的位置,要與master的存放位置一致
master_ip_failover_script=/usr/local/bin/master_ip_failover //設定自動failover時候的切換指令碼位置
master_ip_online_change_script=/usr/local/bin/master_ip_online_change //設定手動切換時的切換指令碼位置
user=mha //監控使用者
password=manager //監控使用者密碼
ping_interval=1 //設定監控主庫,傳送ping包的時間間隔,預設是3秒,嘗試三次沒有迴應的時候自動 進行failover故障切換
remote_workdir=/tmp //設定遠端mysq|在發生切換時binlog的儲存位置
repl_password=123456 //設定複製使用者(從伺服器使用者)的密碼
repl_user=myslave //設定複製使用者(從伺服器使用者
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 20.0.0.18 -s 20.0.0.19
shutdown_script="" //設定故障發生後關閉故障主機指令碼(該指令碼的主要作用是關閉主機防止發生腦裂)
ssh_user=root //使用ssh登入時的使用者
report script=/usr/local/send_report //設定發生切換後傳送的報警的指令碼
[server1]
hostname=20.0.0.12
port=3306
[server2]
hostname=20.0.0.18
port=3306
candidate_master=1
check_repl_delay=0
[server3]
hostname=20.0.0.19
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
7.檢查MHA是否正常
7.1檢查ssh情況,正常會輸出successfully
[root@localhost perl5]# masterha_check_ssh -conf=/etc/masterha/app1.cnf
Sat Sep 19 00:15:33 2020 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Sat Sep 19 00:15:33 2020 - [info] Reading application default configuration from /etc/masterha/app1.cnf..
……省略部分
Sat Sep 19 00:15:41 2020 - [info] All SSH connection tests passed successfully.
7.2檢查群集狀態,正常會輸出Health is OK.
[root@localhost bin]# masterha_check_repl -conf=/etc/masterha/app1.cnf
Sat Sep 19 01:23:56 2020 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Sat Sep 19 01:23:56 2020 - [info] Reading application default configuration from /etc/masterha/app1.cnf..
Sat Sep 19 01:23:56 2020 - [info] Reading server configuration from /etc/masterha/app1.cnf..
Sat Sep 19 01:23:56 2020 - [info] MHA::MasterMonitor version 0.57.
Sat Sep 19 01:23:57 2020 - [info] GTID failover mode = 0
……省略部分
Sat Sep 19 01:24:36 2020 - [info] Checking replication health on 20.0.0.19..
Sat Sep 19 01:24:36 2020 - [info] ok.
Sat Sep 19 01:24:36 2020 - [info] Checking master_ip_failover_script status:
Sat Sep 19 01:24:36 2020 - [info] /usr/local/bin/master_ip_failover --command=status --ssh_user=root --orig_master_host=20.0.0.12 --orig_master_ip=20.0.0.12 --orig_master_port=3306
Sat Sep 19 01:24:36 2020 - [info] OK.
Sat Sep 19 01:24:36 2020 - [warning] shutdown_script is not defined.
Sat Sep 19 01:24:36 2020 - [info] Got exit code 0 (Not