目录
概念
部署
安装MHA
配置SSH密钥对验证
安装mysql
检测
测试故障
修复
概念
MHA (Master High Availability)目前在MysaL 高可用方面是一个相对成熟的解决方案,它由日本 DeNA 公司的voushimaton员工(现就职于 Facebook 公司)开发,是一套优秀的作为 MysaL 高可用性环境下故障切换和主从角色提升的高可用软件。在MysaL 故障切换过程中,MHA 能做到在 0~30 秒之内自动完成数据库的主从故障切換操作,并且在进行故障切换的过程中,MHA 能在最大程度上保证数据的一致性,以达到真正意义上的高可用。
MHA 由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。MHA Manager
可以单独部署在一台独立的机器上管理多个master-slave 集群,也可以部署在一台slave 节点上。MHA Node 运行在每台 MysaL 服务器及Manager 服务器上,MHA Manager 会定时探测集群中的 master 节点,当master 出现故障时,它可以自动将拥有最新数据的 slave 提升为新的 master,然后将所有其他的slave 重新指向新提升的 master。整个故障转移过程对应用程序层面完全透明。
931 口折马经查•口内容格
在MHA 自动故障切换过程中,MHA 会试图从容机的主服务器上保存二进制日志,最大程度的保证数据不丢失,但这种操作是有概率性的。例如,如果主服务器硬件故障或无法通过ssh 访问,MHA 没法保存二进制日志,只进行故障转移从而丢失了最新的数据。使用 MvSaL
5.5 的半同步复制,可以降低数据丢失的风险。MHA 可以与半同步复制结合起来。如果只有一个slave 己经收到了最新的二进制日志,MHA 可以将最新的二进制日志应用于其他所有的slave 服务器上,因此可以保证所有节点的数据一致性
目前 MHA 主要支持一主多从的架构,要搭建 MHA,要求一个MysaL 复制集群中必须最
少有三合数据库服务器,一主二从,即一台充当 master,一台充当备用 master, 另外一台充当从库,因为至少需要三台服务器,出于机器成本的考虑,淘宝也在该基础上进行了改造,目前淘宝 TMHA 已经支持一主一从。另外对于想快速搭建的可以参考:MHA 快速搭建
我们自己使用其实也可以使用1主1从,但是master 主机宕机后无法切换,以及无法补全
binlog。 master 的mysgld 进程 crash 后,还是可以切换成功,以及补全binlog的。
工作流程
(1)从宏机崩溃的 master 上尝试保存二进制日志事件 (binlog events)
(2)识别含有最新更新的slave 服务器:
(3)应用差异的中继日志 (relay log)到其他的 slave;
(4)应用从master 保存的二进制日志事件 (binlog events);
(5)提升一个slave 为新的 master 服务器:
(6)将其他的 slave 连接指向新的 master 进行主从复制:
MHA 软件由两部分组成,Manager 工具包和 Node 工具包,具体的说明如下
Manager 工具包主要包括以下几个工具:
masterha_check_ssh 检查 MHA 的 SSH 配置状况
masterha_check_rep 检查 MysQL 复制状况
masterha_manger 启动 MHA
masterha_check_status 检测当前 MHA 运行状态
masterha_master_monitor 检测 master 是否宕机
masterha_master_switch 控制故障转移(自动或者手动)
masterha_conf_host 添加或删除配置的 server 信息
Node 工具包(这些具通常由 MHA Manager 的脚本触发,无需人为操作) 主要包括以下几个工具:
save binary_logs 保存和复制 master 的二进制日志
apply diff relay logs 识别差异的中继日志事件并将其差异的事件应用于其他的
slave
filter_mysqlbinlog 去除不必要的 ROLLBACK 事件 (MHA 已不再使用这个工具)
purge relay_ logs 清除中继日志 (不会阻塞 SQL 线程)
部署
安装MHA
准备环境
5台虚拟机
五台虚拟机进行改名更好划分
命令:hostnamectl set-hostname server
刷新:bash
管理器
主服务器
从服务器1
从服务器2
从服务器3
所有机器安装
关闭防火墙
查看yum 、查看光盘挂载
下载epel-release源
可以在直接拉进虚拟机
然后用 rpm -ivh 进行安装
rpm -ivh epel-release-latest-7.noarch.rpm
安装阿里源文件同样直接拉进虚拟机
也可使用以下命令安装
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
然后安装MHA
yum install -y perl-DBD-MySQL.x86_64 perl-DBI.x86_64 perl-CPAN perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker
安装 MHA node
如果rz传输有问题也可直接拉进虚拟机
cd进入找到node软件包直接解压到当前目录即可(五台虚拟机都要操作)
tar xf mha4mysql-node-0.56.tar.gz
进入解压的目录去执行
通过 perl 源来进行配置
perl Makefile.PL
然后编译安装
make && make install
MHA Node安装完后会在 /usr/local/bin生成以下脚本(4个脚本文件)
ls -l /usr/local/bin/
安装MHA Manger
只需要安装一台机器即可(server1)
安装MHA Manger依赖的perl模块
yum install -y perl perl-Log-Dispatch perl-Parallel-ForkManager perl-DBD-MySQL perl-DBI perl-Time-HiRes
然后需要安装perl包可拉进虚拟机
或者rz打开窗口拉进虚拟机
perl-Config-Tiny-2.14-7.el7.noarch.rpm
ls查看
使用 rpm -ivh进行安装
perl-Config-Tiny-2.14-7.el7.noarch.rpm
安装MHA Manger软件包
rz打开窗口拉进虚拟机
mha4mysql-manager-0.56.tar.gz
然后操作下步命令
tar xf mha4mysql-manager-0.56.tar.gz 解压
cd mha4mysql-manager-0.56/ 进入目录
perl Makefile.PL 用perl语言编译文件
make && make install 编译安装
安装完成后会有以下脚本文件(13个脚本文件)
ls -l /usr/local/bin/
配置SSH密钥对验证
【注意各台虚拟机都要实现免密登录】!!!
先对各个虚拟机配置解析
vim /etc/hosts
生成密钥
ssh-keygen
可以通过循环的方式连续生成4次
for i in 115 116 117 126;do ssh-copy-id 192.168.1.$i;done
验证免密登录
ssh server1...5
安装mysql
server2....5
四台主机要装
yum -y install mariadb mariadb-server
然后启动系统
systemctl start mariadb
重启之后
输入命令 查看端口
netstat -lnpt | grep :3306
输入命令
mysqladmin -u root password 123456 设置数据库初始密码
设置主从复制配置文件
vim /etc/my.cnf
【server2】主
server-id = 1
log-bin=master-bin
log-slave-updates=true
relay_log_purge=0
【server3】辅助主
server-id = 2
log-bin=master-bin
log-slave-updates=true
relay_log_purge=0
【server4】从
server-id=3
log-bin=mysql-bin
relay-log=slave-relay-bin
log-slave-updates=true
relay_log_purge=0
【server5】从
server-id=4
log-bin=mysql-bin
relay-log=slave-relay-bin
log-slave-updates=true
relay_log_purge=0
重启服务器
systemctl restart mariadb
授权
server2...4数据库都需要授权
创建授权用户
4台虚拟机登录到mysql
mysql -uroot -p123456
然后授权
grant replication slave on *.* to 'repl'@'192.168.1.%' identified by '123456';
刷新授权
flush privileges;
查看主库状态
show master status;
然后三台从服务器指定主服务器
先关闭从服务器
stop slave;
在输入以下内容
CHANGE MASTER TO
MASTER_HOST='192.168.1.115',
MASTER_USER='repl',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mastar-binlog.000001',
MASTER_LOG_POS=472;
输入以下命令查看MySQL数据库中的复制状态
show slave status\G
【!注意 !!!如出现故障试用一下命令排错】
stop slave;
reset slave;
set global sql_slave_skip_counter =1 ;
start slave
从服务器设置read_only状态
做完这个之后从服务器将不再能写入东西
库外写法
mysql -uroot -p123456 -e 'set global read_only=1;'
库里写法
set global read_only=1;
创建监控用户 server2....5 为监控节点服务较高的权限
grant all privileges on *.* to 'root'@'192.168.1.%' identified by '123456';
刷新权限
flush privileges;
下一步为自己的主机名授权
分别为:
grant all privileges on *.* to 'root'@'server2' identified by '123456';
grant all privileges on *.* to 'root'@'server3' identified by '123456';
grant all privileges on *.* to 'root'@'server4' identified by '123456';
grant all privileges on *.* to 'root'@'server5' identified by '123456';
回到server1上
创建 /etc/masterha 目录 创建配置目录复制模板文件
mkdir /etc/masterha
然后复制root下的mha4mysql-manager-0.56到刚才创建的目录中去
cp mha4mysql-manager-0.56/samples/conf/app1.cnf /etc/masterha
修改刚才拷贝的文件配置
vim /etc/masterha/app1.cnf
[server default]
manager_workdir=/var/log/masterha/app1
manager_log=/var/log/masterha/app1/manager.log
master_binlog_dir=/var/lib/mysql
master_ip_failover_script= /usr/local/bin/master_ip_failoverpassword=123456
user=root
ping_interval=1
remote_workdir=/tmp
reql_password=123456
reql_user=repl
[server1]
hostname=server2
port=3306
[server2]
hostname=server3
candidate_master=1
port=3306
check_repl_delay=0
[server3]
hostname=server4
port=3306[server4]
hostname=server5
port=3306
配置故障转移脚本
打开之后把脚本内容复制进去 修改VIP 修改网卡名
vim /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.200.100';
my $key = "1";
my $ssh_start_vip = "/sbin/ifconfig ens32:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig ens32:$key down";
$ssh_user = "root";
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" ) {
# $orig_master_host, $orig_master_ip, $orig_master_port are passed.
# If you manage master ip address at global catalog database,
# invalidate orig_master_ip here.
my $exit_code = 1;
#eval {
# print "Disabling the VIP on old master: $orig_master_host \n";
# &stop_vip();
# $exit_code = 0;
#};
eval {
print "Disabling the VIP on old master: $orig_master_host \n";
#my $ping=`ping -c 1 10.0.0.13 | grep "packet loss" | awk -F',' '{print $3}' | awk '{print $1}'`;
#if ( $ping le "90.0%"&& $ping gt "0.0%" ){
#$exit_code = 0;
#}
#else {
&stop_vip();
# updating global catalog, etc
$exit_code = 0;
#}
};if ($@) {
warn "Got Error: $@\n";
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "start" ) {
# all arguments are passed.
# If you manage master ip address at global catalog database,
# activate new_master_ip here.
# You can also grant write access (create user, set read_only=0, etc) here.
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";
`ssh $ssh_user\@$orig_master_ip \" $ssh_start_vip \"`;
exit 0;
}
else {
&usage();
exit 1;
}
}
# A simple system call that enable the VIP on the new master
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 {
"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"; }
配置完成之后给其x执行权限
chmod +x /usr/local/bin/master_ip_failover
检测
检查MHA ssh通信状态是否正常
masterha_check_ssh --conf=/etc/masterha/app1.cnf
返回 successfully表示没有问题
检查整个集群的状态
masterha_check_repl --conf=/etc/masterha/app1.cnf
【如果出现 ‘NET OK’可根据以上步骤挨个检查命令有没有打错、或者字母有没有敲错】
检查manager状态
masterha_check_status --conf=/etc/masterha/app1.cnf
如果正常会显示"PING_OK"
NOT_RUNNING",代表MHA监控没有开启
开启监控再查看为开启状态
开启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 &
--remove_dead_master_conf 当发生主从切换后,老的主库的ip将会从配置文件中移除
--manger_log 日志存放位置
--ignore_last_failover
在缺省情况下,如果MHA检测到连续发生宕机,且两次宕机间隔不足8小时的话,则不会进行Failover,之所以这样限制是为了避免ping-pong效应。该参数代表忽略上次MHA触发切换产生的文件,默认情况下,MHA发生切换后会在日志目录,也就是上面我设置的/data产生app1.failover.complete文件,下次再次切换的时候如果发现该目录下存在该文件将不允许触发切换,除非在第一次切换后收到删除该文件,为了方便,这里设置为--ignore_last_failover
关闭监控
masterha_stop --conf=/etc/masterha/app1.cnf
测试故障
监控主机完成配置之后可以查看主数据库网卡以获得vip
ip a | grep ens33
模拟主库故障
systemctl stop mariadb 关掉服务
查看各机器在干嘛是什么角色
tail -f /etc/masterha/app1/manger
完成上步之后从库进入到mysql
show slave status\G
会发现从库指定的ip发生 变化
修复
重启即可
systemctl restart mariadb
但是原本的ip不会在回去
使用一下命令查看
ip a | grep ens33