MHA介绍
MHA是mysql高可用的一个相对成熟的方案,可以实现故障切换。在mysql集群出现故障时,mha可以在短时间内自动完成数据库的故障切换,并在最大程度上保证数据的一致性。
实现故障切花的过程:
各个mysql主从之间通过ssh通信,当master宕机时,mha尝试ssh登入到宕机的机器,保存二进制日志(binlog),从多个slave中识别出含有最新更新的slave,并将其作为备选的master。然后基于该slave同步差异的中继日志(relaylog)到其他slave上,接着同步从原master上保存的二进制文件,将备选的master提升为新的master,使其他的slave连接新的master进行复制,在新的master启动vip地址,保证前端请求可以发送到新的master。
环境准备:
192.168.247.160 master
192.168.247.170 slave01
192.168.247.180 slave02
192.168.247.190 mha
操作系统:centos7
mysql版本:mysql 8.0.17
mha版本:0.58
此实现已经安装好mysql,没有安装的可以参考mysql8安装
搭建
在所有主从上执行,因为每个机器都有可能使master:
create user 'repl'@'%' identified with mysql_native_password by '123457';
grant replication slave on *.* to 'repl'@'%';
flush privileges;
修改所有主从的配置文件my.cnf:
[mysqld]
server_id=160 //server_id不可以相同,可以改成ip对应
log_bin=mysql_bin
relay_log=relay_bin
log_slave_updates=on
gtid_mode=ON //开启gtid模式
enforce_gtid_consistency=ON
重启这三台机器,分别执行:
/etc/init.d/mysqld8 restart
进入slave01,执行:
stop slave;
change master to master_host='192.168.247.160', master_port=3306, master_user='repl', master_password='123457', master_auto_position=1;
start slave;
#查看是否主从成功
show slave status\G;
#结果显示两个yes表示成功
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
进入slave2,操作同上,一模一样。
配置ssh密钥登入各个机器互登:
#其中一台master示例
#生成密钥
ssh-keygen
#配置免密登入
cd /root/.ssh/
ssh-copy-id -i id_rsa root@192.168.247.170
ssh-copy-id -i id_rsa root@192.168.247.180
ssh-copy-id -i id_rsa root@192.168.247.190
其他三台机器也一样。
安装MHA软件
下载地址:
https://github.com/yoshinorim/mha4mysql-node/releases/tag/v0.58 注意,所有节点都需要安装MHA
先安装相关依赖:
yum -y install epel-release
yum -y install perl-DBD-MySQL perl-DBI ncftp
安装mha:
rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm
所有的机器都是一样的操作。
安装mha监控manager,只要在190机器上安装:
#下载地址
https://github.com/yoshinorim/mha4mysql-manager/releases/download/v0.58/mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
#下载好了之后,先安装依赖
yum -y install epel-release
yum -y install perl-Config-Tiny perl-Time-HiRes perl-Parallel-ForkManager perl-Log-Dispatch perl-DBD-MySQL ncftp
#如果有些依赖没有,就重新安装epel包
yum -y remove epel-release
yum -y install epel-release
#下载manager包之后安装
rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
在manager管理机器上配置管理节点:
#创建相关目录
mkdir /etc/mha
mkdir /home/mysql_mha
#编写配置文件
vim /etc/mha/mysql_mha.cnf
#添加
[server default]
#mha访问数据库的账号与密码
user=mha
password=123457
#指定mha的工作目录
manager_workdir=/home/mysql_mha
#指定管理日志路径
manager_log=/home/mysql_mha/manager.log
#指定mha在远程节点上的工作目录
remote_workdir=/home/mysql_mha
#可以使用ssh登入的用户
ssh_user=root
#指定主从复制的mysq用户和密码
repl_user=repl
repl_password=123457
#指定检测间隔时间
ping_interval=1
#指定master节点存放binlog的日志文件的目录
master_binlog_dir=/var/lib/mysql
#指定一个脚本,该脚本实现了在主从切换之后,将虚拟ip漂移到新的master上
master_ip_failover_script=/usr/bin/master_ip_failover
#指定用于二次检查节点状态的节点
secondary_check_script=/usr/bin/masterha_secondary_check -s 192.168.247.160 -s 192.168.247.170 -s 192.168.247.180
#配置集群中的节点
[server1]
hostname=192.168.247.160
#指定该节点可以参与master选举
candidate_master=1
[server2]
hostname=192.168.247.170
candidate_master=1
[server3]
hostname=192.168.247.180
#指定该节点不参与master选举
no_master=1
编写配置文件中提到的/usr/bin/master_ip_failover脚本:
vim /usr/bin/master_ip_failover
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;
my (
$command, $orig_master_host, $orig_master_ip,$ssh_user,
$orig_master_port, $new_master_host, $new_master_ip,$new_master_port,
$orig_master_ssh_port,$new_master_ssh_port,$new_master_user,$new_master_password
);
# 这里定义的虚拟IP可以根据实际情况进行修改
my $vip = '192.168.247.80/24';
my $key = '1';
# 这里的网卡名称 “ens33” 需要根据你机器的网卡名称进行修改
my $ssh_start_vip = "sudo /sbin/ifconfig ens33:$key $vip";
my $ssh_stop_vip = "sudo /sbin/ifconfig ens33:$key down";
my $ssh_Bcast_arp= "sudo /sbin/arping -I bond0 -c 3 -A $vip";
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_ssh_port' => \$new_master_ssh_port,
'new_master_user' => \$new_master_user,
'new_master_password' => \$new_master_password
);
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 - $new_master_host \n";
&start_vip();
&start_arp();
$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() {
`ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}
sub start_arp() {
`ssh $ssh_user\@$new_master_host \" $ssh_Bcast_arp \"`;
}
sub usage {
print
"Usage: master_ip_failover --command=start|stop|stopssh|status --ssh_user=user --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";
}
给该脚本添加可执行权限:
chmod a+x /usr/bin/master_ip_failover
在其他所有节点上创建mha的工作目录:
mkdir /home/mysql_mha
在master上创建mha这个用户来访问数据库节点:
create user 'mha'@'%' identified with mysql_native_password by '123457';
grant all privileges on *.* to 'mha'@'%';
flush privileges;
进行检测工作,检测ssh免密和主从,在manager上执行:
masterha_check_ssh --conf=/etc/mha/mysql_mha.cnf
masterha_check_repl --conf=/etc/mha/mysql_mha.cnf
检测没有报错,可以在manager上启动MHA:
nohup masterha_manager --conf=/etc/mha/mysql_mha.cnf &
用ps检测有没有进程:
ps aux |grep masterha_manager
root 10819 0.2 4.5 299648 22032 pts/0 S 19:23 0:00 perl /usr/bin/masterha_manager --conf=/etc/mha/mysql_mha.cnf
第一次启动的时候,需要给master机器设置vip:
ifconfig ens32:1 192.168.247.80/24
测试MHA服务
用客户机ping192.168.247.80看是否可以通信
可以的话,然后用navicat工具测试能不能用vip连接数据库:
最后通过模拟master宕机,看vip是否漂移到其他机器。