MySQL合集-基于MHA搭建高可用架构
nanshan 2025-07-01 22:15 1 浏览 0 评论
MHA架构介绍
MHA是Master High Availability的缩写,它是目前MySQL高可用方面的一个相对成熟的解决方案,其核心是使用perl语言编写的一组脚本,是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件。在MySQL故障切换过程中,MHA能做到在0~30秒之内自动完成数据库的故障切换操作,并且能在最大程度上保证数据的一致性,以达到真正意义上的高可用。
基于MHA的架构不像MMM那样需要搭建主主复制,只需要搭建基本的主从复制架构即可。因为MHA在主库挂掉时,是在多个从库中选取出一个从库作为新的主库。MHA集群中的各节点彼此之间均需要基于ssh互信通信,以实现远程控制及数据管理功能。
MHA提供了什么功能:
可以监控Master节点是否可用
当Master不可用时,能在多个Slave中选举出新的Master
提供了主从切换和故障转移功能,MHA会尝试在宕机的Master上保存binlog,在最大程度上保证事务不丢失。但如果是Master所在的服务器已经无法访问,或硬件层面出现了问题,则无法成功保存binlog
MHA可以与半同步复制结合,避免从库之间出现数据不一致的情况
支持MySQL基于GTID和基于日志点的两种复制方式
MHA故障转移过程:
尝试使用ssh登录到宕机崩溃的Master节点上保存二进制日志事件(binlog events);
从多个Slave中识别含有最新更新的Slave,将其作为备选的Master;
然后基于该Slave同步差异的中继日志(relaylog)到其他的Slave上;
接着同步从原Master上保存的二进制日志事件(binlog events);
将备选的Master提升为新的Master;
使其他的Slave连接新的Master进行复制;
在新的Master启动vip地址,保证前端请求可以发送到新的Master。
MHA的架构图如下:
动手搭建MHA架构
本文中所使用的机器说明:
名称 | HOST | 角色 |
master | 10.7.6.10 | master mha node |
slave-01 | 10.7.6.11 | slave mha node |
slave-02 | 10.7.6.9 | slave mha node |
manager | 10.7.6.9 | mha manager |
环境版本说明:
操作系统版本:CentOS 7
MySQL版本:5.7
MHA版本:0.58
修改主机名
分别在三台主机上修改IP主机名:
vim /etc/hosts
添加如下配置:
i
关闭防火墙
每个主机上都需要进行操作:
systemctl stop iptables
systemctl stop firewalld
systemctl disable firewalld.service
配置主机间SSH信任,实现免密登录
分别在每台主机上创建密钥对:
ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa >/dev/null 2>&1
将公钥分别发送到其他主机上
ssh-copy-id -i /root/.ssh/id_dsa.pub root@master
ssh-copy-id -i /root/.ssh/id_dsa.pub root@slave-01
ssh-copy-id -i /root/.ssh/id_dsa.pub root@slave-02
验证免密登录是否成功:
ssh master
ssh slave-01
ssh slave-02
如果不用输入密码就能登录,则证明配置成功。
MYSQL主从复制搭建
安装文件准备
需要分别将MYSQL安装包
mysql-5.7.28-1.el7.x86_64.rpm-bundle.tar和MHA node安装包
mha4mysql-node-0.58-0.el7.centos.noarch.rpm上传到三台主机上,
并且将MHA manager安装包
mha4mysql-manager-0.58-0.el7.centos.noarch.rpm上传到slave-02上。
卸载已有数据库
某些centos主机自带了mariadb数据库,因此需要先卸载再安装。
查看自带的mariadb数据库:
rpm -qa|grep mariadb
卸载自带的mariadb数据库:
rpm -e mariadb-libs-5.5.60-1.el7_5.x86_64
如果之前有安装过其他版本的MYSQL,也可以通过上面的命令进行卸载。
安装MYSQL
分别在主库、从库上进行以下操作:
解压MYSQL安装文件:
tar -xvf mysql-5.7.28-1.el7.x86_64.rpm-bundle.tar
安装common模块:
rpm -ivh mysql-community-common-5.7.28-1.el7.x86_64.rpm
安装libs模块:
rpm -ivh mysql-community-libs-5.7.28-1.el7.x86_64.rpm
安装libs补丁包:
rpm -ivh mysql-community-libs-compat-5.7.28-1.el7.x86_64.rpm
安装mysql client端:
rpm -ivh mysql-community-client-5.7.28-1.el7.x86_64.rpm
安装mysql server端:
rpm -ivh mysql-community-server-5.7.28-1.el7.x86_64.rpm
安装devel(可选):
rpm -ivh mysql-community-devel-5.7.28-1.el7.x86_64.rpm
初始化MYSQL:
mysqld --initialize --user=mysql
查看mysql默认生成的密码:
cat /var/log/mysqld.log
找到日志最后生成的默认登录密码,并记下,下面登录需要使用。
将mysql服务做成系统服务并启动:
systemctl start mysqld.service
登录MYSQL(输入上面在日志文件中找到的默认密码):
mysql -uroot -p
登录成功后,修改root账号密码:
set password=password('Unicloud.1');
退出后,使用root账号的新密码重新登录MYSQL
配置主从节点的配置文件
1、在所有主从节点上使用如下语句创建用于主从复制的MySQL用户,因为每个从库都有可能会被选举为主库,所以都需要拥有用于复制的用户:
create user 'root'@'%' identified with mysql_native_password by 'Unicloud.1';
grant replication slave on *.* to 'root'@'%';
flush privileges;
2、然后修改master节点上的MySQL配置文件:
[root@master ~]# vim /etc/my.cnf
[mysqld]
# 设置当前节点的id
server_id=101
# 开启binlog,并指定binlog文件的名称
log_bin=mysql_bin
# 开启relay_log,并指定relay_log文件的名称
relay_log=relay_bin
# 将relaylog的同步内容记录到binlog中
log_slave_updates=on
# 开启GTID复制模式
gtid_mode=ON
enforce_gtid_consistency=1
3、在slave-01的配置文件中也是添加一样配置,只不过server_id不一样:
[root@slave-01 ~]# vim /etc/my.cnf
[mysqld]
server_id=102
log_bin=mysql_bin
relay_log=relay_bin
log_slave_updates=on
gtid_mode=ON
enforce_gtid_consistency=1
4、接着是配置slave-02:
[root@slave-02 ~]# vim /etc/my.cnf
[mysqld]
server_id=103
log_bin=mysql_bin
relay_log=relay_bin
log_slave_updates=on
gtid_mode=ON
enforce_gtid_consistency=1
完成以上配置文件的修改后,分别重启这三个节点上的MySQL服务:
systemctl restart mysqld.service
[root@master ~]# systemctl restart mysqld
[root@slave-01 ~]# systemctl restart mysqld
[root@slave-02 ~]# systemctl restart mysqld
配置主从关系
进入slave-01节点的MySQL命令行终端,分别执行如下语句来配置主从复制链路:
-- 停止主从同步
mysql> stop slave;
-- 配置master节点的连接信息
mysql> change master to master_host='10.7.6.10', master_port=3306, master_user='root', master_password='Unicloud.1', master_auto_position=1;
-- 启动主从同步
mysql> start slave;
配置完主从复制链路后,查看主从同步状态
mysql> show slave status\G;
看到数据显示(Slave_IO_Running和Slave_SQL_Running的值均为Yes才能表示主从同步状态是正常的):
同样的步骤,进入slave-02节点的MySQL命令行终端,分别执行如下语句来配置主从复制链路:
-- 停止主从同步
mysql> stop slave;
-- 配置master节点的连接信息
mysql> change master to master_host='10.7.6.10', master_port=3306, master_user='root', master_password='Unicloud.1', master_auto_position=1;
-- 启动主从同步
mysql> start slave;
配置完主从复制链路后,查看主从同步状态
mysql> show slave status\G;
看到数据显示(Slave_IO_Running和Slave_SQL_Running的值均为Yes才能表示主从同步状态是正常的):
安装MHA软件包
1、首先在所有的节点上安装mha4mysql-node软件包
在安装该rpm包之前需要先安装perl相关依赖:
[root@master ~]# yum -y install epel-release
[root@master ~]# yum -y install perl-DBD-MySQL perl-DBI ncftp
现在就可以安装mha4mysql-node了,命令如下:
[root@master ~]# rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm
另外的两个Slave节点按如上步骤安装即可,这里就不重复演示了
2、接着是在监控节点manager上安装mha4mysql-manager软件包:
同样,在安装该rpm包之前需要先安装perl相关依赖:
[root@manager ~]# yum -y install epel-release
[root@manager ~]# yum -y install perl-Config-Tiny perl-Time-HiRes perl-Parallel-ForkManager perl-Log-Dispatch perl-DBD-MySQL ncftp
然后安装mha4mysql-manager包,命令如下:
[root@manager ~]# rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
配置MHA管理节点
1、创建MHA的配置文件存放目录和工作目录:
[root@manager ~]# mkdir /etc/mha
[root@manager ~]# mkdir /home/mysql_mha
2、创建MHA的配置文件,并添加如下内容:
[root@manager ~]# vim /etc/mha/mysql_mha.cnf
[server default]
# mha用于访问数据库的账户和密码
user=mha
password=Unicloud.1
# 指定mha的工作目录
manager_workdir=/home/mysql_mha
# mha日志文件的存放路径
manager_log=/home/mysql_mha/manager.log
# 指定mha在远程节点上的工作目录
remote_workdir=/home/mysql_mha
# 可以使用ssh登录的用户
ssh_user=root
# 用于主从复制的MySQL用户和密码
repl_user=root
repl_password=Unicloud.1
# 指定间隔多少秒检测一次
ping_interval=1
# 指定master节点存放binlog日志文件的目录
master_binlog_dir=/var/lib/mysql
# 指定一个脚本,该脚本实现了在主从切换之后,将虚拟IP漂移到新的Master上
master_ip_failover_script=/usr/bin/master_ip_failover
# 指定用于二次检查节点状态的脚本
secondary_check_script=/usr/bin/masterha_secondary_check -s 10.7.6.10 -s 10.7.6.11 -s 10.7.6.9
# 配置集群中的节点信息
[server1]
hostname=10.7.6.10
# 指定该节点可以参与Master选举
candidate_master=1
[server2]
hostname=10.7.6.11
candidate_master=1
[server3]
hostname=10.7.6.9
# 指定该节点不能参与Master选举
no_master=1
3、编写配置文件中所配置的master_ip_failover脚本,该脚本是根据MHA的官方示例修改的,MHA默认并没有提供。需要注意脚本中的几处地方需要根据实际情况进行修改,已用注释标明:
[root@manager ~]# vim /usr/bin/master_ip_failover
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;
my (
$command, $orig_master_host, $orig_master_ip,$ssh_user,
$orig_master_port, $new_master_host, $new_master_ip,$new_master_port,
$orig_master_ssh_port,$new_master_ssh_port,$new_master_user,$new_master_password
);
# 这里定义的虚拟IP可以根据实际情况进行修改
my $vip = '10.7.6.200/25';
my $key = '1';
# 这里的网卡名称 “eth0” 需要根据你机器的网卡名称进行修改
my $ssh_start_vip = "sudo /sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "sudo /sbin/ifconfig eth0:$key down";
my $ssh_Bcast_arp= "sudo /sbin/arping -I bond0 -c 3 -A $vip";
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,
'orig_master_ssh_port=i' => \$orig_master_ssh_port,
'new_master_host=s' => \$new_master_host,
'new_master_ip=s' => \$new_master_ip,
'new_master_port=i' => \$new_master_port,
'new_master_ssh_port' => \$new_master_ssh_port,
'new_master_user' => \$new_master_user,
'new_master_password' => \$new_master_password
);
exit &main();
sub main {
$ssh_user = defined $ssh_user ? $ssh_user : 'root';
print "\n\nIN SCRIPT TEST====$ssh_user|$ssh_stop_vip==$ssh_user|$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();
&start_arp();
$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 \"`;
}
sub stop_vip() {
`ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}
sub start_arp() {
`ssh $ssh_user\@$new_master_host \" $ssh_Bcast_arp \"`;
}
sub usage {
print
"Usage: master_ip_failover --command=start|stop|stopssh|status --ssh_user=user --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";
}
还需要给该脚本添加可执行权限,否则MHA是无法调用的:
[root@manager ~]# chmod a+x /usr/bin/master_ip_failover
4、根据配置文件中remote_workdir的配置,需在其他节点上创建MHA的远程工作目录:
[root@master ~]# mkdir /home/mysql_mha
[root@slave-01 ~]# mkdir /home/mysql_mha
[root@slave-02 ~]# mkdir /home/mysql_mha
5、在配置文件中指定了让manager使用mha这个用户来访问数据库节点,所以需要在master节点上创建mha用户:
create user 'mha'@'%' identified with mysql_native_password by 'Unicloud.1';
grant all privileges on *.* to 'mha'@'%';
flush privileges;
6、完成以上所有步骤后,在manager节点上使用masterha_check_ssh和masterha_check_repl对配置进行检查,其中masterha_check_ssh用于检查ssh登录是否正常,而masterha_check_repl则用于检查主从节点的复制链路是否正常:
[root@ELK-3 ~]# masterha_check_ssh --conf=/etc/mha/mysql_mha.cnf
[root@ELK-3 ~]# masterha_check_repl --conf=/etc/mha/mysql_mha.cnf
执行结果如下:
7、以上检测都通过后,就可以启动MHA服务了。启动命令如下:
[root@ELK-3 ~]# nohup masterha_manager --conf=/etc/mha/mysql_mha.cnf &
启动完成后,可以使用ps命令查看masterha_manager进程是否存在,如下存在则代表启动成功:
[root@ELK-3 ~]# ps aux |grep masterha_manager
8、最后我们需要到master节点上,手动去配置虚拟IP。因为MHA只会在主从切换时漂移虚拟IP到新的Master节点,而不会在第一次启动时主动去设置Master的虚拟IP,所以我们需要手动设置。设置虚拟IP的命令如下:
[root@ELK-1 ~]# ifconfig eth0:1 10.7.6.200 netmask 255.255.255.0 up
设置成功后,使用ip addr命令可以看到网卡上绑定的虚拟IP:
测试MHA服务
到此为止,我们就已经完成了MHA高可用架构的搭建,接下来我们对其进行一些简单的测试。例如,测试下是否能正常ping通虚拟IP,毕竟应用端访问数据库时连接的是虚拟IP,所以首先得确保虚拟IP是能够被访问的。如下:
能ping通之后,使用Navicat等远程连接工具测试下能否正常通过虚拟IP连接上数据库:
确定了虚拟IP能正常访问后,接着测试MHA是否能够正常进行主从切换,首先将master节点上的MySQL服务给停掉,模拟Master宕机:
正常情况下,此时master节点上的网卡就不会再绑定该虚拟IP:
而是会被MHA漂移到slave-01节点的网卡上,因为此时该Slave就是新的Master:
接着进入slave-02节点上的MySQL命令行终端,确认下该Slave是否已经正常与新的Master进行同步。之前我们配置slave-02的主库是master,现在将master停掉后,可以看到slave-02的Master_Host已经被MHA切换成了slave-01的IP:
经过以上测试后,可以看到我们搭建的MHA架构是能够正常运行的,已经使得Replication集群拥有了基本的高可用能力,即便Master下线后也能正常从Slave中选举新的Master并进行切换,也正确建立了其他Slave与新Master的复制链路。
解决数据库没有权限
mysql> grant all privileges on *.* to 'root'@'%';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
MHA架构优缺点
优点:
使用Perl脚本语言开发并且完全开源,开发者可以根据自己的需求进行二次开发
能够支持基于GTID和基于日志点的复制模式
MHA在进行故障转移时更不易产生数据丢失
在一个监控节点上可以监控多个Replication集群
缺点:
MHA默认不提供虚拟IP功能,需要自行编写脚本或利用第三方工具来实现虚拟IP的配置
MHA启动后只会对Master进行监控,不会对Slave进行监控,也无法监控复制链路的情况
集群环境需要能够通过ssh免密登录,存在一定的安全隐患
MHA没有提供对Slave的读负载均衡功能,需要通过第三方工具来实现
相关推荐
- 爬虫基础之自动化工具 DrissionPage 的使用
-
概述前三期文章中已经介绍到了Selenium与Playwright、Pyppeteer的使用方法,它们的功能都非常强大。而本期要讲的DrissionPage更为独特,强大,而且使用更为方...
- 你不得不知的云计算与虚拟化基础知识(下)
-
1.4KVM日常管理[root@linux-node1opt]#virshstartCentOS-7-x86_64#启动刚才创建的CentOS7KVM虚拟机DomainCentOS-7-x86...
- Linux 终端复用神器 Tmux 使用详解
-
Tmux是TerminalMultiplexer的简称,它是一款优秀的终端复用软件,类似GNUscreen,但比screen更出色。tmux来自于OpenBSD,采用BSD授权。使用它最直...
- Java快速开发框架若依(RuoYi)centos7.6部署
-
RuoYi是一个JavaEE企业级快速开发平台,基于经典技术组合(SpringBoot、SpringSecurity、MyBatis、Jwt、Vue),内置模块如:部门管理、角色用户、菜单...
- 推荐一款Linux的进程管理利器——Supervisor
-
一、supervisor简介项目中需要将一些自己开发的服务放到系统进程中在后台运行。一开始使用的是screen工具配合写了一个shell脚本,基本实现了启动、重启、停止操作,但是对于进程守护方面不是太...
- 读红蓝攻防:技术与策略34日志分析
-
1.日志分析1.1.要调查安全问题,通常需要查看来自不同供应商和不同设备的多种日志1.2.一旦了解了如何读取日志,在多个供应商产品的日志之间切换就会变得更容1.3.许多工具可以自动执行日志聚合...
- Dify存储告急别焦虑!6步迁移教程,系统无缝切换,流畅度暴涨!
-
小王最近愁坏了--用Dify搭建的公司知识库因频繁导入行业文档,旧服务器硬盘红灯频闪,每次跑模型训练都弹出"存储空间不足"报错,甚至有两次差点弄丢用户对话历史数据!而某初创...
- 解决CentOS 中显示乱码问题(centos编码)
-
解决CentOS中显示乱码问题vi/etc/sysconfig/i18nLANG="en_US.UTF-8"SUPPORTED="en_US.UTF-8:en_US:e...
- Tmux——超越screen的终端工具(tmux操作)
-
我们都知道,远程会话如果连接中断了,当前的进程任务也会中断,虽然说可以把任务放在后台,但显示不是很直观。以前linux系统常带的终端工具screen,我们今天介绍比screen更强大的工具...
- MySQL如何找到使用的是哪个配置文件?
-
一个正在运行的MySQL实例,如何查看对应的配置文件用的是哪一个?如果存在多个文件,生效的顺序是怎么样的?1.方法一首先可以先选择查看MySQL进程信息来判断使用了哪个配置文件,例如:ps-au...
- MySQL合集-基于MHA搭建高可用架构
-
MHA架构介绍MHA是MasterHighAvailability的缩写,它是目前MySQL高可用方面的一个相对成熟的解决方案,其核心是使用perl语言编写的一组脚本,是一套优秀的作为MySQL高...
- mysql8版本的卸载、安装、升级(mysql8卸载如何彻底删除)
-
mysql的卸载yumremovemysql-community-client-plugins-8.0.42-1.el7.x86_64yumremovemysql-community-comm...
- 如何用MySQL设计一个分布式锁?(mysql分布式数据库+分布式存储)
-
前言分布式锁想必大家都不陌生,可以用来解决在分布式环境下,多个用户在同一时间读取/更新相同的资源带来的问题。比如秒杀场景下的库存问题、rediskey失效情况下请求直接打到MySQL中造成MySQL...
- QT 5.12.11 编译MySQL 8 驱动教程- 1.01版
-
安装编译环境:qt5.12.11mysql8.0.28修改mysql.pro工程文件,编译生成动态库mysql.pro文件位置:D:\Alantop_Dir\alantop_sde\Qt\Qt5....
- MySQL中exists和in的区别(exists在sql中的用法)
-
在MySQL中,EXISTS和IN用于在查询中检查某个值是否存在于某个集合或表中。exists在MySQL中,EXISTS是一个布尔操作符,用于在SELECT查询中检查子查询是否返回任何行。如果子查询...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- linux 查询端口号 (58)
- docker映射容器目录到宿主机 (66)
- 杀端口 (60)
- yum更换阿里源 (62)
- internet explorer 增强的安全配置已启用 (65)
- linux自动挂载 (56)
- 禁用selinux (55)
- sysv-rc-conf (69)
- ubuntu防火墙状态查看 (64)
- windows server 2022激活密钥 (56)
- 无法与服务器建立安全连接是什么意思 (74)
- 443/80端口被占用怎么解决 (56)
- ping无法访问目标主机怎么解决 (58)
- fdatasync (59)
- 405 not allowed (56)
- 免备案虚拟主机zxhost (55)
- linux根据pid查看进程 (60)
- dhcp工具 (62)
- mysql 1045 (57)
- 宝塔远程工具 (56)
- ssh服务器拒绝了密码 请再试一次 (56)
- ubuntu卸载docker (56)
- linux查看nginx状态 (63)
- tomcat 乱码 (76)
- 2008r2激活序列号 (65)