功能
1、監控主資料庫伺服器是否可用
2、當主DB不可用時,從多個從伺服器中選出新的主資料庫伺服器
3、提供了主從切換和故障轉移功能(可以與半同步複製結合,最大程度的保證資料的完整性)
主從切換過程
1、嘗試從出現故障的主資料庫儲存二進位制日誌
2、從多個備選從伺服器中選出新的備選主資料庫(使用者可指定不參與選擇的資料庫)
3、在備選主伺服器和其它從伺服器之間同步差異二進位制資料
4、新主伺服器應用從原主DB伺服器上儲存的二進位制日誌(若主DB的二進位制儲存下來) 注:重複的主鍵等會使MHA停止進行故障轉移
5、備選主DB伺服器更新為新的主DB,並更改虛擬IP
6、遷移叢集中的其它從DB作為新的主DB的從伺服器
架構(支援基於GTID的複製)
步驟
1、配置叢集中所有主機的SSH免認證登入(比如故障轉移過程中儲存原主伺服器二進位制日誌,配置虛擬IP地址等)
2、安裝MHA-node軟體包(所有節點均安裝)和MHA-manager(監控節點安裝)軟體包
命令:yum -y install perl-Config-Tiny.noarch
perl-Time-HiRes.x86_64
perl-Parallel-ForkManager
perl-Log-Dispatch-Per.noarch
perl-DBD-MySQL ncftp
3、建立主從複製叢集
4、配置MHA管理節點
使用masterha_check_ssh:檢查ssh免認證登入
使用masterha_check_repl :檢查複製鏈路
5、啟動並測試MHA服務
例項
1、建立基於GTID複製的叢集
2、開啟ssh免登入認證
ssh-keygen #開啟ssh金鑰
ssh-copy-id -i /root/.ssh/id_rsa -p 22 root@192.168.71.244|223|220 #複製rsa到叢集中的所有伺服器(互相免登入)
ssh root@192.168.71.244 #驗證是否開啟成功
3、下載node和manager安裝包(wget [url])和安裝perl的支援包(yum -y install perl-DBD-MySQL ncftp per-DBI.x86)
4、安裝node (所有節點)
rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm
5、安裝manager軟體包和安裝perl支援包(監控節點)
yum -y install perl-Config-Tiny.noarch #安裝監控依賴
perl-Time-HiRes.x86_64
perl-Parallel-ForkManager
perl-Log-Dispatch-Per.noarch
perl-DBD-MySQL ncftp
rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm #安裝監控軟體
6、配置MHA (配置監控節點即可)
mkdir -p /etc/mha #建立MHA配置目錄
mkdir -p /home/mysql_mha #建立MHA的工作目錄
vim /etc/mha/mysql_mha.cnf(見附件1) #建立配置檔案
7、配置master_ip_failover(見附件2) 並chmod +x /usr/bin/master_ip_failover#變成可執行檔案
8、檢驗ssh登入
masterha_check_ssh --conf = /etc/mha/mysql_mha.cnf(在監控伺服器中執行)
9、檢驗repl通道
masterha_check_repl --conf = /etc/mha/mysql_mha.cnf(在監控伺服器中執行)
10、執行mha
nohup masterha_manager --conf=/etc/mha/mysql_mha.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /home/mysql_mha/manager.log 2>&1 & #放在後臺執行
11、手動配置虛擬IP(在主中配置)
ifconfig eth0:1 192.168.71.90/24 #ip addr 檢視ip
12、測試(檢視虛擬IP和複製鏈路)
關閉主,檢視從的複製鏈路和虛擬IP
備註:
#停止MHA
masterha_stop --conf=/etc/mha/mysql_mha.cnf [--remove_dead_master_conf ]--ignore_last_failover < /dev/null > /home/mysql_mha/manager.log 2>&1
#開始MHA
nohup masterha_manager --conf=/etc/mha/mysql_mha.cnf [--remove_dead_master_conf] --ignore_last_failover < /dev/null > /home/mysql_mha/manager.log 2>&1 &
--remove_dead_master_conf:刪除失敗配置
若M當機後,MHA會自動切換
若M重新恢復時,需要再次手動配置主動
CHANGE MASTER TO MASTER_HOST='192.168.71.244', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123456';
MHA常用命令
masterha_manager --conf=/etc/mha/mysql_mha.cnf #開啟MHA manager
masterha_check_status --conf=/etc/mha/mysql_mha.cnf #檢查MHA執行狀態
masterha_check_repl --conf=/etc/mha/mysql_mha.cnf #檢查複製健康狀態
masterha_stop --conf=/etc/mha/mysql_mha.cnf #停止MHA manager執行
masterha_conf_host --command=add--conf=/etc/mha/mysql_mha.cnf --hostname=db101 --params="no_master=1;ignore_fail=1" #在配置檔案中新增或移除host --block 移除
masterha_check——ssh --conf=/etc/mha/mysql_mha.cnf #ssh認證檢查
【附件1】 mysql_mha.cnf:
[server default]
user = mha
password = 123456
manager_workdir = /home/mysql_mha
manager_log = /home/mysql_mha/manager.log
remote_workdir = /home/mysql_mha
ssh_user = root
repl_user = repl
repl_password = 123456
ping_interval =1
master_binlog_dir = /usr/local/mysql/log/mysql-bin
master_ip_failover_script = /usr/bin/master_ip_failover
#master_ip_online_change_script= /usr/bin/master_ip_online_change
secondary_check_script = /usr/bin/masterha_secondary_check -s 192.168.71.223 -s 192.168.71.244 -s 192.168.71.220
[server1]
hostname = 192.168.71.244
candidate_master = 1
[server2]
hostname = 192.168.71.223
candidate_master = 1
[server3]
hostname = 192.168.71.220
no_master = 1
【附件2】master_ip_failover
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;
my (
$command,
$orig_master_host,$orig_master_ip,$orig_master_port, $orig_master_ssh_port,
$ssh_user,
$new_master_host,$new_master_ip, $new_master_port, $new_master_user,$new_master_password,$new_master_ssh_port
);
my $vip = '192.168.71.90/24';
my $key = '1';
my $ssh_start_vip = "sudo /sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "sudo /sbin/ifconfig eth0:$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,
'orig_master_ssh_port=i' => \$orig_master_ssh_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,
'new_master_ssh_port=i' => \$new_master_ssh_port
);
exit &main();
sub main {
$ssh_user = defined $ssh_user ? $ssh_user : 'root';
print "\n\nIN SCRIPT TEST ==== $ssh_user | $ssh_stop_vip == $ssh_user | $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_port 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";
}
【附件3】 report_script 郵箱通知
#!/usr/bin/perl
use strict;
use warnings FATAL => 'all';
use Email::Simple;
use Email::Sender::Simple qw(sendmail);
use Email::Sender::Transport::SMTP::TLS;
use Getopt::Long;
my ( $dead_master_host, $new_master_host, $new_slave_hosts, $subject, $body );
my $smtp='smtp.qq.com';
my $mail_from='xxx@qq.com';
my $mail_user='xxx@qq.com';
#郵箱授權碼不是密碼 郵箱授權碼獲取方式可以百度
my $mail_auth_pass='xxxxxx';
my $mail_to='xxxxxxxxxx';
GetOptions(
'orig_master_host=s' => \$dead_master_host,
'new_master_host=s' => \$new_master_host,
'new_slave_hosts=s' => \$new_slave_hosts,
'subject=s' => \$subject,
'body=s' => \$body,
);
my $transport = Email::Sender::Transport::SMTP::TLS->new(
host => $smtp,
port => 25,
username => $mail_user,
password => $mail_auth_pass,
);
my $message = Email::Simple->create(
header => [
From => $mail_from,
To => $mail_to,
Subject => $subject,
],
body => $body,
);
sendmail( $message, {transport => $transport} );
exit 0;
【附圖1】MHA的配置引數
【附圖2】masterha_check_ssh --conf = /etc/mha/mysql_mha.cnf 結果:
【附圖3】masterha_check_repl --conf=/etc/mha/mysql_mha.cnf 結果:
本作品採用《CC 協議》,轉載必須註明作者和本文連結