1、测试环境
目前MHA主要支持一主多从的架构,要搭建MHA,要求一个复制集群中必须最少有三台数据库服务器,一主二从,即一台充当master,一台充当备用master,另外一台充当从库.
一主两从的环境,通过GTID方式配置主从复制同步环境
用途 | IP地址 | 安装软件 | MySQL版本 |
---|---|---|---|
主库 db01 | 192.168.3.112 | mha-node | mysql 8.0.24 |
从库 db02 | 192.168.3.113 | mha-node | mysql 8.0.24 |
从库 db03 | 192.168.3.114 | mha-manager、mha-node | mysql 8.0.24 |
创建MySQL相关命令软链接
## 三台服务器都需执行
# ln -s /opt/mysql/bin/mysqlbinlog /usr/bin/
# ln -s /opt/mysql/bin/mysql /usr/bin/
配置三台主机之间ssh免密互信登录,配置完成三台主机验证确认无误
## 三台服务器都需执行
# rm -rf /root/.ssh/
## 只在主库上执行
# cd /root/.ssh
# mv id_rsa.pub authorized_keys
# ssh-keygen
# scp -r /root/.ssh 192.168.3.114:/root
# scp -r /root/.ssh 192.168.3.113:/root
mha软件下载
mha版本
-
0.56 适用于 mysql5.6 版本系列
-
0.57 适用于 mysql5.7 版本系列
-
0.58 适用于 mysql8.0 版本系列
安装mha软件
## 三台服务器都需执行
# yum install perl-DBD-MySQL -y
# rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm
## 在db01上创建需要的mha数据库用户
db01 [(none)]>create user mha@'192.168.3.%' identified with mysql_native_password by 'mha';
db01 [(none)]>grant all privileges on *.* to mha@'192.168.3.%';
## 在db03安装mha-manger软件
# yum install -y perl-Config-Tiny epel-release perl-Log-Dispatch perl-ParallelForkManager perl-Time-HiRes
# yum install mha4mysql-manager-0.58-0.el7.centos.noarch.rpm -y
# mkdir -p /etc/mha
# mkdir -p /var/log/mha/app1
vim /etc/mha/app1.cnf
[server default]
manager_log=/var/log/mha/app1/manager
manager_workdir=/var/log/mha/app1
master_binlog_dir=/opt/mysql/binlog/
user=mha
password=mha
ping_interval=2
repl_password=repl
repl_user=repl
ssh_user=root
[server1]
hostname=192.168.3.112
port=3306
[server2]
hostname=192.168.3.113
candidate_master=1
port=3306
[server3]
hostname=192.168.3.114
port=3306
## 互信检查
masterha_check_ssh --conf=/etc/mha/app1.cnf
## 主从状态检查
masterha_check_repl --conf=/etc/mha/app1.cn
## 启动mha
# nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null> /var/log/mha/app1/manager.log 2>&1 &
## 查看mha状态
# masterha_check_status --conf=/etc/mha/app1.cnf
配置 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.3.111/24';
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down";
my $ssh_Bcast_arp= "/sbin/arping -I ens33 -c 3 -A 192.168.3.111";
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 \"`;
}
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";
}
## 添加脚本路径到manager配置文件
# vim /etc/mha/app1.cnf
master_ip_failover_script=/usr/local/bin/master_ip_failover
## 重启mha
# masterha_stop --conf=/etc/mha/app1.cnf
## 手动添加VIP
# masterha_check_status --conf=/etc/mha/app1.cnf
# ifconfig ens33:1 192.168.3.111/24
配置邮件提醒
# more send_report
#!/usr/bin/perl
# Copyright (C) 2011 DeNA Co.,Ltd.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
## Note: This is a sample script and is not complete. Modify the script based on your environment.
use strict;
use warnings FATAL => 'all';
use Mail::Sender;
use Getopt::Long;
#new_master_host and new_slave_hosts are set only when recovering master succeeded
my ( $dead_master_host, $new_master_host, $new_slave_hosts, $subject, $body );
my $smtp='smtp.qq.com'; # smtp服务器
my $mail_from='@qq.com'; # 发件箱
my $mail_user=''; # QQ号
my $mail_pass=''; # 授权码
#my $mail_to=['to1@qq.com','to2@qq.com']; # 多个收件箱
my $mail_to='@qq.com'; # 收件箱
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,
);
# Do whatever you want here
mailToContacts($smtp,$mail_from,$mail_user,$mail_pass,$mail_to,$subject,$body);
sub mailToContacts {
my ($smtp, $mail_from, $mail_user, $mail_pass, $mail_to, $subject, $msg ) = @_;
open my $DEBUG, ">/tmp/mail.log"
or die "Can't open the debug file:$!\n";
my $sender = new Mail::Sender {
ctype => 'text/plain;charset=utf-8',
encoding => 'utf-8',
smtp => $smtp,
from => $mail_from,
auth => 'LOGIN',
TLS_allowed => '0',
authid => $mail_user,
authpwd => $mail_pass,
to => $mail_to,
subject => $subject,
debug => $DEBUG
};
$sender->MailMsg(
{
msg => $msg,
debug => $DEBUG
}
) or print $Mail::Sender::Error;
return 1;
}
exit 0;
## manager配置文件中添加,重启mha
report_script=/usr/local/bin/send_report
对于异步复制方式,可以添加 binlog 的日志补偿,减少数据丢失。
## db03 创建保存binlog日志文件目录
# mkdir -p /data/binlog_master/
# chown -R mysql.mysql /data/*
# cd /data/binlog_master/
# mysql -e "show slave status \G"|grep "Master_Log"
# masterha_check_status --conf=/etc/mha/app1.cnf
# mysqlbinlog -R --host=192.168.3.112 --user=mha --password=mha --raw --stop-never mysql-bin.000002 &
# vim /etc/mha/app1.cnf
[binlog1]
no_master=1
hostname=192.168.3.114
master_binlog_dir=/data/binlog_master/
# masterha_stop --conf=/etc/mha/app1.cnf
# nohup masterha_manager --conf=/etc/mha/app1.cnf --
remove_dead_master_conf --ignore_last_failover < /dev/null>
/var/log/mha/app1/manager.log 2>&1 &
binlog server不是100%可靠的。他模拟的是从库IO线程的功能(异步)。
替代方案: 5.7+GTID+增强半同步。
注意的是,当master数据库出现故障后,切换主库后,mha程序自动停止,只能监测切换一次,需要手动进行恢复mha高可用。
数据一致性保证同步配置
#*************** rpl_semi_sync ***************
rpl_semi_sync_master_enabled =ON
rpl_semi_sync_master_timeout =5000
rpl_semi_sync_master_wait_for_slave_count =1
rpl_semi_sync_master_wait_no_slave =ON
rpl_semi_sync_master_wait_point =AFTER_SYNC
rpl_semi_sync_slave_enabled =ON
#*************** group commit ***************
binlog_group_commit_sync_delay =1
binlog_group_commit_sync_no_delay_count =1000
#*************** gtid ***************
gtid_mode =ON
enforce_gtid_consistency =ON
log_slave_update =1
#*************** gtid ***************
slave_parallel_type =LOGICAL_CLOCK
slave_parallel_workers =4
master_info_repository =TABLE
relay_log_info_repository =TABLE
标签:--,mha,host,master,ssh,MySQL,new,MHA,搭建
From: https://www.cnblogs.com/zbc230/p/17472932.html