搭建MySQL的高可用架构(MHA)

本文详细介绍MHA(Master High Availability)在MySQL高可用环境下的应用,包括故障切换、主从提升、半同步复制结合MHA确保数据一致性,以及如何在多节点环境中配置MHA实现自动故障转移和VIP漂移。

1.MHA简介

MHA(Master High Availability)是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件。在MySQL故障切换过程中,
MHA能做到在0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA能在最大程度上保证数据的一致性,以达到真正意义上的高可用。

MHA由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。
MHA Manager可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署在一台slave节点/master结点上。
MHA Node运行在每台MySQL服务器上,MHA Manager会定时探测集群中的master节点,当master出现故障时,它可以自动将最新数据的slave提升为新的master,
然后将所有其他的slave重新指向新的master。整个故障转移过程对应用程序完全透明。
在MHA自动故障切换过程中,MHA试图从宕机的主服务器上保存二进制日志,最大程度的保证数据的不丢失,但这并不总是可行的。
例如,如果主服务器硬件故障或无法通过ssh访问,MHA没法保存二进制日志,只进行故障转移而丢失了最新的数据。
使用MySQL 5.5的半同步复制,可以大大降低数据丢失的风险。MHA可以与半同步复制结合起来。
如果只有一个slave已经收到了最新的二进制日志,MHA可以将最新的二进制日志应用于其他所有的slave服务器上,因此可以保证所有节点的数据一致性。

2.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信息

3.Node工具包主要包括以下几个工具

save_binary_logs                #保存和复制master的二进制日志
apply_diff_relay_logs           #识别差异的中继日志事件并将其差异的事件应用于其他的slave
filter_mysqlbinlog              #去除不必要的ROLLBACK事件(MHA已不再使用这个工具)
purge_relay_logs                #清除中继日志(不会阻塞SQL线程)

这些工具通常由MHA Manager的脚本触发,无需人为操作

实验前提:

注意:主从复制的前提是,数据高度一致性,如果你之前已经做好了一主一从,再继续添从库时,会出现SQL线程连接失败,因为此时主库与新添加的从库数据不一致 ,为了避免此类问题,建议重新打开3个虚拟机做一主二从,保证实验环境的纯净

先做好一主二从的基于GTID的主从复制与半同步复制(基于GTID主从复制在复制过程中更加方便,而半同步复制有效的避免了数据的丢失)

1.配置一主二从

为了尽可能的减少主库硬件损坏宕机造成的数据丢失,因此在配置MHA的同时建议配置成MySQL 5.5的半同步复制

安装包:

mysql-5.7.24-1.el7.x86_64.rpm-bundle.tar

点击此处查看MySQL主从复制,半同步复制等具体步骤
(1).基于GTID的主从复制
配置master端:

#1.解压并安装数据库
[root@server1 ~]# ls
mysql-5.7.24-1.el7.x86_64.rpm-bundle.tar
[root@server1 ~]# tar -xf mysql-5.7.24-1.el7.x86_64.rpm-bundle.tar
[root@server1 ~]# ls

在这里插入图片描述

[root@sever1 ~]# yum install -y mysql-community-client-5.7.24-1.el7.x86_64.rpm mysql-community-common-5.7.24-1.el7.x86_64.rpm mysql-community-libs-5.7.24-1.el7.x86_64.rpm mysql-community-libs-compat-5.7.24-1.el7.x86_64.rpm mysql-community-server-5.7.24-1.el7.x86_64.rpm 
[root@sever1 ~]# scp mysql-community-client-5.7.24-1.el7.x86_64.rpm mysql-community-common-5.7.24-1.el7.x86_64.rpm mysql-community-libs-5.7.24-1.el7.x86_64.rpm mysql-community-libs-compat-5.7.24-1.el7.x86_64.rpm mysql-community-server-5.7.24-1.el7.x86_64.rpm root@172.25.66.2:
[root@sever1 ~]# scp mysql-community-client-5.7.24-1.el7.x86_64.rpm mysql-community-common-5.7.24-1.el7.x86_64.rpm mysql-community-libs-5.7.24-1.el7.x86_64.rpm mysql-community-libs-compat-5.7.24-1.el7.x86_64.rpm mysql-community-server-5.7.24-1.el7.x86_64.rpm root@172.25.66.3:
2.更改文件
[root@server1 mysql]# vim /etc/my.cnf
#####################
server-id=1
log-bin=mysql-bin

gtid_mode=ON
enforce_gtid_consistency=ON

log_slave_updates=ON

在这里插入图片描述

#3.开启数据库
[root@server1 mysql]# systemctl start mysqld
#4.查看初始密码
[root@server1 mysql]#  cat /var/log/mysqld.log | grep password
#5.初始化
[root@sever1 ~]#  mysql_secure_installation 
#6.登陆数据库并用户授权
[root@server1 ~]# mysql -u root -pWestos+001
#用户授权
mysql> grant replication slave on *.* to repl@'172.25.66.%' identified by 'Westos+001'; 
#刷新授权表
mysql> flush privileges;

配置slave端:(server2)
#1.安装数据库

[root@sever2 ~]# ls

在这里插入图片描述

[root@sever2 ~]# yum install -y *
#2.更改配置文件;仅server-id不同
[root@server2 mysql]# vim /etc/my.cnf
#####################
server-id=2
log-bin=mysql-bin

gtid_mode=ON
enforce_gtid_consistency=ON

log_slave_updates=ON

在这里插入图片描述

#3.开启数据库
[root@server2 mysql]# systemctl start mysqld
#4.查看初始密码
[root@server2 mysql]# cat /var/log/mysqld.log | grep password
#5.初始化
[root@sever2 ~]# mysql_secure_installation 
#6.复制主库
[root@server2~]# mysql -u root -p'Westos+001'
#GTID方式复制主库
mysql> change master to master_host='172.25.66.1',master_user='repl',master_password='Westos+001',MASTER_AUTO_POSITION = 1;
#开启slave
mysql> start slave;
#查看slave的状态
mysql> show slave status\G; 

在这里插入图片描述
配置slave端:(server3)
操作步骤完全同server2结点

#1.安装数据库
[root@sever3 ~]# ls
[root@sever3 ~]# yum install -y *
#2.更改配置文件;仅server-id不同
[root@server3 mysql]# vim /etc/my.cnf
#####################
server-id=3
log-bin=mysql-bin

gtid_mode=ON
enforce_gtid_consistency=ON

log_slave_updates=ON

在这里插入图片描述

#3.开启数据库
[root@server3 mysql]# systemctl start mysqld
#4.查看初始密码
[root@server3 mysql]# cat /var/log/mysqld.log | grep password
2019-02-26T06:37:39.817817Z 1 [Note] A temporary password is generated for root@localhost: lVyoaMAbj8(!
#5.初始化
[root@sever3 ~]# mysql_secure_installation 
#6.复制主库
[root@server3~]# mysql -u root -p'Westos+001'
#GTID方式复制主库
mysql> change master to master_host='172.25.66.1',master_user='repl',master_password='Westos+001',MASTER_AUTO_POSITION = 1;
#开启slave
mysql> start slave;
#查看slave的状态
mysql> show slave status\G; 

在这里插入图片描述
(2).半同步复制
查看链接配置半同步复制

2.配置MHA高可用

注意:

server1和server2和server3结点上都有解析(/etc/hosts)

在这里插入图片描述
配置管理机:

为了节省结点,我们将server1设定为既是master又是管理机

1.安装软件

在主库安装MHA Manage:(perl是依赖包)

[root@server1 ~]# ls

在这里插入图片描述

[root@server1 ~]# yum install -y *
[root@server1 ~]# scp mha4mysql-node-0.58-0.el7.centos.noarch.rpm server2:
[root@server1 ~]# scp mha4mysql-node-0.58-0.el7.centos.noarch.rpm server3:

在从库安装MHA Node:

[root@server2 ~]# ls
mha4mysql-node-0.58-0.el7.centos.noarch.rpm
[root@server2 ~]# yum install -y *
[root@server3 ~]# ls
mha4mysql-node-0.58-0.el7.centos.noarch.rpm
[root@server3 ~]# yum install -y *

2.设定ssh免密

(1)管理机可以免密连接其他结点

[root@server1 ~]# ssh-keygen

在这里插入图片描述

[root@server1 ~]# ssh-copy-id server1

在这里插入图片描述

[root@server1 ~]# ssh-copy-id server2

在这里插入图片描述

[root@server1 ~]# ssh-copy-id server3

在这里插入图片描述
测试

[root@server1 ~]# ssh server1
Last login: Tue Feb 26 12:57:24 2019 from foundation66.localdomain
[root@server1 ~]# exit
logout
Connection to server1 closed.
[root@server1 ~]# ssh server2
Last login: Tue Feb 26 13:08:35 2019 from foundation66.localdomain
[root@server2 ~]# exit
logout
Connection to server2 closed.
[root@server1 ~]# ssh server3
Last login: Tue Feb 26 14:23:17 2019 from foundation66.localdomain
[root@sever3 ~]# exit
logout
Connection to server3 closed.

在这里插入图片描述
(2)主从结点之间相互免密
只需将在管理机端生成的公钥和私钥发送给其他结点即可

[root@server1 ~]# cd .ssh/
[root@server1 .ssh]# ls
authorized_keys  id_rsa  id_rsa.pub  known_hosts
[root@server1 .ssh]# cd
#将.ssh/整个目录发送到其他结点
[root@server1 ~]# scp -r .ssh/ server2:
[root@server1 ~]# scp -r .ssh/ server3:

测试:

server结点就不用再测试了,因为它既是master又是管理结点,管理结点刚已经测试过了

server2可以免密连接其他结点:

[root@server2 ~]# cd .ssh/
[root@server2 .ssh]# ls
authorized_keys  id_rsa  id_rsa.pub  known_hosts
[root@server2 .ssh]# ssh server1
Last login: Tue Feb 26 15:58:03 2019 from server2
[root@server1 ~]# exit
logout
Connection to server1 closed.
[root@server2 .ssh]# ssh server3
Last login: Tue Feb 26 15:58:11 2019 from sever2
[root@sever3 ~]# exit
logout
Connection to server3 closed.

在这里插入图片描述
server3可以免密连接其他结点:

[root@sever3 ~]# cd .ssh/
[root@sever3 .ssh]# ls
authorized_keys  id_rsa  id_rsa.pub  known_hosts
[root@sever3 .ssh]# ssh server1
Last login: Tue Feb 26 15:58:26 2019 from server2
[root@server1 ~]# exit
logout
Connection to server1 closed.
[root@sever3 .ssh]# ssh server2
Last login: Tue Feb 26 15:58:06 2019 from server2
[root@server2 ~]# exit
logout
Connection to server2 closed.

在这里插入图片描述
3.编写配置文件

[root@server1 ~]# mkdir /etc/masterha
[root@server1 ~]# cd /etc/masterha/
[root@server1 masterha]# vim app1.conf
########################
[server default]          #默认设置
manager_workdir=/etc/masterha        #指定manager工作目录
manager_log=/var/log/masterha.log    #指定manager日志存放路径
master_binlog_dir=/etc/masterha      #指定mysql的数据目录

user=root                            #设定管理员用户
password=Westos+001             #设置管理员密码
ping_interval=1                      #设置监控频率,默认是3秒,尝试三次没有回应的时候自动进行railover
remote_workdir=/tmp                  #设置远端mysql在发生切换时,binlog(二进制日志)的保存位置
repl_user=repl                       #设置复制环境中的复制用户名
repl_password=Westos+001        #设置复制用户的密码
ssh_user=root                        #设置免密用户

[server1]                 #master
hostname=172.25.66.1
port=3306

[server2]                 #salve
hostname=172.25.66.2
port=3306
candidate_master=1   #设置为候选master
check_repl_delay=0   #忽略复制延

[server3]                 #salve
hostname=172.25.66.3
port=3306
no_master=1   #不竞选master

3.测试
1.检测ssh免密

[root@server1 masterha]# masterha_check_ssh --conf=/etc/masterha/app1.conf

在这里插入图片描述
排错:若出现如下报错,一定是主从结点的免密没有做好
在这里插入图片描述
在这里插入图片描述
2.检测复制过程

报错:不允许root用户远程登陆

[root@server1 masterha]# masterha_check_repl --conf=/etc/masterha/app1.conf

解决方案:在master端,给root用户添加权限即可

[root@server1 masterha]# mysql -u root -p'Westos+001'
#给root用户授权
mysql> grant all on *.* to root@'%' identified by 'Westos+001';
[root@server1 masterha]# masterha_check_repl --conf=/etc/masterha/app1.conf

根据提示,设定slave端只读:

[root@server2 ~]# mysql -u root -p'Westos+001'
mysql> set global read_only=1;
[root@server3 ~]# mysql -u root -p'Westos+001'
mysql> set global read_only=1

3.检测故障切换

1.手动切换

(1).故障切换

模拟主库master宕机:

#关闭数据库
[root@server1 ~]# systemctl stop mysqld

手动切换:

#由于server1(主库)已经宕机,此时将手动master切换到server2结点上
[root@server1 ~]# masterha_master_switch --master_state=dead --conf=/etc/masterha/app1.conf --dead_master_host=172.25.66.1 --dead_master_ip=172.25.66.1 --dead_master_prot=3306 --new_master_host=172.25.66.2 --new_master_port=3306 

测试:发现当server1(主库)宕机后,server2结点接管master,server3结点依旧是slave

[root@server2 ~]# mysql -u root -p'Westos+001'
#查看slave信息为空,因为此时server2已经切换为master
mysql> show slave status\G;
mysql> show master status;

在这里插入图片描述

[root@sever3 ~]# mysql -u root -p'Westos+001'
mysql> show slave status\G;

在这里插入图片描述
开启server1的数据库,手动将其添加到slave中

[root@server1 ~]# systemctl start mysqld
[root@server1 ~]# mysql -u root -p'Westos+001'
#MASTER_HOST为master主库的ip
mysql> CHANGE MASTER TO MASTER_HOST='172.25.66.2', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='Westos+001';
#开启slave
mysql> start slave;
mysql> show slave status\G;

在这里插入图片描述
(2)热切换

热切换:在主库没有宕机的情况下,手动切换 master
#删除app1.failover.complete文件

[root@server1 ~]# cd /etc/masterha/
[root@server1 masterha]# ls
app1.conf  app1.failover.complete
[root@server1 masterha]# cat app1.failover.complete 
[root@server1 masterha]# rm -rf app1.failover.complete 
[root@server1 masterha]# ls
app1.conf

在主库活跃的情况下,手动将master切回到server1结点上

[root@server1 masterha]# masterha_master_switch --master_state=alive --conf=/etc/masterha/app1.conf --new_master_host=172.25.66.1 --new_master_port=3306 --orig_master_is_new_slave --running_updates_limit=10000

测试:

发现的确实现了在主库活跃的情况下,将master回切到server1结点上

[root@server1 ~]# mysql -u root -p'Westos+001'
mysql> show master status;

在这里插入图片描述

[root@sever2 ~]# mysql -u root -p'Westos+001'
mysql> show slave status\G;

在这里插入图片描述

[root@sever3 ~]# mysql -u root -p'Westos+001'
mysql> show master status;

在这里插入图片描述
2.自动切换

设定自动切换:

[root@server1 ~]# cd /etc/masterha/ 
#自动切换
[root@server1 masterha]# nohup masterha_manager --conf=/etc/masterha/app1.conf &> /dev/null &
[1] 6286
[root@server1 masterha]# ps a

在这里插入图片描述
测试:

当主库宕机后,master自动切换到server2结点上

[root@server1 masterha]# systemctl stop mysqld
[1]+  Done                    nohup masterha_manager --conf=/etc/masterha/app1.conf &>/dev/null
[root@server2 ~]# mysql -u root -p'Westos+001'
mysql> show master status;

在这里插入图片描述

[root@sever3 ~]# mysql -u root -p'Westos+001'
mysql> show slave status\G

在这里插入图片描述

[root@server1 masterha]# pwd
/etc/masterha
[root@server1 masterha]# ls
app1.conf  app1.failover.complete
[root@server1 masterha]# rm -rf app1.failover.complete 

开启server1的数据库,手动添加到slave中(此过程没办法自动完成)

[root@server1 ~]# systemctl start mysqld
[root@server1 ~]# mysql -u root -p'Westos+001'
mysql> CHANGE MASTER TO MASTER_HOST='172.25.66.2', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='Westos+001';
#开启slave
mysql> start slave;
mysql> show slave status\G;

在这里插入图片描述

4.脚本实现vip的漂移

1.下载脚本

[kiosk@foundation66 Desktop]$ scp master_ip_failover master_ip_online_change  root@172.25.66.1:/usr/local/bin/
[root@server1 ~]# cd /usr/local/bin/
[root@server1 bin]# ls
master_ip_failover  master_ip_online_change

2.更改脚本

#此脚本用于实现手动切换vip
[root@server1 bin]# vim master_ip_online_change 
###################
my $vip = '172.25.66.100/24';      #设定vip
my $ssh_start_vip = "/sbin/ip addr add $vip dev eth0";   #添加vip
my $ssh_stop_vip = "/sbin/ip addr del $vip dev eth0";    #删除vip

在这里插入图片描述

#此脚本用于实现自动切换vip
[root@server1 bin]# vim master_ip_failover 
###################
my $vip = '172.25.66.100/24';      #设定vip
my $ssh_start_vip = "/sbin/ip addr add $vip dev eth0";   #添加vip
my $ssh_stop_vip = "/sbin/ip addr del $vip dev eth0";    #删除vip
my $exit_code = 0;

在这里插入图片描述
3.给脚本一个可执行权限

[root@server1 bin]# ll
total 8
-rw-r--r-- 1 root root 2179 Feb 26 21:14 master_ip_failover
-rw-r--r-- 1 root root 3796 Feb 26 21:13 master_ip_online_change
[root@server1 bin]# chmod +x *
[root@server1 bin]# ll
total 8
-rwxr-xr-x 1 root root 2179 Feb 26 21:14 master_ip_failover
-rwxr-xr-x 1 root root 3796 Feb 26 21:13 master_ip_online_change

4.更改配置文件

[root@server1 bin]# cd /etc/masterha/
[root@server1 masterha]# ls
app1.conf
[root@server1 masterha]# vim app1.conf 
########################
master_ip_failover_script=/usr/local/bin/master_ip_failover              #设置自动failover时候的切换脚本
master_ip_online_change_script=/usr/local/bin/master_ip_online_change    #设置手动切换时候的切换脚本

在这里插入图片描述
5.给master端添加vip

[root@server2 ~]# ip addr 

在这里插入图片描述

#添加vip
[root@server2 ~]# ip addr add 172.25.66.100/24 dev eth0
[root@server2 ~]# ip addr 

在这里插入图片描述
6.测试

(1)手动热切换

手动切换:

#将master手动切换到server1上(热切换)
[root@server1 masterha]# masterha_master_switch --master_state=alive --conf=/etc/masterha/app1.conf --new_master_host=172.25.66.1 --new_master_port=3306 --orig_master_is_new_slave --running_updates_limit=10000

检测:

发现vip漂移到server1结点上,因为此时server1切换为了master

[root@server1 masterha]# ip addr

在这里插入图片描述

[root@server2 ~]# ip addr
[root@server1 ~]# mysql -u root -p'Westos+001'
mysql> show master status;

在这里插入图片描述

[root@server2 ~]# mysql -u root -p'Westos+001'
mysql> show slave status\G;

在这里插入图片描述

[root@server3 ~]# mysql -u root -p'Westos+001'
mysql> show slave status\G;

在这里插入图片描述
(2)自动切换

设定自动切换

[root@server1 ~]# nohup masterha_manager --conf=/etc/masterha/app1.conf &> /dev/null &
[1] 2220

检测:

发现当主库(server1)宕机后,server2自动接管master,此时vip漂移到server2结点上。也即是说,vip会随着master的切换而漂移,谁接管master,vip便会漂向谁

[root@server1 ~]# systemctl stop mysqld
[1]+  Done                    nohup masterha_manager --conf=/etc/masterha/app1.conf &>/dev/null
[root@server2 ~]# ip addr

在这里插入图片描述

[root@server1 ~]# ip addr

在这里插入图片描述

[root@server2 ~]# mysql -u root -p'Westos+001'
mysql> show master status;

在这里插入图片描述

[root@server3 ~]# mysql -u root -p'Westos+001'
mysql> show slave status\G;

开启server1的数据库,手动将其添加到slave中

[root@server1 ~]# systemctl start mysqld
[root@server1 ~]# mysql -u root -p'Westos+001'
mysql> CHANGE MASTER TO MASTER_HOST='172.25.66.2', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='Westos+001';
mysql> start slave;
mysql> show slave status\G;

排错:

当开启slave时,报错

#启动slave时,使用repository中信息初始化relay log结构失败了
mysql> start slave;
ERROR 1872 (HY000): Slave failed to initialize relay log info structure from the repository
解决方案:先重置slave,再重新启动机即可
mysql> reset slave;
Query OK, 0 rows affected (0.25 sec)

mysql> start slave;
Query OK, 0 rows affected (0.14 sec)

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值