| VIP:10.0.3.200/24 | |||
| 角色 | IP | server_id | 权限 |
| master | 10.0.3.105 | 105 | 写 |
| slave(备用master) | 10.0.3.115 | 115 | 读 |
| manager(slave2) | 10.0.3.112 | 112 | 读 |
| 系统版本:centos7.8 | |||
| 数据库版本:MySQL5.7.30 | |||
| MHA版本:mha0.58 | |||
一 mysql主从搭建。。。略(一主两从GTID) 二 MHA基本环境准备1.配置三台机器的ssh互信(三台机器都要操作)
ssh-keygen -t rsa ssh-copy-id -i /root/.ssh/id_rsa.pub root@10.0.3.105 ssh-copy-id -i /root/.ssh/id_rsa.pub root@10.0.3.115 ssh-copy-id -i /root/.ssh/id_rsa.pub root@10.0.3.112 # 测试是否成功 ssh 10.0.3.105 date ssh 10.0.3.115 date ssh 10.0.3.112 date
2.绑定VIP先在主库master上绑定VIP(只需手工绑定一次,后续脚本会自动切换)
ifconfig ens192:1 10.0.3.200/24
3.安装MHA软件项目地址: https://github.com/yoshinorim/mha4mysql-manager/releases/tag/v0.58三台机器上都要安装mha的node软件先安装依赖
yum install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager -y
安装node软件
rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm
仅在manager机器上安装mha管理软件
rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
三 配置MHA(在manager机器上操作10.0.3.112)3.创建目录
mkdir -p /etc/mha/scripts mkdir -p /var/log/mha/app1
4.编写全局配置文件
cat /etc/masterha_default.cnf #一定要是这个路径,不然后期masterha_check_ssh会提示未找到全局文件 [server default] user=mha password=mha ssh_user=root repl_user=repl repl_password=123 ping_interval=3 secondary_check_script=masterha_secondary_check -s 10.0.3.105 -s 10.0.3.115 -s 10.0.3.112 master_ip_failover_script="/etc/mha/scripts/master_ip_failover" master_ip_online_change_script="/etc/mha/scripts/master_ip_online_change" report_script="/etc/mha/scripts/send_report"
5.编写主配置文件
cat /etc/mha/app1.cnf [server default] manager_log=/var/log/mha/app1/manager.log manager_workdir=/var/log/mha/app1 [server1] candidate_master=1 hostname=10.0.3.105 master_binlog_dir="/data/mysql/binlog" [server2] candidate_master=1 hostname=10.0.3.115 master_binlog_dir="/data/mysql/binlog" [server3] hostname=10.0.3.112 master_binlog_dir="/data/mysql/binlog" no_master=1
6.配置VIP
#为了防止脑裂发生,推荐生产环境采用脚本的方式来管理虚拟 ip,而不是使用 keepalived来完成。
cat /etc/mha/scripts/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
);
#定义VIP变量
my $vip = '10.0.3.200/24';
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig ens192:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig ens192:$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 ($@) {
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";
}
7.配置微信机器人报警脚本
cat /etc/mha/scripts/send_report
#!/bin/bash
source /root/.bash_profile
# 解析变量
orig_master_host=`echo "$1" | awk -F = '{print $2}'`
new_master_host=`echo "$2" | awk -F = '{print $2}'`
new_slave_hosts=`echo "$3" | awk -F = '{print $2}'`
subject=`echo "$4" | awk -F = '{print $2}'`
body=`echo "$5" | awk -F = '{print $2}'`
tac /var/log/mha/app1/manager.log | sed -n 2p | grep 'successfully' > /dev/null
if [ $? -eq 0 ]
then
messages=`echo -e "MHA $subject 主从切换成功\n master:$orig_master_host --> $new_master_host \n $body \n 当前从库:$new_slave_hosts"`
TOKEN="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=bb09197b-xxxx-xxxx-xxxx-aa5fa8xxxxxx"
DING="curl -H \"Content-Type: application/json\" -X POST --data '{\"msgtype\": \"text\", \"text\": {\"content\": \"${messages}\"},\"isAtAll\": false}}' ${TOKEN}"
eval $DING
echo "$messages" >>/tmp/gaojin.log 2>&1
else
messages=`echo -e "MHA $subject 主从切换失败\n master:$orig_master_host --> $new_master_host \n $body" `
TOKEN="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=bb09197b-xxxx-xxxx-xxxx-aa5fa8xxxxxx"
DING="curl -H \"Content-Type: application/json\" -X POST --data '{\"msgtype\": \"text\", \"text\": {\"content\": \"${messages}\"},\"isAtAll\": false}}' ${TOKEN}"
eval $DING
echo "$messages" >>/tmp/gaojin.log 2>&1
fi
8.配置编写VIP脚本
cat /etc/mha/scripts/master_ip_online_change
#!/bin/bash
source /root/.bash_profile
vip=`echo '10.0.3.200/24'` #设置VIP
key=`echo '1'`
command=`echo "$1" | awk -F = '{print $2}'`
orig_master_host=`echo "$2" | awk -F = '{print $2}'`
new_master_host=`echo "$7" | awk -F = '{print $2}'`
orig_master_ssh_user=`echo "${12}" | awk -F = '{print $2}'`
new_master_ssh_user=`echo "${13}" | awk -F = '{print $2}'`
#要求服务的网卡识别名一样,都为ens192(这里是)
stop_vip=`echo "ssh root@$orig_master_host /usr/sbin/ifconfig ens192:$key down"`
start_vip=`echo "ssh root@$new_master_host /usr/sbin/ifconfig ens192:$key $vip"`
if [ $command = 'stop' ]
then
echo -e "\n\n\n****************************\n"
echo -e "Disabled thi VIP - $vip on old master: $orig_master_host \n"
$stop_vip
if [ $? -eq 0 ]
then
echo "Disabled the VIP successfully"
else
echo "Disabled the VIP failed"
fi
echo -e "***************************\n\n\n"
fi
if [ $command = 'start' -o $command = 'status' ]
then
echo -e "\n\n\n*************************\n"
echo -e "Enabling the VIP - $vip on new master: $new_master_host \n"
$start_vip
if [ $? -eq 0 ]
then
echo "Enabled the VIP successfully"
else
echo "Enabled the VIP failed"
fi
echo -e "***************************\n\n\n"
fi
9.赋予脚本执行权限
chmod -R 744 /etc/mha/scripts
四 运行MHA10.使用 masterha_check_ssh 命令检查 ssh 互信是否成功
masterha_check_ssh --conf=/etc/mha/app1.cnf
All SSH connection tests passed successfully. #输出这个表示ssh检查通过 11. 使用 masterha_check_repl 命令检查 mysql 主从是否正常
masterha_check_repl --conf=/etc/mha/app1.cnf
MySQL Replication Health is OK. #输出这个代表主从检查通过 12.最后一步启动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 &
13.通过日志检查MHA是否启动成功
tail -f /var/log/masterha/app1/manager.log
Ping(SELECT) succeeded, waiting until MySQL doesn't respond.. #最后一行出现如下字样表明启动成功 14.检查MHA集群状态
[root@mha ~]# masterha_check_status --conf=/etc/mha/app1.cnf app1 (pid:76925) is running(0:PING_OK), master:10.0.3.105
五 故障模拟15.手动结束主库mysql进程(10.0.3.105)
systemctl stop mysqld.service
16.微信收到监控报警信息
17.查看MHA日志,了解整个整个切换过程(10.0.3.112)
cat /var/log/mha/app1/manager.log
18.观察切换完成后变化
1、vip 自动从原来的 master 切换到新的 master。 2、manager 节点的MHA监控进程自动退出(一次性高可用,需要手动恢复)。 3、/etc/mha/app1.cnf 配置文件中原来老的 master 配置节点被删除。
六 将修复好的节点重新加入集群19.修复mysql主从关系在MHA日志中寻找 CHANGE MASTER TO 信息
cat /var/log/mha/app1/manager.log
Mon Aug 31 16:54:59 2020 - [info] All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='10.0.3.105', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='xxx';在修复的故障节点中执行如上 CHANGE MASTER TO 信息,'xxx'为主从复制的密码
mysql> CHANGE MASTER TO MASTER_HOST='10.0.3.105', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='xxx'; mysql> start slave; mysql> show slave status\G;
20.修改manger配置文件 将修复好的节点信息重新加入到配置文件中
vim/etc/mha/app1.conf [server1] candidate_master=1 hostname=10.0.3.105 master_binlog_dir="/data/mysql/binlog"
21.重新检查启动MHA
masterha_check_ssh --conf=/etc/mha/app1.cnf masterha_check_repl --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 & masterha_check_status --conf=/etc/mha/app1.cnf
