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
image

工作原理:

所有操作由MHA自动完成

  1. 如果master挂掉,但是还没完全挂(主机还开机,可以ssh登录系统,仅mysql挂),管理者进系统保存master的二进制日志事件
  2. 在slaves中选出一个最近更新的(relay log最新的)
  3. 把差异的中继日志(relay-log)传给其他slave,再把master的二进制日志传输给所有人
  4. 提升一个slave为master
  5. 使其他的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

  1. 所有从节点日志都是一致的,默认会以配置文件的顺序去选择一个新主
  2. 从节点日志不一致,自动选择最接近于主库的从库充当新主
  3. 如果对于某节点设定了权重(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

借鉴了其他人文章:
mmm与mha
mha高可用

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也自动进行了切换

posted @ 2022-02-17 16:23  suyanhj  阅读(152)  评论(0)    收藏  举报