ITPub博客

首页 > 数据库 > MySQL > MHA高可用架构的实现方式

MHA高可用架构的实现方式

原创 MySQL 作者:easydba 时间:2020-08-31 21:10:44 0 删除 编辑
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-aa5fa8802689"
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-aa5fa8802689"
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


四 运行MHA

10.使用 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


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/69982604/viewspace-2716136/,如需转载,请注明出处,否则将追究法律责任。

下一篇: MySQL多实例部署
请登录后发表评论 登录
全部评论
因为有悔,所以披星戴月;因为有梦,所以奋不顾身! 个人博客首发:easydb.net 微信公众号:easydb 关注我,不走丢!

注册时间:2020-08-25

  • 博文量
    15
  • 访问量
    4666