使用MHA實現mysql高可用性(centos7.5+mysql5.7.23+MHA0.58)
一、MHA概述
1、MHA
MHA(Master High Availability)事由日本人DeNA開發的一套MySQL高可用性環境下故障切換和主從提升的軟體,目前在MySQL高可用方面是一個相對成熟的解決方案。在MySQL故障切換過程中,MHA能做到在0~30秒之內自動完成資料庫的故障切換操作,並且在進行故障切換的過程中,MHA能在最大程度上保證資料的一致性,以達到真正意義上的高可用。
2、MHA的主要功能
(1)自動故障檢測和自動故障轉移
(2)互動式(手動)故障轉移
(3)線上切換Master到不同的主機
3、MHA的優勢
(1)自動故障轉移快
(2)主庫崩潰不存在資料一致性問題
(3)配置不需要對當前mysql環境做重大修改
(4)不需要新增額外的伺服器(僅一臺manager就可管理上百個replication)
(5)效能優秀,可工作在半同步複製和非同步複製
(6)只要replication支援的儲存引擎,MHA都支援,不會侷限於innodb
4、MHA的組成部分
MHA由Manager節點和Node節點組成;MHA Manager可以單獨部署在一臺獨立的機器上管理多個master-slave叢集,也可以部署在一臺slave節點上。MHA Node執行在每臺MySQL伺服器上。
5、MHA工作原理
(1)MHA Manager會定時探測叢集中的master節點
(2)當master出現故障時,從宕機崩潰的master儲存二進位制日誌事件(binlog events);
(3)識別含有最新更新的slave;
(4)應用差異的中繼日誌(relay log)到其他的slave;
(5)應用從master儲存的二進位制日誌事件(binlog events);
(6)提升一個slave為新的master,使其他的slave連線新的master進行復制;
二、MHA安裝部署
1、環境準備
(1)環境準備
主機名 |
IP地址 |
節點資訊 |
資料庫版本 |
系統版本 |
MYSQL01 |
192.168.16.151 |
Mysql主節點 |
5.7.23 |
centos7.5 |
MYSQL02 |
192.168.16.152 |
Mysql從節點 |
5.7.23 |
centos7.5 |
MYSQL03 |
192.168.16.153 |
Mysql從節點 |
5.7.23 |
centos7.5 |
MANAGER |
192.168.16.155 |
MHA manager節點 |
|
centos7.5 |
(2)拓撲結構
(3)設定主機名並互相做祕鑰的認證
首先需要在各個節點上配置各個主機的主機名,使各節點通過主機名能夠互相解析。
]# tail -4f /etc/hosts
192.168.16.151 MYSQL01
192.168.16.152 MYSQL02
192.168.16.152 MYSQL03
192.168.16.155 MANAGER
由於MHA manager通過SSH訪問所有的node節點,各個node節點也同樣通過SSH來相互發送不同的relay log 檔案,所以要在每一個node和manager上配置SSH無密碼登陸。
# 在每個節點上分別生成祕鑰對
[[email protected] ~]# ssh-keygen
# 每臺節點分別將自己的公鑰傳送到另外的三臺節點
]# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
]# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
]# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
]# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
2、配置mysql主從環境
(1)配置mysql主節點及從節點
Mysql主節點的配置如下:
[mysqld]
log-bin=mysql-bin
server-id=1
replicate-do-db=course
character-set-server=utf8
init_connect='SET AUTOCOMMIT=0;set names utf8'
mysql兩臺slave節點的配置如下:
[mysqld]
log-bin=mysql-bin
server-id=2|3 #兩個節點的id配置不同
replicate-do-db=course # 只同步course庫
# 更新資料的語句也記錄在slave自己的bin log中
log-slave-updates=true
# 設定relay_log的清除方式
relay_log_purge=0
skip-slave-start=1
# 設定字符集及連線客戶端字符集
character-set-server=utf8
init_connect='SET AUTOCOMMIT=0;set names utf8'
(2)建立用於複製的使用者
由於同步資料時將所有的資料都同步到了主庫,所有建立用於同步的使用者時只需在主庫建立,如果同步時不同步”mysql”庫,需要在三臺資料庫主機上分別建立用於複製的使用者。
# 建立用於複製的使用者
mysql> CREATE USER 'repl'@'192.168.16.%' IDENTIFIED BY 'replication';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.16.%';
(3)同步資料
1)獲取主庫的bin log資訊以及備份主庫
# 將主庫鎖定
mysql> FLUSH TABLES WITH READ LOCK;
# 獲取bin log日誌資訊
mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000006
Position: 4838
# 備份庫
]# mysqldump --all-databases --master-data -u root -p > course.sql
# 登入主庫釋放鎖
mysql> unlock tables;
# 將備份檔案傳到從庫
]# scp course.sql [email protected]:/data/
]# scp course.sql [email protected]:/data/
2)在從庫上匯入資料並開啟主從複製
# 在兩臺slave上分別匯入資料
]# mysql -uroot -p </data/mysql.sql
# 登入兩臺從庫分別配置同步
mysql> CHANGE MASTER TO
-> MASTER_HOST='192.168.16.151',
-> MASTER_PORT=3306,
-> MASTER_USER='repl',
-> MASTER_PASSWORD='replication',
-> MASTER_LOG_FILE='mysql-bin.000006',
-> MASTER_LOG_POS=4838;
# 開啟同步
mysql> start slave;
(4)設定mysql程式及binglog程式的軟連線
雖然mysql程式已經加入了環境變數,如果預設路徑下mysql客戶端不存在在使用MHA時會報錯。
]# ln -s /usr/local/mysql/bin/mysql /usr/bin/mysql
]# ln -s /usr/local/mysql/bin/mysqlbinlog /usr/local/bin/mysqlbinlog
3、安裝MHA
(1)在各節點上安裝mha4mysql-node
在四臺機器上上分別安裝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
# 安裝net-tools,最小化安裝的centos7中沒有一些網路管理工具
]# yum install –y net-tools
# 安裝epel yum源
]# yum install epel-release
# 在安裝前先安依賴軟體
]# yum install –y perl-DBD-MySQL
# 安裝mha4mysql-node
]# rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm
(3)在管理節點上安裝manage節點
# 在管理節點安裝依賴軟體
]# yum install -y perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager
# 在管理節點安裝mha4mysql-manager
]# rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
(4)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、配置MHA
(1)配置MHA
MHA管理端和客戶端安裝完成後,在管理端需要建立MHA的配置檔案,配置檔案內容如下:
# 建立manager工作目錄
]# mkdir /data/manager –p
# manager的配置檔案
[[email protected] ~]# cat /etc/manager/manager.conf
[server default]
user=root
password=dayi123
ssh_user=root
manager_workdir=/data/manager
remote_workdir=/tmp
repl_user=repl
repl_password=replication
[server1]
hostname=MYSQL01
port=3306
master_binlog_dir=/data/mysql/data
[server2]
hostname=MYSQL02
port=3306
master_binlog_dir=/data/mysql/data
[server3]
hostname=MYSQL03
port=3306
master_binlog_dir=/data/mysql/data
(2)MHA主要配置檔案說明
manager_workdir=/var/log/masterha/app1.log:設定manager的工作目錄
manager_log=/var/log/masterha/app1/manager.log:設定manager的日誌檔案
master_binlog_dir=/data/mysql:設定master 儲存binlog的位置,以便MHA可以找到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=root:設定監控mysql的使用者
password=dayi123:設定監控mysql的使用者,需要授權能夠在manager節點遠端登入
ping_interval=1:設定監控主庫,傳送ping包的時間間隔,預設是3秒,嘗試三次沒有迴應的時候自動進行railover
remote_workdir=/tmp:設定遠端mysql在發生切換時binlog的儲存位置
repl_user=repl :設定mysql中用於複製的使用者密碼
repl_password=replication:設定mysql中用於複製的使用者
report_script=/usr/local/send_report:設定發生切換後傳送的報警的指令碼
shutdown_script="":設定故障發生後關閉故障主機指令碼(該指令碼的主要作用是關閉主機放在發生腦裂,這裡沒有使用)
ssh_user=root //設定ssh的登入使用者名稱
candidate_master=1:在節點下設定,設定當前節點為候選的master
slave check_repl_delay=0 :在節點配置下設定,預設情況下如果一個slave落後master 100M的relay logs的話,MHA將不會選擇該slave作為一個新的master;這個選項對於對於設定了candidate_master=1的主機非常有用
5、檢查MHA的環境是否工作正常
(1)通過masterha_check_ssh指令碼檢測SSH連線是否配置正常
]# masterha_check_ssh --conf=/etc/app1.cnf
Mon Oct 29 12:05:48 2018 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Mon Oct 29 12:05:48 2018 - [info] Reading application default configuration from /etc/app1.cnf..
Mon Oct 29 12:05:48 2018 - [info] Reading server configuration from /etc/app1.cnf..
Mon Oct 29 12:05:48 2018 - [info] Starting SSH connection tests..
Mon Oct 29 12:05:53 2018 - [debug]
…….
Mon Oct 29 12:05:52 2018 - [debug] Connecting via SSH from [email protected](192.168.16.153:22) to [email protected](192.168.16.152:22)..
Mon Oct 29 12:05:52 2018 - [debug] ok.
Mon Oct 29 12:05:53 2018 - [info] All SSH connection tests passed successfully.
(2)在管理節點檢查複製配置
為了讓MHA正常工作,所有的master和slave必須在配置檔案中正確配置,MHA可通過masterha_check_repl 指令碼檢測複製是否正確配置。
]# masterha_check_repl --conf=/etc/app1.cnf
Fri Nov 2 16:27:47 2018 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Fri Nov 2 16:27:47 2018 - [info] Reading application default configuration from /etc/app1.cnf..
……
Fri Nov 2 16:27:53 2018 - [info] Got exit code 0 (Not master dead).
MySQL Replication Health is OK.
三、MHA的管理
Mysql中主從的工作狀態監測及切換事由manager節點來完成的,MHA安裝完成以及檢測通過後就可以根據自己的需求開啟以及停止manager,讓manager工作起來。
1、啟動Manager
Manager是通過 masterha_manager 命令開啟,啟動後需要將它放在後臺執行。
當MHA manager啟動監控以後,如果沒有異常則不會列印任何資訊。我們可通過masterha_check_status命令檢查manager的狀態。
# 啟動Manager
]# nohup masterha_manager --conf=/etc/app1.cnf > /var/log/mha_manager.log < /dev/null &
# 檢測manager的工作狀態
]# masterha_check_status --conf=/etc/app1.cnf
app1 (pid:22330) is running(0:PING_OK), master:MYSQL0
2、停止MHA manager
當需要停止manager時,可以通過 masterha_stop命令來停止manager。
# 停止manager
]# masterha_stop --conf=/etc/app1.cnf
Stopped app1 successfully.
3、故障的切換
(1)自動故障切換
Manager啟動後,manager會自動去監測主從同步的狀態,當主節點故障時,會自動進行故障的轉移將從節點提升為主節點,讓其他的從節點去新的主節點同步。
# 將主庫192.168.16.151關閉後,檢視manager的日誌,主要的切換記錄如下:
]# tail -100f /var/log/mha_manager.log
……
app1: MySQL Master failover MYSQL01(192.168.16.151:3306) to MYSQL02(192.168.16.152:3306) succeeded
Master MYSQL01(192.168.16.151:3306) is down!
Check MHA Manager logs at MANAGER for details.
Started automated(non-interactive) failover.
The latest slave MYSQL02(192.168.16.152:3306) has all relay logs for recovery.
Selected MYSQL02(192.168.16.152:3306) as a new master.
MYSQL02(192.168.16.152:3306): OK: Applying all logs succeeded.
MYSQL03(192.168.16.153:3306): This host has the latest relay log events.
Generating relay diff files from the latest slave succeeded.
MYSQL03(192.168.16.153:3306): OK: Applying all logs succeeded. Slave started, replicating from MYSQL02(192.168.16.152:3306)
MYSQL02(192.168.16.152:3306): Resetting slave info succeeded.
Master failover to MYSQL02(192.168.16.152:3306) completed successfully.
(2)手動故障切換
當在業務上沒有啟用MHA自動切換功能,當主伺服器故障時,需要人工手動呼叫MHA來進行故障切換操作。
# 進行配置停掉的主節點,讓成新的從節點;並manager程序時停掉的,否則會影響手動故障轉移
]# masterha_stop --conf=/etc/app1.cnf
# 切換時需要將master停掉,否則會報錯,在切換命令中使用主機名,不要使用ip,否則也會報錯,在切換時也需要確認切換
]# masterha_master_switch --master_state=dead --conf=/etc/app1.cnf --dead_master_host=MYSQL02 --dead_master_port=3306 --new_master_host=MYSQL01 --new_master_port=3306 --ignore_last_failover……..
Started manual(interactive) failover.
The latest slave MYSQL01(192.168.16.151:3306) has all relay logs for recovery.
Selected MYSQL01(192.168.16.151:3306) as a new master.
MYSQL01(192.168.16.151:3306): OK: Applying all logs succeeded.
MYSQL03(192.168.16.153:3306): This host has the latest relay log events.
Generating relay diff files from the latest slave succeeded.
MYSQL03(192.168.16.153:3306): OK: Applying all logs succeeded. Slave started, replicating from MYSQL01(192.168.16.151:3306)
MYSQL01(192.168.16.151:3306): Resetting slave info succeeded.
Master failover to MYSQL01(192.168.16.151:3306) completed successfully.
(3)線上切換
為了保證資料完全一致性,在最快的時間內完成切換,MHA的線上切換必須滿足以下條件才會切換成功,否則會切換失敗。
1)所有slave的IO執行緒都在執行
2)所有slave的SQL執行緒都在執行
3)所有的show slave status的輸出中Seconds_Behind_Master引數小於或者等於running_updates_limit秒,如果在切換過程中不指定running_updates_limit,那麼預設情況下running_updates_limit為1秒。
4)在master端,通過show processlist輸出,沒有一個更新花費的時間大於running_updates_limit秒。
# 在切換前先停掉manage,同時也恢復上面手動切換時停掉的MYSQL02為MYSQL01的從節點
]# masterha_stop --conf=/etc/app1.cnf
# 線上切換MYSQL03為主節點,切換時不需要停掉現有的主節點,在切換的過程中需要確認
]# masterha_master_switch --conf=/etc/app1.cnf --master_state=alive --new_master_host=MYSQL03 --new_master_port=3306 --orig_master_is_new_slave --running_updates_limit=10000
…..
Sat Nov 3 11:17:27 2018 - [info] Executed CHANGE MASTER.
Sat Nov 3 11:17:27 2018 - [info] Slave started.
Sat Nov 3 11:17:27 2018 - [info] All new slave servers switched successfully.
Sat Nov 3 11:17:27 2018 - [info]
Sat Nov 3 11:17:27 2018 - [info] * Phase 5: New master cleanup phase..
Sat Nov 3 11:17:27 2018 - [info]
Sat Nov 3 11:17:27 2018 - [info] MYSQL03: Resetting slave info succeeded.
Sat Nov 3 11:17:27 2018 - [info] Switching master to MYSQL03(192.168.16.153:3306) completed successfully.
線上切換完成後,從節點MYSQL03成為了主節點,原來的主節點MYSQL01變為從節點,兩個從節點會去新的主節點MYSQL03複製。
在切換過程中的引數說明:
-orig_master_is_new_slave:切換時加上此引數是將原 master 變為 slave 節點,如果不加此引數,原來的 master 將不啟動
--running_updates_limit=10000:故障切換時,候選master 如果有延遲的話, mha 切換不能成功,加上此引數表示延遲在此時間範圍內都可切換(單位為s),但是切換的時間長短是由recover 時relay 日誌的大小決定。
4、在MHA環境中配置VIP
通過MHA進行故障轉以後,連線Mysql資料庫的服務並不知道Mysql複製環境中進行了故障的轉移,同時連線mysql的服務也無法知曉主節點是哪一個,此時,可以通過配置VIP的方式讓所有的應用程式連線VIP,當mysql故障切換時,VIP會自動漂移到新的主節點。vip配置可以採用兩種方式,一種通過keepalived的方式管理;另外一種通過指令碼方式啟動VIP,下面以指令碼的方式進行演示。
# 為mysql主節點在配置一個IP地址
]# ifconfig eno16777736:2 192.168.16.156/24
# 修改manager配置檔案,新增VIP漂移指令碼配置檔案
master_ip_failover_script=/usr/local/bin/master_ip_failover
# 建立指令碼/usr/local/bin/master_ip_failover,內容如下
]# cat /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.16.156/24';
my $key = '2';
my $ssh_start_vip = "/sbin/ifconfig eno16777736:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eno16777736:$key down";
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 ([email protected]) {
warn "Got Error: [email protected]\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 ([email protected]) {
warn [email protected];
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 \"`;
}
sub stop_vip() {
return 0 unless ($ssh_user);
`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";
}
# 為指令碼賦予執行的許可權
]# chmod a+x master_ip_failover
切換指令碼中的去連線mysql各節點配置vip是通過”user”@”hostname”的方式去連線各節點配置vip的,所以在配置完各節點配置完ssh祕鑰認證後,要通過”ssh [email protected]”的方式去連線各個節點建立快取(第一次通過祕鑰登入需要輸入”yes”確認);否則指令碼在執行到”Disabling the VIP on old master”會執行不下去。