2021-03-28

MySQL高可用架构之MHA
MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton(现就职于Facebook公司)开发,是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件。在MySQL故障切换过程中,MHA能做到在0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA能在最大程度上保证数据的一致性,以达到真正意义上的高可用。

该软件由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)
MHA工作原理
(1)从宕机崩溃的master保存二进制日志事件(binlog events);
(2)识别含有最新更新的slave;
(3)应用差异的中继日志(relay log)到其他的slave;
(4)应用从master保存的二进制日志事件(binlog events);
(5)提升一个slave为新的master;
(6)使其他的slave连接新的master进行复制;
MHA软件组成
MHA软件由两部分组成
Manager工具包
主要包括以下几个工具
masterha_check_ssh 检查MHA的SSH配置状况
masterha_check_repl 检查MySQL复制状况
masterha_manger 启动MHA
masterha_stop 停止MHA
masterha_check_status 检测当前MHA运行状态
masterha_master_monitor 检测master是否宕机
masterha_master_switch 控制故障转移(自动或者手动)
masterha_conf_host 添加或删除配置的server信息
Node工具包
save_binary_logs 保存和复制master的二进制日志
apply_diff_relay_logs 识别差异的中继日志事件并将其差异的事件应用于其他的slave
filter_mysqlbinlog 去除不必要的ROLLBACK事件(MHA已不再使用这个工具)
purge_relay_logs 清除中继日志(不会阻塞SQL线程)
注意:
为了尽可能的减少主库硬件损坏宕机造成的数据丢失,因此在配置MHA的同时建议配置成MySQL 5.5的半同步复制。(不是必须)
部署MHA
Manager 管理节点
Master 主mysql(写入)
slave1 从mysql(读)
Slave2 从mysql(读)
注:时间要同步(在本实验环境中192.168.30.10主机作为NTP时间服务器)
配置所有主机相互SSH登录无密码验证
ssh-keygen -t rsa
for i in seq 1 4;do ssh-copy-id root@192.168.19.$i; done;

测试ssh无交互登录
for i in 1 2 3 4 ; do ssh 192.168.19.$i hostname ; done;
上传需要的软件包
mha4mysql-manager-0.57-0.el7.noarch.rpm mha4mysql-node-0.57-0.el7.noarch.rpm
mhapath.tar.gz
yum安装软件依赖包
vim /etc/yum.repos.d/mhapath.repo
[mha]
name=mhapath
baseurl=file:///root/mhapath
enabled=1
gpgcheck=0

tar -zxvf mhapath.tar.gz #解压依赖包

vim /etc/yum.repos.d/centos7.repo
[CentOS7]
name=CentOS-server
baseurl=file:///mnt
enabled=1
gpgcheck=0
mount /dev/sr0 /mnt #挂载光驱
拷贝软件包和yum配置文件到其他节点
for ip in 1 2 3 ; do scp -r /etc/yum.repos.d/* 192.168.19.$ip:/etc/yum.repos.d/ ; done

批量上传包
for ip in 1 2 3 ; do scp /root/mha4mysql-node-0.57-0.el7.noarch.rpm 192.168.19.$ip:/root ; done;

for b in 1 2 3 ; do scp -r /root/mhapath 192.168.19.$b:/root ; done;
在manager主机和各个node节点安装软件依赖件包

批量解压包
for i in seq 1 4;do ssh 192.168.19.$i yum -y install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager --skip-broken --nogpgcheck ;done;

for i in seq 1 4;do ssh 192.168.19.$i rpm -ivh /root/mha4mysql-node-0.57-0.el7.noarch.rpm ;done;

三台服务器挂载mount /dev/sr0 /mnt
安装完成后会在/usr/bin/目录下生成以下脚本文件:
cd /usr/bin/
ll app* filter* purge* save*
注:
save_binary_logs 保存和复制master的二进制日志
apply_diff_relay_logs 识别差异的中继日志事件并将其差异的事件应用于其他的slave
filter_mysqlbinlog 去除不必要的ROLLBACK事件(MHA已不再使用这个工具)
purge_relay_logs 清除中继日志(不会阻塞SQL线程)

安装MHA Manager
安装MHA Manger依赖的perl模块
yum install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker perl-CPAN -y
安装MHA Manager软件包:
rpm -ivh mha4mysql-manager-0.57-0.el7.noarch.rpm
安装完成后会在/usr/bin目录下面生成以下脚本文件:
ll /usr/bin/mast*
注:
masterha_check_ssh 检查MHA的SSH配置状况
masterha_check_repl 检查MySQL复制状况
masterha_manger 启动MHA
masterha_stop 停止MHA
masterha_check_status 检测当前MHA运行状态
masterha_master_monitor 检测master是否宕机
masterha_master_switch 控制故障转移(自动或者手动)
masterha_conf_host 添加或删除配置的server信息

搭建主从复制环境
注:mysql半同步插件是由谷歌提供,具体位置/usr/local/mysql/lib/plugin/下,一个是master用的semisync_master.so,一个是slave用的semisync_slave.so
1、分别在主从节点上安装相关的插件(master,备主master,slave),在MySQL上安装插件需要数据库支持动态载入。检查是否支持,用如下检测:
show variables like ‘%have_dynamic_loading%’;
所有mysql数据库服务器,安装半同步插件(semisync_master.so,semisync_slave.so)
install plugin rpl_semi_sync_master soname ‘semisync_master.so’ ;

install plugin rpl_semi_sync_slave soname ‘semisync_slave.so’;

其他mysql主机采用同样的方法安装半同步插件
show plugins; #检查Plugin是否已正确安装
查看半同步相关信息:
show variables like ‘%rpl_semi_sync%’;
还没有启用,所以是off
配置主数据库服务器
vim /etc/my.cnf
server-id=1
log-bin=/data/mysql/log/mysql-bin
log-bin-index=/data/mysql/log/mysql-bin.index
binlog_format=mixed
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=10000
rpl_semi_sync_slave_enabled=1
relay_log_purge=0
relay-log = /data/mysql/log/relay-bin
relay-log-index = /data/mysql/log/slave-relay-bin.index
binlog-do-db=HA
log_slave_updates=1

注:相关参数解释
rpl_semi_sync_master_enabled=1 1表是启用,0表示关闭
rpl_semi_sync_master_timeout=10000 毫秒单位,该参数表示主服务器等待确认消息,10秒后,不再等待,变为异步方式。(1s=1000ms)
relay_log_purge=0禁止 SQL 线程在执行完一个 relay log 后自动将其删除,对于MHA场景下,对于某些滞后从库的恢复依赖于其他从库的relay log,因此采取禁用自动删除功能,

systemctl restart mysqld #重启服务
创建需要同步的数据库:
mysql -uroot -p123456
create database HA;
use HA;
create table test(id int,name varchar(20));
insert into test values(1,‘tom1’);

授权:
grant replication slave on . to repl@‘192.168.19.%’ identified by ‘123456’;
grant all privileges on . to manager@‘192.168.19.%’ identified by ‘123456’;
flush privileges; #刷新权限
show master status;查看master的状态
导出HA数据库到从服务器
mysqldump -uroot -p123456 -B HA>HA.sql
scp HA.sql root@192.168.19.2:~
scp HA.sql root@192.168.19.3:~
配置slave1从服务:
导入数据库
mysql -uroot -p123456 <HA.sql

配置my.cnf:
vim /etc/my.cnf
server-id=2
log-bin=/data/mysql/log/mysql-bin
log-bin-index=/data/mysql/log/mysql-bin.index
binlog_format=mixed
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=10000
rpl_semi_sync_slave_enabled=1
relay_log_purge=0
relay-log=/data/mysql/log/relay-bin
relay-log-index=/data/mysql/log/slave-relay-bin.index
binlog-do-db=HA
log_slave_updates=1
#只有开启log_slave_updates,从库binlog才会记录主库同步的操作日志

systemctl restart mysqld #重启服务器
授权
grant replication slave on . to repl@‘192.168.19.%’ identified by ‘123456’;
grant all privileges on . to manager@‘192.168.19.%’ identified by ‘123456’;
flush privileges; #刷新权限
建立主从关系
stop slave;
change master to master_host=‘192.168.19.1’,master_user=‘repl’,master_password=‘123456’,master_log_file=‘mysql-bin.000001’,master_log_pos=1350;
start slave;
show slave status\G

配置slave2从服务:
导入数据库
mysql -uroot -p123456 <HA.sql
配置my.cnf:
vim /etc/my.cnf
server-id=3
log-bin=/data/mysql/log/mysql-bin
log-bin-index=/data/mysql/log/mysql-bin.index
binlog_format=mixed
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=10000
rpl_semi_sync_slave_enabled=1
relay_log_purge=0
relay-log = /data/mysql/log/relay-bin
relay-log-index = /data/mysql/log/slave-relay-bin.index
binlog-do-db=HA
log_slave_updates=1
只有开启log_slave_updates,从库binlog才会记录主库同步的操作日志
授权

grant replication slave on . to repl@‘192.168.19.%’ identified by ‘123456’;
grant all privileges on . to manager@‘192.168.19.%’ identified by ‘123456’;
flush privileges; #刷新权限
建立主从关系
stop slave;
change master to master_host=‘192.168.19.1’,master_user=‘repl’,master_password=‘123456’,master_log_file=‘mysql-bin.000001’,master_log_pos=1350;
start slave;
show slave status\G
两台slave服务器设置read_only
mysql -uroot -p123456 -e ‘set global read_only=1’
在master上查看半同步相关信息:
show variables like ‘%rpl_semi_sync%’;
查看半同步状态:
show status like ‘%rpl_semi_sync%’;

配置MHA
创建MHA的工作目录,并且创建相关配置文件
mkdir -p /etc/masterha
mkdir -p /var/log/masterha/app1
vim /etc/masterha/app1.cnf
[server default]
manager_workdir=/var/log/masterha/app1
manager_log=/var/log/masterha/app1/manager.log
master_binlog_dir=/data/mysql/log
master_ip_failover_script= /usr/bin/master_ip_failover
master_ip_online_change_script=/usr/bin/master_ip_online_change

user=manager
password=123456
ping_interval=1
remote_workdir=/tmp
repl_user=repl
repl_password=123456
report_script=/usr/local/send_report
shutdown_script=""
ssh_user=root

[server1]
hostname=192.168.19.1
port=3306

[server2]
hostname=192.168.19.2
port=3306

[server3]
hostname=192.168.19.3
port=3306

检查SSH配置
检查MHA Manger到所有MHA Node的SSH连接状态:
masterha_check_ssh --conf=/etc/masterha/app1.cnf
如果报错:请检查你所有节点是不是都配置了SSH免密登陆
检查整个复制环境状况
masterha_check_repl --conf=/etc/masterha/app1.cnf
在验证时,若遇到这个错误:Can’t exec “mysqlbinlog” …
解决方法是在所有mysql服务器上执行:
ln -s /usr/local/mysql/bin/* /usr/local/bin/
在验证时,若遇到这个错误:Can’t exec /usr/bin
解决方法先暂时将/etc/masterha/app1.cnf这两行注释掉。
#master_ip_failover_script=/usr/bin/master_ip_failover
#master_ip_online_change_script=/usr/bin/master_ip_online_change
这个报错

删除之前健康检查的文件
rm -rf /var/log/masterha/app1/app1.master_status.health
检查MHA Manager的状态:
masterha_check_status --conf=/etc/masterha/app1.cnf
正常,会显示"PING_OK"
开启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 &
再次查看MHA Manager监控是否正常
masterha_check_status --conf=/etc/masterha/app1.cnf
查看启动日志
tail -20 /var/log/masterha/app1/manager.log
关闭MHA Manage监控
masterha_stop --conf=/etc/masterha/app1.cnf
模拟故障
开启监控
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 &

模拟主库挂掉
systemctl stop mysqld
看日志是否切换master成功
tail -20 /var/log/masterha/app1/manager.log
登陆slave2查看show slave status\G是否成功切换
show slave status\G
可以看到 master 的 IP 现在为 192.168.19.2,已经切换到和192.168.19.2同步了,本来是和192.168.19.1同步的,说明 MHA 已经把cong12提升为了新的 master,IO线程和SQL线程也正确运行,MHA 搭建成功。
查看slave1主从状态
show processlist \G
发现只剩下slave2的slave,MHA把原先的master踢掉了
关于配置VIP配合MHA使用
使用VIP 可以实现mysql master服务器的高可用。
vip配置可以采用两种方式,一种通过keepalived的方式管理虚拟ip的浮动;另外一种通过脚本方式启动虚拟ip的方式(即不需要keepalived或者heartbeat类似的软件)。
在mysql主上配置VIP
手动在master服务器上绑定一个vip由于刚才把mysql主切换到slave1上,这里在slave1上配置。
ifconfig ens33:1 192.168.19.200 netmask 255.255.255.0 up
在主配置文件里开启脚本
在主配置文件添加master_ip_failover_script=/usr/bin/master_ip_failover,MHA切换master后,会把原先的msater清除,把刚才清掉的cong11的mysql 添加进主配置文件,设为slave。
vim /etc/masterha/app1.cnf
master_ip_failover_script=/usr/bin/master_ip_failover #开启脚本
[server1] # 添加master
hostname=192.168.19.1
port=3306
把master设为mysql从服务器
重构:
重构就是你的主挂了,切换到备主 master上,备主master变成了主,因此重构就是将原来的主库修复成一个新的slave
grep “CHANGE MASTER TO MASTER” /var/log/masterha/app1/manager.log | tail -1
CHANGE MASTER TO MASTER_HOST=‘192.168.30.12’, MASTER_PORT=3306, MASTER_LOG_FILE=‘mysql-bin.000001’, MASTER_LOG_POS=2311, MASTER_USER=‘repl’, MASTER_PASSWORD=‘123456’;
systemctl start mysqld
mysql -uroot -p123456
stop slave;
CHANGE MASTER TO MASTER_HOST=‘192.168.30.12’, MASTER_PORT=3306, MASTER_LOG_FILE=‘mysql-bin.000001’,MASTER_LOG_POS=2311, MASTER_USER=‘repl’, MASTER_PASSWORD=‘123456’;
start slave;
show slave status\G
查看slave1master状态
mysql -uroot -p123456
show processlist \G
MHA
编写脚本/usr/bin/master_ip_failover,要会perl脚本语言
vim /usr/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.19.200/24’;
my $key = ‘1’;
my s s h s t a r t v i p = " / s b i n / i f c o n f i g e n s 33 : ssh_start_vip = "/sbin/ifconfig ens33: sshstartvip="/sbin/ifconfigens33:key $vip";
my s s h s t o p v i p = " / s b i n / i f c o n f i g e n s 33 : ssh_stop_vip = "/sbin/ifconfig ens33: sshstopvip="/sbin/ifconfigens33: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";
    #`ssh $ssh_user\@cluster1 \" $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 {
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”;
}
给脚本添加可执行权限
chmod +x /usr/bin/master_ip_failover
检查SSH配置
masterha_check_ssh --conf=/etc/masterha/app1.cnf
检查整个集群复制环境状况
需要删除之前健康检查的文件
rm -rf /var/log/masterha/app1/app1.master_status.health //如果存在就删除
masterha_check_repl --conf=/etc/masterha/app1.cnf
开启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 &
查看MHA Manager监控是否正常
masterha_check_status --conf=/etc/masterha/app1.cnf
查看启动日志
tail -20 /var/log/masterha/app1/manager.log
模拟主库挂掉
[root@slave1 ~]# systemctl stop mysqld
看日志是否切换master成功
登陆从slave2查看show slave status\G是否成功切换
mysql -uroot -p123456
show slave status\G
查看master主从状态
mysql -uroot -p123456
show processlist \G
查看VIP是否漂移过来
ifconfig
注意:master切换以后,MHA监控就会停止,会在配置文件删除出问题的主机配置信息,我们可以把出问题的mysql服务器修复好以后,重新添加进集群,开启MHA监控。
重构
grep “CHANGE MASTER TO MASTER” /var/log/masterha/app1/manager.log | tail -1
将slave1修复为master的从库
systemctl start mysqld
stop slave;
CHANGE MASTER TO MASTER_HOST=‘192.168.30.11’, MASTER_PORT=3306, MASTER_LOG_FILE=‘mysql-bin.000002’, MASTER_LOG_POS=154, MASTER_USER=‘repl’, MASTER_PASSWORD=‘123456’;
start slave;
show slave status\G;
编辑/etc/masterha/app1.cnf
vim /etc/masterha/app1.cnf

master_ip_failover_script=/usr/bin/master_ip_failover

[server2]
hostname=192.168.19.2 //修改192.168.30.11为192.168.30.12
port=3306

检查SSH配置
masterha_check_ssh --conf=/etc/masterha/app1.cnf
检查整个集群复制环境状况
需要删除之前健康检查的文件
rm -rf /var/log/masterha/app1/app1.master_status.health //如果存在就删除
masterha_check_repl --conf=/etc/masterha/app1.cnf 查看
开启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 &

查看MHA Manager监控是否正常
masterha_check_status --conf=/etc/masterha/app1.cnf

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值