Mysql数据库(十一)——MHA高可用集群部署及故障切换

  • 一、MHA概述
  • 二、MHA的组成
  • 三、MHA的特点
  • 四、案例环境
  • 1、服务器配置
  • 2、思路
  • 3、关闭防火墙和安全机制,并进行主从配置
  • 4、配置MHA
  • 5、配置无密码认证
  • 6、配置MHA
  • 7、测试
  • 8、模拟故障验证
  • 总结
  • MHA的原理
  • 5、MHA工具的优缺点
  • 优点:
  • 缺点


一、MHA概述



二、MHA的组成

  • MHA Node(数据节点)
  • MHA Node 运行在每台 MySQL 服务器上。
  • MHA Manager(管理节点)
  • MHA Manager 可以单独部署在一台独立的机器上,管理多个 master-slave 集群;也可以部署在一台 slave 节点上
  • MHA Manager 会定时探测集群中的 master 节点。当 master 出现故障时,它可以自动将最新数据的 slave 提升为新的 master, 然后将所有其他的 slave 重新指向新的 master。整个故障转移过程对应用程序完全透明。

三、MHA的特点




四、案例环境

1、服务器配置

主机名

ip地址

角色

所需安装软件包(MHA)

manager

192.168.184.70

manager管理节点

manager组件,node组件

master

192.168.184.10

mysql主数据库

node组件

slave1

192.168.184.20

mysql从数据库

node组件( 主-备 )

slave2

192.168.184.40

mysql从数据库

node组件

2、思路

  • 1、先使用三台mysql服务器,配置一主两从,实现主从复制
  • 2、安装MHA软件
  • 3、配置免密登录和MHA的高可用
  • 4、模拟故障并进行查看

3、关闭防火墙和安全机制,并进行主从配置

#安装编译依赖环境(三台MySQL服务器)
yum -y install ncurses-devel gcc-c++ perl-Module-Install


#安装cmake编译工具
cd /opt
tar zxvf cmake-2.8.6.tar.gz 

cd /opt/cmake-2.8.6/
./configure
gmake && gmake install


#安装mysql5.6
cd /mnt/mha
tar zxvf mysql-5.6.36.tar.gz -C /opt
cd /opt/mysql-5.6.36/
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_EXTRA_CHARSETS=all \
-DSYSCONFDIR=/etc


make && make install 

#复制启动脚本与配置文件
#/etc/init.d/ :各种服务器和程序的二进制文件存放目录。 
#/etc/rc.d/: 各个启动级别的执行程序连接目录。里头的文件很多都是指向init.d/的一些软连接
cp support-files/my-default.cnf /etc/my.cnf
cp:是否覆盖"/etc/my.cnf"? y
cp support-files/mysql.server /etc/rc.d/init.d/mysqld
chmod +755 /etc/rc.d/init.d/mysqld
chkconfig --add /etc/init.d/mysqld
chkconfig mysqld --level 35 on

echo 'PATH=$PATH:/usr/local/mysql/bin' >> /etc/profile
source /etc/profile
tail /etc/profile

useradd -s /sbin/nologin mysql
chown -R mysql.mysql /usr/local/mysql


##mysql_install_db 初始化,目录文件basedir和数据文件datadir都必须要有
/usr/local/mysql/scripts/mysql_install_db \
--basedir=/usr/local/mysql \
--datadir=/usr/local/mysql/data \
--user=mysql


#修改master的主配置文件
#开启二进制日志log_bin,允许从服务器同步log-slave-updates 22行之后
cat /etc/my.cnf
[mysqld]vim
server-id = 1
log_bin = master-bin
log-slave-updates = true


#配置从服务器
#在/etc/my.cnf 中修改或者增加下面内容
#开启中继日志,创建索引,同步主服务器
#slave 1
vim /etc/my.cnf
server-id = 2
log_bin = master-bin
relay-log = relay-log-bin
relay-log-index = slave-realy-bin.index

#slave 2
vim /etc/my.cnf
server-id = 3
log_bin = master-bin
relay-log = relay-log-bin
relay-log-index = slave-realy-bin.index


#第一步关键点
#master、slave1、slave2分别做两个软链接 第一个是mysql命令文件
#第二个mysqlbinlog可用于断点恢复
ln -s /usr/local/mysql/bin/mysql /usr/sbin
ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin


#在后台启动mysql服务()
/usr/local/mysql/bin/mysqld_safe --user=mysql &

#netstat -natp | grep 3306

systemctl stop firewalld.service 
setenforce 0


mysqladmin -uroot -p password '010230'


#配置MySQL 一主两从
#在所有数据库节点上授权两个用户,一个是从库同步使用,另一个是manager使用
第四个账户managter 管理mysql集群使用(监控)
grant replication slave on *.* to 'myslave'@'192.168.184.%' identified by '010230'; 
grant all privileges on *.* to 'mha'@'192.168.184.%' identified by 'manager';
flush privileges;

#下面三条授权,理论上不用添加,但是实验环境通过MHA检查MySQL主从报错,
报两个从库通过主机名连接不上主库,所有数据库都需要添加以下授权
grant all privileges on *.* to 'mha'@'master' identified by 'manager';
grant all privileges on *.* to 'mha'@'slave1' identified by 'manager';
grant all privileges on *.* to 'mha'@'slave2' identified by 'manager';

flush privileges;

通过mha检查的时候,是通过主机名的形式进行监控,这种情况会容易报错


#在master上查看二进制文件和同步点
show master status;

#在两台slave节点服务器进行同步
change master to master_host='192.168.184.10',master_user='myslave',master_password='010230',master_log_file='master-bin.000001',master_log_pos=1499;

start slave;
show slave status\G

#必须设置两个从库为只读模式
set global read_only=1;

flush privileges;

4、配置MHA

#所有节点配置
systemctl stop firewalld
systemctl disable firewllad
vi /etc/sysconfig/selinux
SELINUX=disabled

setenforce 0


#在所有服务器上安装MHA依赖环境,首先安装epel源,只有安装了源 perl才会有
#安装epel源,并且不进行gph检查
yum install epel-release --nogpgcheck -y
	

#perl针对于mysql数据库
#从配置文件中提拿其中的值
#log-日志
#多线程管理
#扩展工具CBuilder  MakeMaker
#cpan perl中的数据库
yum install -y perl-DBD-MySQL \
perl-Config-Tiny \
perl-Log-Dispatch \
perl-Parallel-ForkManager \
perl-ExtUtils-CBuilder \
perl-ExtUtils-MakeMaker \
perl-CPAN


#MHA 软件包对于每个操作系统版本不一样,这里Centos7.4必须选择0.57版本
#在所有服务器上必须先安装node组件,最后在MHA-manager节点上安装manager组件
因为manager依赖node组件,

####所有节点安装node组件
cd /mnt
tar zxvf /mnt/mha4mysql-node-0.57.tar.gz -C /root
cd /root/mha4mysql-node-0.57
perl Makefile.PL
make && make install


#在MHA(manager)节点上安装manager组件(必须先安装node才能安装manager组件)

tar zxvf /mnt/mha4mysql-manager-0.57.tar.gz -C /root
cd /root/mha4mysql-manager-0.57
perl Makefile.PL
make && make install



#manager 安装后在/usr/local/bin目录下会生成几个工具,主要包括以下:
	
masterha-check_ssh  		检查MHA的SSH配置状况
masterha_check_repl  		检查MySQL复制状况
masterha_manager 			启动manager的脚本
masterha_check_status 		检查当前MHA运行状态
masterha_master_monitor 	检查master是否宕机
masterha_master_switch 		控制故障转移(自动或者手动)
masterha_conf_host 			添加或删除配置的server信息
masterha_stop  				关闭manager


#node 安装后也会在/usr/local/bin目录下生成几个脚本,需要进行检查,主要包括以下
save_binary_logs			#保存和复制master的二进制日志
apply_diff_relay_logs 		#识别差异的中继日志事件,并将其差异的事件应用于其他的slave
filter_mysqlbinlog			#去除不必要的ROLLBACK回滚事件(MHA 已不适用这个工具)
purge_relay_logs			#清除中继日志(不会阻塞SQL线程)

mysql router手动切换 mysql数据库切换_perl

5、配置无密码认证

#一、在mannager上配置到所有数据库节点的无密码认证
#一路回车
ssh-keygen -t rsa
ssh-copy-id 192.168.184.10
ssh-copy-id 192.168.184.20
ssh-copy-id 192.168.184.40

#二、在master上配置到slave1和salve2的无密码认证
ssh-keygen -t rsa
ssh-copy-id 192.168.184.20
ssh-copy-id 192.168.184.40


#三、在slave1上配置到master和salve2的无密码认证
ssh-keygen -t rsa
ssh-copy-id 192.168.184.10
ssh-copy-id 192.168.184.40


#四、在slave2上配置到master和salve1的无密码认证
ssh-keygen -t rsa
ssh-copy-id 192.168.184.10
ssh-copy-id 192.168.184.20

mysql router手动切换 mysql数据库切换_mysql_02


mysql router手动切换 mysql数据库切换_mysql_03


mysql router手动切换 mysql数据库切换_perl_04


mysql router手动切换 mysql数据库切换_perl_05

6、配置MHA

1、在MHA节点上复制相关脚本到/usr/local/bin目录
cp -ra /root/mha4mysql-manager-0.57/samples/scripts/ /usr/local/bin
#拷贝后会有四个执行文件
ll /usr/local/bin/scripts/

master_ip_failover			#自动切换时 VIP管理的脚本(故障转移)
master_ip_online_change		#在线切换时 VIP的管理
power_manager				#故障发生后关闭主机的脚本
send_report					#因故障切换后发送报警的脚本

#复制上述的master_ip_failover(自动切换时VIP管理的脚本)	到/usr/local/bin目录 这里使用脚本管理VIP

cp /usr/local/bin/scripts/master_ip_failover /usr/local/bin
cp /usr/local/bin/scripts/master_ip_online_change /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.184.200';			#浮动IP
my $brdc = '192.168.184.255';			#广播地址
my $ifdev = 'ens33';					#使用的网卡为ens33
my $key = '1';							#虚拟接口
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";							#使用ifoconfig命令将其启动,同时设置浮动地址
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down";							#可以使用ifconfig命令将其down掉(关闭)
my $exit_code = 0;						#正常退出(返回状态码)
#my $ssh_start_vip = "/usr/sbin/ip addr add $vip/24 brd $brdc dev $ifdev label $ifdev:$key;/usr/sbin/arping -q -A -c 1 -I $ifdev $vip;iptables -F;";
#my $ssh_stop_vip = "/usr/sbin/ip addr del $vip/24 dev $ifdev label $ifdev:$key";
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 \"`;
}
# 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";
}

% s /#//g


#创建MHA软件目录并拷贝配置文件
mkdir /etc/masterha
cp /root/mha4mysql-manager-0.57/samples/conf/app1.cnf /etc/masterha/
vim /etc/masterha/app1.cnf
#以下部分配置节点相关信息


[server default]
manager_log=/var/log/masterha/app1/manager.log
manager_workdir=/var/log/masterha/app1
master_binlog_dir=/usr/local/mysql/data
master_ip_failover_script=/usr/local/bin/master_ip_failover
master_ip_online_change_script=/usr/local/bin/master_ip_online_change
password=manager
user=mha					
ping_interval=1
remote_workdir=/tmp
repl_password=010230
repl_user=myslave		
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.184.20 -s 192.168.184.40
shutdown_script=""
ssh_user=root			

[server1]
hostname=192.168.184.10
port=3306

[server2]
candidate_master=1
hostname=192.168.184.20
check_repl_delay=0
port=3306

[server3]
hostname=192.168.184.40
port=3306


#manager工作目录
manager_log=/var/log/masterha/app1/manager.log

#manager日志
manager_workdir=/var/log/masterha/app1

#master保存binlog的位置,这里的路径要于master里配置的binlog(相同?)
master_binlog_dir=/usr/local/mysql/data

#设置自动failover时候切换脚本,也就是上一个配置的脚本
master_ip_failover_script=/usr/local/bin/master_ip_failover

#设置手动切换时候的切换脚本
master_ip_online_change_script=/usr/local/bin/master_ip_online_change

#此处密码为之前创建监控用户的密码
password=manager

#设置监控用户
user=mha

#设置监控主库,发送ping包的事件间隔,默认为3秒,尝试三次没有回应的时候自动进性failover
ping_interval=1

#设置远端的MySQL在发生切换时binlog的(临时)保存位置
remote_workdir=/tmp

#设置复制(slaves)用户的密码
repl_password=123456

#设置复制用户的账户
repl_user=myslave

#设置发生切换后发送的报警的脚本
report_script=/usr/local/send_report

#设置检查从服务器的脚本
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.184.20 -s 192.168.184.40

#设置故障发生后关闭故障主机脚本
shutdown_script=""

#设置ssh的登录用户名
ssh_user=root

[server2]
#设置候选master,如果设置了此参数,发生主从切换后,会将此库提升为主库
candidate_master=1
#支持复制的检查,默认情况下如果一个slave落后master 100M的relay logs(中继日志)的话,
MHA将不会选择该slave作为新的master,设置为0的话会忽略此规则
check_repl_delay=0

hostname=192.168.184.20
port=3306

mysql router手动切换 mysql数据库切换_mysql_06

7、测试

#测试无密码认证,如果正常会输出successfully 
masterha_check_ssh -conf=/etc/masterha/app1.cnf

#测试主从复制
masterha_check_repl -conf=/etc/masterha/app1.cnf

#易错的位置:
软连接不创建的话,无法开启故障检测

#需注意:第一次配置需要在master节点上手动开启虚拟IP
/sbin/ifconfig ens33:1 192.168.184.200/24


#启动MHA
#启动时会进行日志记录(在后台开启)
nohup masterha_manager --conf=/etc/masterha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1 &

nohup #选项

masterha_manager #开启

–conf=/etc/masterha/app1.cnf #指定配置文件

–remove_dead_master_conf #当master服务器失效时,发生主从切换后,会把旧的master的ip从主配置文件删除

–ignore_last_failover #忽略故障转移,忽略掉总是宕机不够可靠的服务器

在缺省情况下,如果MHA检测到连续发生宕机,且两次宕机间隔不足8小时的话,则不会进行Failover,
之所以这样限制是为了避免ping-pong效应。该参数代表忽略桑次MHA出发切换产生的文件,默认情况下
,MHA发生切换后会在日志记录下,也就是上面设置的日志app1.failover.complete文件,
下次再次切换的时候如果发现该目录下存在该文件将不允许触发切换,除非在第一次切换后收到删除该文件;
为了方便,这里设为为–ignore_last_failover

< /dev/null > #生成的所有信息会导到null下或者/var/log/masterha/app1/manager.log日志文件中

2>&1 & #把2错误性的输出从定向为标准性输出,开启后台运行

#查看到当前的master节点是谁
masterha_check_status --conf=/etc/masterha/app1.cnf
#查看当前日志信息'
cat /var/log/masterha/app1/manager.log 

#查看MySQL的VIP地址 192.168.184.200是否存在,这个VIP地址不会因为manager节点停止MHA服务而消失
ifconfig

mysql router手动切换 mysql数据库切换_服务器_07

mysql router手动切换 mysql数据库切换_perl_08


mysql router手动切换 mysql数据库切换_mysql_09

8、模拟故障验证

#manager服务器上启用监控观察日志
tailf /var/log/masterha/app1/manager.log 

#模拟故障查看master变化
pkill -9 mysql

VIP地址消失、主备服务器查看ifconfig ,同时查看日志


#重启开启一个客户端(manater),安装mariadb,然后到当前的“master服务器”给与root权限
grant all on *.* to 'root'@'%' identified by '010230';

#此时从manager 远程登陆数据库(通过vip登陆)
mysql -h 192.168.184.20 -p010230

① 创建表、插入数据

② 到当前的主数据库中查看数据

③ 到slave 上show slave status


#模拟故障:
#在主库pkill -9 mysql
#可以看到从库的状态,其中之一肯定由切换为主库的
#切换备选主库的算法
#1一般判断从库是从(position/GTID)判断优劣,数据有差异,最接近于master的slave,称为备选主
#2、数据一致的情况下,按照配置文件顺序选择备选主库
#3、设定有权重(candidate_master=1),按照权重强制指定备选主
#1)默认情况下,如果一个slave落后master 100M的relay logs(中继日志)的话,即使有权重,也会失效
#2)如果check_repl_delay=0的话,即使落后很多日志,也强制选择其为备选主
#故障修复步骤:
#1、修复db
/etc/init.d/mysqld start
#2、修复主从(现主数据库输入show master status;)
从数据库输入:
change master to master_host='192.168.184.20',master_port=3306,master_auto_position=1,master_user='myslave',master_password='010230',master_log_file='master-bin.000001',master_log_pos=1845;
start slave;
#3、修改配置文件(再把这个记录添加进去,因为它检测到失效时候会自动消失)
vi /etc/masterha/app1.cnf
[server1]
hostname=192.168.184.10
port=3306
#4、启动manager(在manager那台机器上)
nohup masterha_manager --conf=/etc/masterha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1 &

#解决中英字不兼容报错的问题
dos2unix /usr/local/bin/master_ip_failover

mysql router手动切换 mysql数据库切换_linux_10


mysql router手动切换 mysql数据库切换_perl_11


mysql router手动切换 mysql数据库切换_服务器_12

1、查看现主服务器同步点
show master status;

2、原主服务器执行操作,以从服务器身份加入集群
change master to master_host='192.168.184.20',master_user='myslave',master_password='010230',master_log_file='master-bin.000001',master_log_pos=1845;
start slave;
show slave status\G

3、manager 节点上修改配置文件app1.cnf
vim /etc/masterha/app1.cnf
……
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.184.10 -s 192.168.184.40
......
[server1]
hostname=192.168.184.20
port=3306

[server2]
candidate_master=1
check_repl_delay=0
hostname=192.168.184.10
port=3306

[server3]
hostname=192.168.184.40
port=3306

mysql router手动切换 mysql数据库切换_mysql_13

mysql router手动切换 mysql数据库切换_linux_14


mysql router手动切换 mysql数据库切换_perl_15

总结

MHA的原理

  • 1、从宕机崩溃的 Master 保存二进制日志事件(binlog event);
  • 2、识别含有最新更新的 Slave;
  • 3、应用差异的中继日志(relay log)到其他 Slave;
  • 4、应用从 Master 保存的二进制日志事件;
  • 5、提升一个 Slave 为新的 Master;
  • 6、使其他的 Slave 连接新的 Master 进行复制;

5、MHA工具的优缺点

优点:

  • 同样是由Perl语言开发的开源工具,可以支持基于GTID的复制模式,MHA在进行故障转移时更不易产生数据丢失,同一个监控节点可以监控多个集群,

缺点

  • 需要编写脚本或利用第三方工具来实现vip的配置,MHA启动后只会对数据库进行监控,需要基于ssh免认证配置,存在一定的安全隐患,没有提供从服务器的读负载均衡的功能。