mysql基于mha实现主从复制高可用
mysql高可用:
官方社区给出高可用方案,及数据:
- 简单主从复制: 98-99.9%
- 主主复制/MMM(软件): 99%
- SAN: 99.5-99.9%
- MHA: 99.9%
- NDBCluster/Galera Cluster: 99.999%
MHA介绍:
- 对主节点进行监控,实现自动故障转移至其它从节点;通过提升某一从节点为新的主节点,基于主从复制实现,还需要客户端配合实现,目前MHA主要支持一主多从的架构,要搭建MHA,要求一个复制集群中必须最少有三台数据库服务器,一主二从,即一台充当master,一台充当备用master,另外一台充当从库
Galera Cluster介绍:
- 通过wsrep协议在全局实现复制;任何一节点都可读写,不需要主从复制,实现多主读写
GR(Group Replication)介绍:
- MySQL官方提供的组复制技术(MySQL 5.7.17引入的技术),基于原生复制技术Paxos算法,实现了多主更新,复制组由多个server成员构成,组中的每个server可独立地执行事务,但所有读写事务只在冲突检测成功后才会提交
MHA(Master High Availability):
架构:
一个管理器,对应多个被管理端(master节点),一个被管理端对应多个slave。也就是一个管理器负责多个数据库集群
至少4台主机:1个mha、1个master、2个slave

工作原理:
所有操作由MHA自动完成
- 如果master挂掉,但是还没完全挂(主机还开机,可以ssh登录系统,仅mysql挂),管理者进系统保存master的二进制日志事件
- 在slaves中选出一个最近更新的(relay log最新的)
- 把差异的中继日志(relay-log)传给其他slave,再把master的二进制日志传输给所有人
- 提升一个slave为master
- 使其他的slave连接新的master进行复制
注意:
- 为了尽可能的减少主库硬件损坏宕机造成的数据丢失,因此在配置MHA的同时建议配置成MySQL的半同步复制
MHA软件:
组成:
- Manager工具包
- Node工具包
注意:
- 由于未经维护,版本太老,rhel7只能装 manager包
- node包没有系统版本限制,都可以安装
Manager包的工具:
masterha_check_ssh 检查MHA的SSH配置状况
masterha_check_repl 检查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自定义扩展:
secondary_check_script 通过多条网络路由检测master的可用性
master_ip_ailover_script 更新Application使用的masterip
shutdown_script 强制关闭master节点
report_script 发送报告
init_conf_load_script 加载初始配置参数
master_ip_online_change_script 更新master节点ip地址
MHA配置文件:
global配置:为各application提供默认配置,默认文件路径 /etc/masterha_default.cnf
application配置:为每个主从复制集群
mha实现:
| 2.2.2.13 | mha管理端,centos7 |
| 2.2.2.12 | mha节点,master, centos8 |
| 2.2.2.22 | mha节点,slave节点,centos8 |
| 2.2.2.32 | mha节点,slave节点 ,centos8 |
注意:
- 所有mysql服务都要设置: relay_log_purge=0
- 此项为不清理中继日志,默认的中继日志在每次复制master的二进制日志后,会清理干净,如果slave主机在提升为master后,没有原始master的记录,其他的slave会同步不到真实最新数据
1)在MHA节点,配置所有的ssh免密
方便mha管理端进系统拿二进制文件,不然节点挂掉后不能root登录,都是白做
方法1: 测试时可用,生产环境别玩骚操作
ssh-keygen
ssh-copy-id 127.0.0.1 #记录自己的公钥,方便自己登陆自己
for i in {1..3} ;do rsync -av ~/.ssh 2.2.2.${i}2:/root/ ;done #所有主机都使用一个公私钥
方法2:
ssh-keygen
echo "2.2.2.13 mha
2.2.2.12 msater
2.2.2.22 slave1
2.2.2.32 slave2" >> /etc/hosts
for i in mha msater slave1 slave2; do ssh-copy-id root@${i}; done
for i in mha msater slave1 slave2; do scp /etc/hosts root@${i}:/etc; done
#在其他节点生成秘钥,再次执行上条命令分发出去
for i in mha msater slave1 slave2; do ssh ${i} "ssh-keygen"; done
for i in mha msater slave1 slave2; do ssh-copy-id root@${i}; done
2)在管理节点建立配置文件
mkdir /opt/mastermha
#一个cnf文件代表一个mysql集群
vim app1.cnf
[server default]
user=mhauser #登录MySQL的用户(要有管理员权限)
password=123456
manager_workdir=/opt/mastermha/app1/ #mha管理节点运行时的工作目录,自动生成,无需手动创建
manager_log=/opt/mastermha/app1/manager.log
remote_workdir=/opt/mastermha/app1/ #远程的工作目录
master_binlog_dir=/var/lib/mysql #master主机的二进制日志存放位置
ssh_user=root #ssh登录用户
repl_user=copy #主从复制的用户
repl_password=123456
ping_interval=1 #健康检查的时间间隔
ping_type SELECT SELECT(执行SELECT 1)和CONNECT(创建连接/断开连接)两种方式
master_ip_failover_script=/usr/local/bin/master_ip_failover #切换VIP的perl脚本
report_script=/usr/local/bin/sendmail.sh #报警执行的脚本
check_repl_delay=0 #默认如果slave中从库落后主库relaylog超过100M,主库不会选择这个从库为新的master,因为这个从库进行恢复需要很长的时间.通过这个参数,mha触发主从切换的时候会忽略复制的延时,通过check_repl_delay=0这个参数,mha触发主从切换时会忽略复制的延时,对于设置candidate_master=1的从库非常有用,这样确保这个从库一定能成为最新的master
[server1] #server配置段为mysql服务
hostname=2.2.2.12
candidate_master=1
[server2]
hostname=2.2.2.22
candidate_master=1 #成为master的优先级
[server3]
hostname=2.2.2.32
说明: 主库宕机谁来接管新的master
- 所有从节点日志都是一致的,默认会以配置文件的顺序去选择一个新主
- 从节点日志不一致,自动选择最接近于主库的从库充当新主
- 如果对于某节点设定了权重(candidate_master=1),权重节点会优先选择。但是此节点日志量落后主库超过100M日志的话,也不会被选择。可以配合check_repl_delay=0,关闭日志量的检查,强制选择候选节点
3)写报警脚本和vip切换脚本
报警发邮件脚本
发邮件需要配置smtp邮件,这个可以百度到,博主就不演示了
vim sendmail.sh
echo "MySQL is down" | mail -s "MHA Warning" 1137127273@qq.com
chmod +x sendmail.sh
vip漂移perl脚本
mha的vip漂移,不建议使用keepalived,因为容易导致脑裂(出现两个主机都有vip),建议使用自带的脚本参数指定脚本进行vip切换
根据场景修改配置:
- 建议网卡名称标准化
my $vip = '2.2.2.100/16'; vip地址
my $gateway = '2.2.0.1'; #网关IP
my $interface = 'eth0'; 物理网卡名称
my $key = '1'; 虚拟的网卡名称
vim 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
);
##定义VIP变量
my $vip = '2.2.2.100/16'; #设置Virtual IP
my $gateway = '2.2.0.1'; #网关Gateway IP
my $interface = 'eth0'; #指定VIP所在网卡
my $key = "1";
my $ssh_start_vip = "/sbin/ifconfig $interface:$key $vip;/sbin/arping -I $interface -c 3 -s $vip $gateway >/dev/null 2>&1";
my $ssh_stop_vip = "/sbin/ifconfig $interface:$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" ) {
# $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;
};
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_host \" $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 master_ip_failover
4)master节点配置
vim /etc/my.cnf
[mysqld]
log-bin
server_id=1
skip_name_resolve=1
systemctl restart mariadb
mysql
->show master logs;
grant replication slave,replication client on *.* to copy@"%" identified by "123456";
grant all on *.* to mhauser@"%" identified by "123456";
#为master配置vip
ifconfig eth0:1 2.2.2.100/16
5)slave节点配置
vim /etc/my.cnf
[mysqld]
server_id=2
log-bin
read_only
relay_log_purge=0
skip_name_resolve=1
mysql
->CHANGE MASTER TO
MASTER_HOST='2.2.2.12',
MASTER_USER='copy',
MASTER_PASSWORD='123456',
MASTER_PORT=3306,
MASTER_LOG_FILE='文件',
MASTER_LOG_POS=位置;
start slave;
6)mha安装,验证
mysql客户端版本要>5.7,mariadb客户端>10
#需要先指定epel源,perl-Config-Tiny可能要手动下载:
yum install -y http://vault.centos.org/7.9.2009/os/Source/SPackages/perl-Config-Tiny-2.14-7.el7.src.rpm
yum install -y cpan perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager
#mha管理端,manager和node都要安装
yum install -y mha4mysql-manager-*.rpm
yum install -y mha4mysql-node*.rpm
#mha被管理端只需安装node
yum install -y mha4mysql-node*.rpm
#检查ssh是否可免密登录
masterha_check_ssh --conf=/opt/mastermha/app1.cnf
#检查主从复制是否正常
masterha_check_repl --conf=/opt/mastermha/app1.cnf
7)启动MHA
#开启MHA,默认是前台运行,生产环境使用
nohup masterha_manager --conf=/opt/mastermha/app1.cnf &> /dev/null
或者:
daemonize /usr/bin/masterha_manager --conf=/opt/mastermha/app1.cnf
#测试使用,屏幕输出内容
masterha_manager --conf=/opt/mastermha/app1.cnf
#观察运行日志
tail -f /opt/mastermha/app1/manager.log
#查看运行状态
masterha_check_status --conf=/opt/mastermha/app1.cnf
#排错日志
tail /data/mastermha/app1/manager.log
8)模拟master崩溃
当master down机后,mha会自动退出,也就是mha只能挡一次故障
#查看mha工作工作
tail -f /opt/mastermha/app1/manager.log
killall mysqld
#在旧master和新master上验证vip的切换
ip a
此时会发现mha进程已自动关闭,可观察运行日志manager.log,会有探测master生命的过程信息、slave上任的过程信息
vip也自动进行了切换

浙公网安备 33010602011771号