引言

Mysql服务器中,单台服务器无法承受服务量就配置多台Mysql服务器,多台Myslq服务器或者Mysql服务器冗余的情况下,配置主从复制。没有上去看服务器的读和写的压力不均衡可使用Mysql的读写分离,Mysql的读写分离中Master存在单点故障,就需要用到MHA.

一,Mysql四种同步方式

Mysql有四种同步方式:

  1. 异步复制(Async Replication)
  2. 同步复制(sync Replication)
  3. 半同步复制(Async Replication)
  4. 增强半同步复制(lossless Semi-Sync Replication)、无损复制

1.1 异步复制(Async Replication)

主库将更新写入Binlog日志文件后,不需要等待数据更新是否已经复制到从库中,就可以继续处理更多的请求。Master将事件写入binlog,但并不知道Slave是否或何时已经接收且已处理。在异步复制的机制的情况下,如果Master宕机,事务在Master上已提交,但很可能这些事务没有传到任何的Slave上。假设有Master->Salve故障转移的机制,此时Slave也可能会丢失事务。MySQL复制默认是异步复制,异步复制提供了最佳性能。

 1.2 同步复制 (sync Replication)

主库将更新写入Binlog日志文件后,需要等待数据更新已经复制到从库中,并且已经在从库执行成功,然后才能返回继续处理其它的请求。同步复制提供了最佳安全性,保证数据安全,数据不会丢失,但对性能有一定的影响

 1.3 半同步复制(Semi-Sync Replication)

写入一条数据请求到master,从服务器只要有一台接收到写入自己的中继日志,会给客户端返回一条接收成功的信息。
**主库提交更新写入二进制日志文件后,等待数据更新写入了从服务器中继日志中,然后才能再继续处理其它请求。该功能确保至少有1个从库接收完主库传递过来的binlog内容已经写入到自己的relay log里面了,才会通知主库上面的等待线程,**该操作完毕。
半同步复制,是最佳安全性与最佳性能之间的一个折中。
MySQL 5.5版本之后引入了半同步复制功能,主从服务器必须安装半同步复制插件,才能开启该复制功能。如果等待超时,超过rpl_semi_sync_master_timeout参数设置时间(默认值为10000,表示10秒),则关闭半同步复制,并自动转换为异步复制模式。当master dump线程发送完一个事务的所有事件之后,如果在rpl_semi_sync_master_timeout内,收到了从库的响应,则主从又重新恢复为增强半同步复制。
ACK (Acknowledge character)即是确认字符。
 

 3.4 增强半同步复制(lossless Semi-Sync Replication、无损复制)

增强半同步是在MySQL 5.7引入,其实半同步可以看成是一个过渡功能,因为默认的配置就是增强半同步,所以,大家一般说的半同步复制其实就是增强的半同步复制,也就是无损复制。
增强半同步和半同步不同的是,等待ACK时间不同
rpl_semi_sync_master_wait_point = AFTER_SYNC(默认)
半同步的问题是因为等待ACK的点是Commit之后,此时Master已经完成数据变更,用户已经可以看到最新数据,当Binlog还未同步到Slave时,发生主从切换,那么此时从库是没有这个最新数据的,用户看到的是老数据。
增强半同步将等待ACK的点放在提交Commit之前,此时数据还未被提交,外界看不到数据变更,此时如果发送主从切换,新库依然还是老数据,不存在数据不一致的问题。
 

二,MHA概念 

1,什么是MHA?

1,MHA是一套优秀的Mysql高可用环境下故障切换和主从复制的软件

2,MHA的出现就是解决Mysql单点故障的问题

3,Mysql故障切换过程中,MHA能够0-30秒内自动完成故障切换操作

4,MHA能在故障切换的过程中最大程度上保证数据的一致性,以达到真正意义上的高可用

2,MHA的组成

2,1 MHA Node(数据节点)

MHA Node运行在每台Mysql服务器上

2.2 MHA Manager(管理节点)

1,MHA Manager 可以单独部署在一台独立的机器上,管理多个master-slave集群;也可以部署在一台slave节点上。

2,MHA Manager 会定时探测集群中的master节点。当master出现故障时,他可以自动将最新数据的slave,提升为新的master,然后将所以其他的slave 重新指向新的master。

3,整个故障转系过程对应用程序完全透明。

3,MHA 的特点

1,自动故障切换过程中,MHA试图从宕机的主服务器上保存二进制日志,最大程度的保证数据不丢失

2,使用半同步复制,可以大大降低数据丢失的风险,如果只有一个slave已经收到了最新的二进制日志,MHA可以将最新的二进制日志应用于其他所以的slave服务器上,因此可以保证所以节点的数据一致性

3,目前MHA主从一主多从架构,最少三台服务,即一主两从

MHA:为了解决的是故障切换,数据尽可能的保存,以及所以节点日志的一致性

4,MHA工作原理

MHA Manger管理多组主从复制

  • MHA工作原理总结如下:
  • 从宕机崩溃的master保存二进制日志事件(binlog events);
  • 识别含有最新的更新slave日志
  • 应用差异的中继日志(relay log)到其他的slave
  • 应用从master保存的二进制日志事件
  • 提升一个salve为新的master
  • 是其他的slave连接行的master进行复制

三,搭建Mysql MHA

MHA架构

1,数据库安装

2,一主两从

3,MHA搭建

实验环境

主机

IP地址

MHA Manager

192.168.135.195

master

192.168.135.91

slave1

192.168.135.192

slave 2

192.168.135.193

关闭防火墙

systemctl stop firewalld
systemctl disable firewalld
setenforce 0
yum -y install ntp
 
下载ntp进行时间同步
 
ntpdate ntp1.aliyun.com
进行时间同步,
 
 
24 Sep 20:51:12 ntpdate[10525]: adjust time server 120.25.115.20 offset 0.009524 sec

mysql 主从复制出错_服务器

 

mysql 主从复制出错_mysql_02

 3,主服务器配置(主从同步,192.168.135.91)

mysql 主从复制出错_服务器_03

 三台台机器都需要做软链接

mysql 主从复制出错_mysql_04

 

mysql 主从复制出错_服务器_05

 

mysql 主从复制出错_服务器_06

mysql -uroot -pkya123;
进入数据库
mysql> grant replication slave on *.* to 'myslave'@'192.168.135.%' identified by 
'kya123';
给从服务器提权,允许使用slave的身份复制master的所以数据库的所以表,并且指定密码为kya123;
mysql> flush privileges;
刷新权限表
查看master数据库状态
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000018 |      604 |              |                  |                   |
+------------------+----------+--------------+------------------+--------------

mysql 主从复制出错_数据库_07

 多所以数据库节点进行mysql授权

mysql -uroot -p
grant replication slave on *.* to 'myslave'@'192.168.135.%' identified by 'kya123';		#从数据库同步使用
grant all privileges on *.* to 'mha'@'192.168.135.%' identified by 'manager';		#manager 使用

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;

mysql 主从复制出错_服务器_08

 

mysql 主从复制出错_mysql_09

 

mysql 主从复制出错_服务器_10

 从服务器配置文件(192.168.135.192      192.168.135193)

mysql 主从复制出错_mysql 主从复制出错_11

 

mysql 主从复制出错_服务器_12

 

mysql 主从复制出错_数据库_13

 192.168.135.192

mysql 主从复制出错_服务器_14

 

mysql 主从复制出错_mysql_15

 验证主从复制的效果

在master服务器上创建任意一个库 

mysql 主从复制出错_mysql_16

 在两台从服务器上进行查看,是否可以看到同步来的数据

mysql 主从复制出错_数据库_17

 

mysql 主从复制出错_数据库_18

 查看两个服务器上slave状态时

mysql -uroot -pkya123 -e 'show slave status\G'|grep -i 'yes'

mysql 主从复制出错_数据库_19

 四,安装MHA软件

4.1 所以服务器上都安装MHA依赖的环境

yum install epel-release --nogpgcheck -y
#安装在线源

yum install -y perl-DBD-MySQL \
perl-Config-Tiny \
perl-Log-Dispatch \
perl-Parallel-ForkManager \
perl-ExtUtils-CBuilder \
perl-ExtUtils-MakeMaker \
perl-CPAN
#安装依赖环境

将node组件包放在各个服务器的/opt目录下
cd /opt
tar zxvf mha4mysql-node-0.57.tar.gz
#将node安装包解压当当前目录

cd mha4mysql-node-0.57
#进入目录

perl Makefile.PL
#进行编译

make && make install
#编译安装

mysql 主从复制出错_mysql_20

 

mysql 主从复制出错_mysql_21

mysql 主从复制出错_数据库_22

 

mysql 主从复制出错_mysql_23

 注:所有服务器都要安装依赖环境,包括MHA manager服务器

在manager中间服务器上安装manager组件

4.2 安装MHA 软件包

cd /opt
tar zxvf mha4mysql-manager-0.57.tar.gz
#将安装包进行解压

cd mha4mysql-manager-0.57
#进入解压后的目录

perl Makefile.PL
#进行编译

make && make install
#安装

mysql 主从复制出错_同步复制_24

mysql 主从复制出错_mysql 主从复制出错_25

 manager组件安装在/usr/local/bin 下面会生成几个工具,主要包括以下几个

工具

描述

masterha_check_ssh

检查MHA的SSH配置状况

masterha_check_repl

检查MYSQL复制状况

masterha_manger

启动manager的脚本

master_check_status

检测当前MHA运行状态

masterha_master_monitor

检测master是否宕机

masterha_master_switch

控制故障转移(自动或手动)

masterha_conf_host

添加或删除配置的server信息

masterha_stop

关闭manager

manager组件安装在/usr/local/bin 下面会生成几个脚本,主要包括以下几个(这些工具通常由MHAmabager的脚本触发,无需认为操作),主要如下

脚本工具

描述

save_binary_logs

保存和复制master的二进制日志

apply_diff_relay_logs

识别差异的中继日志事件并将其差异的时间应用于其它的slave

filter_mysqlbinlog

去除不必要的ROLLBACK事件(MHA已不再使用的工具

purge_relay_logs

清除中继日志(不会阻塞sql线程)

mysql 主从复制出错_服务器_26

 4.3 在所以服务器上配置无密码登录

##在manager中间件上配置到所有数据节点的无密码认证##

mysql 主从复制出错_mysql_27

 

mysql 主从复制出错_mysql_28

 

mysql 主从复制出错_服务器_29

 在 master 上配置到数据库节点 slave1 和 slave2 的无密码认证

ssh-copy-id 192.168.135.192
ssh-copy-id 192.168.135.193

在 slave1 上配置到数据库节点 master 和 slave2 的无密码认证

ssh-copy-id 192.168.135.91
ssh-copy-id 192.168.135.193

在 slave2 上配置到数据库节点 master 和 slave1 的无密码认证

ssh-copy-id 192.168.135.91
ssh-copy-id 192.168.135.192

4.4 在manager节点上配置MHA

##在 manager 节点上复制相关脚本到/usr/local/bin 目录##

cp -rp /opt/mha4mysql-manager-0.57/samples/scripts/ /usr/local/bin/
#复制相关脚本到/usr/local/bin中

mysql 主从复制出错_mysql_30

脚本文件

描述

master_ip_failover

自动切换时VIP管理的脚本

master_ip_online_change

在线切换时vip的管理

power_manager

故障发生后关闭主机的脚本

send_report

因故障切换后发送报警的脚本

##复制自动切换vip管理的脚本到/usr/local/bin/目录下##

cp /usr/local/bin/scripts/master_ip_failover /usr/local/bin
#复制上述的自动切换时VIP管理的脚本到/usr/local/bin目录,这里使用master_ip_failover脚本来管理VIP和故障切换

mysql 主从复制出错_数据库_31

 ##修改管理脚本的内容(清空原有脚本)##

vim /usr/local/bin/master_ip_failover   #清空以前的,添加内容如下记得修改ip地址

#!/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.135.100';									#指定vip的地址
my $brdc = '192.168.135.255';								#指定vip的广播地址
my $ifdev = 'ens33';										#指定vip绑定的网卡
my $key = '1';												#指定vip绑定的虚拟网卡序列号
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";		#代表此变量值为ifconfig ens33:1 192.168.10.200
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down";		#代表此变量值为ifconfig ens33:1 192.168.10.200 down
my $exit_code = 0;											#指定退出状态码为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";
}

mysql 主从复制出错_服务器_32

 ##创建MHA软件目录并拷贝配置文件,这里使用app1.cnf配置文件来管理mysql节点服务器##

mkdir /etc/masterha

cp /opt/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日志
manager_workdir=/var/log/masterha/app1            #manager工作目录
master_binlog_dir=/usr/local/mysql/data/         #master保存binlog的位置,这里的路径要与master里配置的binlog的路径一致,以便MHA能找到
master_ip_failover_script=/usr/local/bin/master_ip_failover  #设置自动failover时候的切换脚本,也就是上面的那个脚本
master_ip_online_change_script=/usr/local/bin/master_ip_online_change  #设置手动切换时候的切换脚本
password=manager			#设置mysql中root用户的密码,这个密码是前文中创建监控用户的那个密码
ping_interval=1				#设置监控主库,发送ping包的时间间隔,默认是3秒,尝试三次没有回应的时候自动进行failover
remote_workdir=/tmp			#设置远端mysql在发生切换时binlog的保存位置
repl_password=123		    #设置复制用户的密码
repl_user=myslave			#设置复制用户的用户
report_script=/usr/local/send_report     #设置发生切换后发送的报警的脚本
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.135.192 -s 192.168.135.193	#指定检查的从服务器IP地址
shutdown_script=""			#设置故障发生后关闭故障主机脚本(该脚本的主要作用是关闭主机防止发生脑裂,这里没有使用)
ssh_user=root				#设置ssh的登录用户名
user=mha					#设置监控用户root

[server1]
hostname=192.168.135.91
port=3306

[server2]
hostname=192.168.135.192
port=3306
candidate_master=1
#设置为候选master,设置该参数以后,发生主从切换以后将会将此从库提升为主库,即使这个从库不是集群中最新的slave

check_repl_delay=0
#默认情况下如果一个slave落后master 超过100M的relay logs的话,MHA将不会选择该slave作为一个新的master, 因为对于这个slave的恢复需要花费很长时间;通过设置check_repl_delay=0,MHA触发切换在选择一个新的master的时候将会忽略复制延时,这个参数对于设置了candidate_master=1的主机非常有用,因为这个候选主在切换的过程中一定是新的master

[server3]
hostname=192.168.135.193
port=3306

mysql 主从复制出错_mysql_33

 

mysql 主从复制出错_mysql_34

 4.5 第一次配置需要在master节点上手动开启虚拟ip

/sbin/ifconfig ens33:1 192.168.135.100/24

mysql 主从复制出错_同步复制_35

 4.6 在manager中间件上测试ssh无密码登录

 总结

作用:mysql的高可用+故障切换

核心部分:

MHA组件:

  • manager:主要功能:做MHA的启动、关闭管理和检测mysql各种健康状态
  • node:在发生故障时,尽可能地保存二进制日志,并且实现故障切换(VIP地址漂移)

MHA需要配置的文件:
master ip failover:命令工具,定义的是基于VIP的检测和故障转移(VIP从master—>到新的master)
app1.cnf:mha的主要配置文件,主要定义了mba的工作目录、日志
mysql二进制日志位置
使用mha的登录mysql的用户、密码使用从服务器
身份同步master的账号、密码(5个
故障切换mba会做那些动作?

mha会多次尝试检测master的存活状态
mha会多次尝试尽可能的保存master的二进制日志
mha会根据app1.cnf中的配置部分,进行从服务器—》主服务器
mha最后会将master的VIP作为切换到从服务器的位置
mha在选择完新的master之后,会在其余的slave上执行change master操作,指向新的master,来保证mysql的集群健康性
2、mha的故障问题

  1. 软链接必须得做
  2. 免交互登录
  3. 5个账号授权(其中3个账号是测试环境需要做的)
  4. 初次运行mha的功能时,需要临时添加虚拟IP
  5. 配置文件需要校验(master ip_failover 1个故障切换的脚本,app1.cnf mha的主配置文件)