MHA高可用 MHA+Keepalive
MHA高可用
MHA簡介
MHA(Master High Availability)目前在MySQL高可用方面是一個相對成熟的解決方案,它由日本DeNA公司youshimaton(現就職於Facebook公司)開發,是一套優秀的作為MySQL高可用性環境下故障切換和主從提升的高可用軟體。 在MySQL故障切換過程中,MHA能做到在10~30秒之內自動完成資料庫的故障切換操作,並且在進行故障切換的過程中,MHA能在最大程度上保證資料的一致性,以達到真正意義上的高可用。 該軟體由兩部分組成:MHA Manager(管理節點)和MHA Node(資料節點)。
MHA功能
MHA能夠在較短的時間內實現自動故障檢測和故障轉移,通常在10-30秒以內; 在複製框架中,MHA能夠很好地解決複製過程中的資料一致性問題,由於不需要在現有的 replication中新增額外的伺服器,僅需要一個manager節點,而一個Manager能管理多套複製,所以能大大地節約伺服器的數量 另外,安裝簡單,無效能損耗,以及不需要修改現 有的複製部署也是它的優勢之處。 MHA還提供線上主庫切換的功能,能夠安全地切換當前執行的主庫到一個新的主庫中 (通過將從庫提升為主庫),大概0.5-2秒內即可完成。 MHA Manager可以單獨部署在一臺獨立的機器上管理多個master-slave叢集,也可以部署在一臺slave節點上。MHA Node執行在每臺MySQL伺服器上,MHA Manager會定時探測叢集中的master節點,當master出現故障時,它可以自動將最新資料的slave提升為新的master,然後將所有其他的slave重新指向新的master。整個故障轉移過程對應用程式完全透明。
MHA工作原理
工作原理說明: 1、儲存master上的所有binlog事件 2、找到含有最新binlog位置點的slave 3、通過中繼日誌將資料恢復到其他的slave 4、將包含最新binlog位置點的slave提升為master 5、將其他從庫slave指向新的master原slave01 並開啟主從複製 6、將儲存下來的binlog恢復到新的master上
MHA工具介紹
MHA軟體由兩部分組成,Manager工具包和Node工具包
masterha_check_ssh #檢査 MHA 的 ssh-key masterha_check_repl #檢査主從複製情況 masterha_manger #啟動MHA masterha_check_status #檢測MHA的執行狀態^ masterha_mast er_monitor #檢測master是否宕機 masterha_mast er_switch #手動故障轉移— masterha_conf_host #手動新增server倍息 masterha_secondary_check #建立TCP連線從遠端伺服器v masterha_stop #停止MHA
Node工具包主要包括以下幾個工具:
save_binary_1ogs #儲存宕機的master的binlog
apply_diff_relay_logs #識別relay log的差異
filter_mysqlbinlog #防止回滾事件一MHA已不再使用這個工具
purge_relay_logs #清除中繼曰志一不會阻塞SQL執行緒
MHA的優點
1、自動故障轉移 2、主庫崩潰不存在資料不一致的情況 3、不需要對當前的mysql環境做重大修改 4、不需要新增額外的伺服器 5、效能優秀,可以工作再半同步和非同步複製框架 6、只要replication支援的儲存引擎mha都支援
MHA部署
本次部署包括 mysql主從同步+MHA高可用+keepalived mha版本0.56 資料庫5.7
機器名 IP地址 功能劃分 db01 172.16.1.51 主 keepalived node db02 172.16.1.52 從 keepalived node db03 172.16.1.53 從 manager node
基礎環境部署
基礎內容
關閉防火牆和selinux
systemctl stop firewalld && setenforce 0
下載資料庫 安裝mysql, 預設5.7版本, 使用本地yum源下載
yum install mysql-community-server -y
修改配置檔案
修改配置檔案/etc/my.cnf server-id 以IP最後一段命名 db01的內容
[[email protected] ~]# vi /etc/my.cnf #使用vi開啟
[mysqld]
server-id=51
log-bin = master-log
relay-log = relay-log
skip_name_resolve
db02的內容
[[email protected] ~]# vi /etc/my.cnf
server-id=52
relay-log = relay-log
log-bin = master-log
read_only = ON
relay_log_purge = 0
skip_name_resolve
log_slave_updates = 1
db03的內容
[[email protected] ~]# vi /etc/my.cnf
[mysqld]
server-id = 53
relay-log = relay-log
log-bin = master-log
read_only = ON
relay_log_purge = 0
skip_name_resolve
log_slave_updates = 1
啟動資料庫, 並加入開機自啟動
systemctl start mysqld && systemctl enable mysqld
修改密碼及匯入資料 修改密碼
登陸mysql資料庫 [password中填寫上一步過濾的密碼]
mysql -uroot -p$(awk '/temporary password/{print $NF}' /var/log/mysqld.log)
修改資料庫密碼
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'Bgx123.com';
mysql> exit
匯入原先的資料(三臺機器都要操作)
mysql -uroot -pBgx123.com < /tmp/db-all.sql #匯入原有的資料庫即可
然後重啟mysql
systemctl restart mysqld
增加使用者
db01主庫的操作
[[email protected] ~]# mysql -uroot -pBgx123.com
mysql> grant all on *.* to 'all'@'%' identified by 'Bgx123.com'; #這個是配置遠端連線規則
mysql> grant replication slave, replication client on *.*
to 'rep'@'172.16.1.%' identified by 'Rep123.com'; #授權, 允許能夠遠端連線的主機(replicaiton)
mysql> flush privileges;
在 master 上進行授權 在所有 Mysql進行授權 擁有管理許可權的使用者可在本地網路中有其他節點上遠端訪問。 mha為manager管理使用者
mysql> grant all on *.* to 'mha'@'172.16.%.%' identified by 'Bgx123.com'; #所有資料庫都要進行授權
mysql> flush privileges;
#mysql 新設定使用者或更改密碼後需用flush privileges重新整理MySQL的系統許可權相關表,否則會出現拒絕訪問
安裝MHA軟體
(在三個節點上都裝mha的node軟體) 在db03(manager監控端)安裝manager
[[email protected] ~]# ll
-rw-r--r-- 1 root root 36326 Oct 24 20:11 mha4mysql-node-0.56-0.el6.noarch.rpm
[[email protected] ~]# ll
-rw-r--r-- 1 root root 36326 Oct 24 20:11 mha4mysql-node-0.56-0.el6.noarch.rpm
[[email protected] ~]# ll
-rw-r--r-- 1 root root 87119 Oct 24 20:11 mha4mysql-manager-0.56-0.el6.noarch.rpm
-rw-r--r-- 1 root root 36326 Oct 24 20:11 mha4mysql-node-0.56-0.el6.noarch.rpm
首先要確保yum源有base源和epel源而且可以上網 因為mha安裝會安裝依賴
[[email protected] ~]# ll /etc/yum.repos.d/
-rw-r--r-- 1 root root 2523 Sep 4 17:06 CentOS-Base.repo
-rw-r--r-- 1 root root 664 Sep 4 17:06 epel.repo
然後直接使用yum install 安裝 db03 manager node都要安裝 其他兩臺只安裝node
[[email protected] ~]# yum install mha4mysql-node-0.56-0.el6.noarch.rpm -y
[[email protected] ~]# yum install -y mha4mysql-node-0.56-0.el6.noarch.rpm
[[email protected] ~]# yum install mha4mysql-manager-0.56-0.el6.noarch.rpm
[[email protected] ~]# yum install mha4mysql-node-0.56-0.el6.noarch.rpm
配置manager
mha配置檔案內容
[[email protected] ~]# mkdir /etc/mha_master/
[[email protected] ~]# cat /etc/mha_master/mha.cnf
[server default]
user=mha
password=Bgx123.com
manager_workdir=/etc/mha_master/app1
manager_log=/etc/mha_master/manager.log
remote_workdir=/mydata/mha_master/app1
ssh_user=root
repl_user=rep
repl_password=Rep123.com
ping_interval=1
[server1]
hostname=172.16.1.51
port=3306
candidate_master=1
[server2]
hostname=172.16.1.52
port=3306
candidate_master=1
#[server3]
#hostname=172.16.1.53
#port=3306
#candidate_master=1
配置三臺機器的ssh互信(三臺都要操作)在配置MHA會要求三臺資料庫無密碼通訊
ssh-keygen -t rsa
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 172.16.1.52 不用輸入密碼就證明成功
指向Master 只在db02 db03操作 在兩個salve節點(從庫)上執行,只讀限制(防止意外被寫資料,很重要)
mysql> set global read_only=1;
mysql> change master to
-> master_host='172.16.1.51',
-> master_user='rep',
-> master_password='Rep123.com';
mysql> start slave;
mysql> show slave status\G; #檢視slave IO和slave sql是否都正常 Yes就是正常的
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
測試配置
測試連通性
[[email protected] ~]# masterha_check_ssh -conf=/etc/mha_master/mha.cnf #最後一行如下圖即為成功
確認上一步連通性沒問題後開始下一步檢查 檢查管理的MySQL複製叢集的連線配置引數是否OK
[[email protected] ~]# masterha_check_repl -conf=/etc/mha_master/mha.cnf
底部顯示OK即為正常
配置VIP漂移
配置Keepalived
使用keepalived做VIP轉移 keepalived只在 db01 db02上安裝
[[email protected] ~]# yum install keepalived -y
[[email protected] ~]# yum install keepalived -y
keepalived db01的配置檔案內容
[[email protected] ~]# cat /etc/keepalived/keepalived.conf
global_defs {
router_id db01
}
vrrp_instance VI_1 {
state MASTER
interface eth1
virtual_router_id 50
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.16.1.66/24 dev eth1
}
}
啟動keepalived
systemctl start keepalived.service
keepalived db02的配置檔案內容
[[email protected] ~]# cat /etc/keepalived/keepalived.conf
global_defs {
router_id db02
}
vrrp_instance VI_1 {
state BACKUP
interface eth1
virtual_router_id 50
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.16.1.66/24 dev eth1
}
}
配置完不要忘記啟動
systemctl start keepalived.service
配置指令碼內容
寫入指令碼內容(我們使用的yum安裝 沒有自帶的指令碼 所以自己寫)見檔案包內
[[email protected] ~]# 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 = '172.16.1.66';
my $ssh_start_vip = "systemctl start keepalived";
my $ssh_stop_vip = "systemctl stop keepalived";
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 \"`;
}
# 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";
}
給指令碼增加執行許可權不然會報錯
[[email protected] ~]# chmod +x /usr/local/bin/master_ip_failover
在db03的配置檔案內加入一行(在原有內容的基礎上增加)
[[email protected] ~]# vim /etc/mha_master/mha.cnf
master_ip_failover_script= /usr/local/bin/master_ip_failover
測試連通性
[[email protected] ~]# masterha_check_ssh -conf=/etc/mha_master/mha.cnf
測試配置
[[email protected] ~]# masterha_check_repl -conf=/etc/mha_master/mha.cnf
啟動mha (在db03上執行)
nohup masterha_manager -conf=/etc/mha_master/mha.cnf &> /etc/mha_master/manager.log &
[1] 13530 #這個號碼每次都會不一樣
[[email protected] ~]# masterha_check_status -conf=/etc/mha_master/mha.cnf
mha (pid:13530) is running(0:PING_OK), master:172.16.1.51
上面的資訊中“mha (pid:13530) is running(0:PING_OK)”表示MHA服務執行OK,否則, 則會顯示為類似“mha is stopped(1:NOT_RUNNING).”
如果,我們想要停止 MHA ,則需要使用 stop 命令:
[[email protected] ~]# masterha_stop -conf=/etc/mha_master/mha.cnf
測試 MHA 故障轉移
先在db03開啟日誌
[[email protected] ~]# tail -f /etc/mha_master/manager.log
主庫 db01 關閉 mariadb 服務,模擬主節點資料崩潰
[[email protected] ~]# systemctl stop mysqld
轉移後的恢復
重新啟動主庫後 db01的操作(不要忘記重啟)
[[email protected] ~]# systemctl start mysqld
[[email protected] ~]# systemctl start keepalived.service
在從庫上執行以下命令(重新設定從庫)
mysql> stop slave;
mysql> reset slave;
mysql> CHANGE MASTER TO
MASTER_HOST=' 172.16.1.51',
MASTER_USER='rep',
MASTER_PASSWORD=' Rep123.com',
MASTER_PORT=3306,
MASTER_LOG_FILE='master-log.000005',
MASTER_LOG_POS=154;
mysql> start slave;
mysql> show slave status\G;
db03的操作 (重新啟動mha之前一定要刪除這個目錄下的檔案 不然下次轉移報錯)
[[email protected] ~]# rm -f /etc/mha_master/app1/*
檢查
[[email protected] ~]# masterha_check_repl -conf=/etc/mha_master/mha.cnf
重新啟動
nohup masterha_manager -conf=/etc/mha_master/mha.cnf &> /etc/mha_master/manager.log &