一、本文目标

要搭建一个MySQL高可用的集群架构(4台主机,1主,2从,1台MHA)。
实现目标:
1、实现1主2从的同步复制功能(采取半同步复制机制)。
2、采用MHA实现主库出现故障,从库能自动切换成主库。

二、开发环境简介

虚拟机:VMware Workstation 15.0
系统:Linux CentOS 7.0
数据库:MySQL 5.7.28
远程连接:XShell
文件传输:XFtp

三、环境架构介绍

机器名称 IP 角色 权限
vm1(master) 192.168.199.3 Master 主库,可读写
vm2(slave1) 192.168.199.4 Slave 从库,只读
vm3(slave2) 192.168.199.5 Slave 从库,只读
vm4(mha) 192.168.199.6 MHA Manager 高可用监控

四、MySQL主从搭建

4.1环境搭建

做4台虚拟机,可以先做一台,然后克隆得到剩下三台,因为克隆得到的机器配置是一样的,所以需要修改剩下三台机器的配置。
1.修改ifcfg-ens33配置文件
vi /etc/sysconfig/network-scripts/ifcfg-ens33

加入以下配置:

image.png
IPADDR=192.168.199.5(此处IP每台机器保持不同即可)
NETMASK=255.255.255.0
GATEWAY=192.168.199.2
BOOTPROTO=static
DNS1=114.114.114.114
2.重启网卡
service network restart
ping www.baidu.com 测试连通性
image.png

4.2MySQL安装

1.下载MySQL 5.7.28
地址:https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.28-1.el7.x86_64.rpm-bundle.tar
我是在windows电脑下载完成后上传linux到虚拟机服务器上
2.解压
tar -xvf mysql-5.7.28-1.el7.x86_64.rpm-bundle.tar
可以得到以下安装包:
image.png
3.要移除CentOS自带的mariadb-libs,不然会提示冲突
rpm -qa|grep mariadb(检查当前环境有没有安装mariadb)
rpm -e mariadb-libs-5.5.41-2.el7_0.x86_64 —nodeps(移除mariadb)
4.依次安装common,libs,libs-compat,client,server,devel(注意顺序别错)
rpm -ivh mysql-community-common-5.7.28-1.el7.x86_64.rpm
rpm -ivh mysql-community-libs-5.7.28-1.el7.x86_64.rpm
rpm -ivh mysql-community-libs-compat-5.7.28-1.el7.x86_64.rpm
rpm -ivh mysql-community-client-5.7.28-1.el7.x86_64.rpm
rpm -ivh mysql-community-server-5.7.28-1.el7.x86_64.rpm
rpm -ivh mysql-community-devel-5.7.28-1.el7.x86_64.rp
5.初始化MySQL
mysqld —initialize —user=mysql
6.查看初始化密码
cat /var/log/mysqld.log | grep password
7.启动MySQL服务
systemctl start mysqld
8.配置为开机自动启动
systemctl enable mysqld
9.登录MySQL,修改默认密码
mysql -uroot -p
xxxxxx输入初始密码
mysql> SET PASSWORD = PASSWORD(‘root’);
Query OK, 0 rows affected, 1 warning (0.00 sec)
10.依次克隆两台从服务器,按照以上规则配置从服务器,具体区别下面做更改

4.2关闭防火墙

四台机器要互相访问,需要关闭防火墙,否则就要在/etc/sysconfig/iptables中增加规则,本文只是为了搭建简单的MySQL集群环境 ,故防火墙不在考虑范围内
systemctl stop iptables(如果没有iptables就不用执行)
systemctl stop firewalld (关闭防火墙)
systemctl disable firewalld.service(彻底关闭防火墙,这样就不用每次重启服务器都重新关闭一次了)

4.3MySQL主从配置

4.3.1 Master配置

1.使用vi /etc/my.cnf命令修改Master配置文件

  1. #bin_log配置
  2. #增加bin_log,这条配置等同于log-bin=ON和log-bin-basename=mysql-bin的集合
  3. log_bin=mysql-bin
  4. #配置server-id,要求主从不同
  5. server-id=1
  6. #配置代表着每次提交事务,都会刷新到bin_log
  7. sync-binlog=1
  8. #排除哪些库不同步
  9. binlog-ignore-db=performance_schema
  10. binlog-ignore-db=information_schema
  11. binlog-ignore-db=sys
  12. #只同步哪些库同步,这里不做特殊配置
  13. #binlog-do-db=lagou

2.重启服务
systemctl restart mysqld
3.主库给从库授权
登录MySQL,执行如下命令:
授权主从同步权限给root用户
mysql> grant replication slave on . to root@’%’ identified by ‘密码’; (.代表所有库下的所有表)
授权所有权限给root用户(包括增删改查等)
mysql> grant all privileges on . to root@’%’ identified by ‘密码’;(授权)
刷新权限
mysql> flush privileges;
//查看主库状态信息
mysql> show master status;
image.png
能看到bin_log的名字,偏移点等信息(代表从Position这个点开始主从复制)

4.3.2 Slave配置

1.修改从库的配置文件
vi /etc/my.cnf

  1. # log_bin
  2. #服务器ID,每个服务器要求不一样
  3. server-id=2
  4. #中继日志名称
  5. relay_log=mysql-relay-bin
  6. #配置从库是只读
  7. read_only=1

2.重启服务
systemctl restart mysqld
3.开启同步
在从库的mysql内执行同步操作,注意下面的参数与上面主库的show master status得到的信息保持一致
mysql> change master to master_host=’192.168.199.3’,master_port=3306,master_user=’root’,master_password=’root’,master_log_file=’mysql-bin.000002’,master_log_pos=154;

mysql> start slave;
4.测试
主库添加一条记录
image.png
查询主库:
image.png
查询从库:
image.png

4.4配置半同步复制

4.4.1 Master配置

1.登录MySQL,执行如下命令安装semi插件
mysql> install plugin rpl_semi_sync_master soname ‘semisync_master.so’;
查看semi插件状态
mysql> show variables like ‘%semi%’;
image.png
这里我们要把rpl_semi_sync_master_enabled和rpl_semi_sync_master_timeout这两个参数改为ON和1秒,有两种方案一种是通过set命令,一种是在my.cnf里修改。(第一种是临时修改,重启MySQL失效,第二种是永久性修改),这里我们选择在my.cnf里修改

  1. # 自动开启半同步复制
  2. rpl_semi_sync_master_enabled=ON
  3. rpl_semi_sync_master_timeout=1000

4.4.2 Slave配置

1.登录MySQL,执行如下命令安装semi插件
install plugin rpl_semi_sync_slave soname ‘semisync_slave.so’;
2.修改my.cnf文件修改semi状态

  1. # 自动开启半同步复制
  2. rpl_semi_sync_slave_enabled=ON

3.重启服务
systemctl restart mysqld
4.查看semi状态
image.png
5.查看**主库**日志,确认semi是否已经启用
cat /var/log/mysqld.log
image.png
发现semi已经启用,证明semi启用了

4.5并行复制

4.5.1 Master配置

1.进入mysql,查看主库并行复制参数
mysql> show variables like ‘%bin_log_group%’
image.png
其中第一个代表同步延迟,第二个代表每次同步的事务数,我们要把这两个参数都设置为1000和100
修改my.cnf文件

  1. binlog_group_commit_sync_delay=1000
  2. binlog_group_commit_sync_no_delay_count=100

image.png

4.5.2 Slave配置

设置从库配置文件
vi etc/my.cnf

  1. #基于组提交的并行复制方式
  2. slave-parallel-type=LOGICAL_CLOCK
  3. #并行线程数
  4. slave-parallel-workers=8
  5. #开启MTS功能后,务必将参数master_info_repostitory设置为TABLE,这样性能可以有50%~80%的提升
  6. master_info_repository=TABLE
  7. #创建mysql.slave_relay_info表来记录同步的位置信
  8. relay_log_info_repository=TABLE
  9. #在数据库启动后立即启动自动relay_log恢复
  10. relay_log_recovery=1

4.5.3验证

1.主库插入一条记录
image.png
2.从库已经有了
image.png
3.查看主库perfoemance_schema库的replication_applier_status_by_worker表,发现已经出现了并行复制的内容
image.png

五、MHA高可用搭建

5.1四台机器SSH互通

1.在四台服务器上分别执行下面命令,生成公钥和私钥(注意:连续按换行回车采用默认值)
ssh-keygen -t rsa
image.png
2.在三台MySQL服务器分别执行下面命令,密码输入系统密码,将公钥拷到MHA Manager服务器上
ssh-copy-id 192.168.199.6(这个IP为MHA Manager服务器的IP)
image.png
3.在MHA Manager服务器上检查下,看看.ssh/authorized_keys文件是否包含3个公钥
cat /root/.ssh/authorized_keys
image.png
4.执行下面命令,将MHA Manager的公钥添加到authorized_keys文件中(此时应该包含4个公钥)
cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys
image.png
5.从MHA Manager服务器执行下面命令,向其他三台MySQL服务器分发公钥信息
scp /root/.ssh/authorized_keys root@192.168.199.3:/root/.ssh/authorized_keys
scp /root/.ssh/authorized_keys root@192.168.199.4:/root/.ssh/authorized_keys
scp /root/.ssh/authorized_keys root@192.168.199.5:/root/.ssh/authorized_keys
image.png
6.在MHA Manager执行下面命令,检测下与三台MySQL是否实现ssh互通
ssh 192.168.199.3
exit
ssh 192.168.199.4
exit
ssh 192.168.199.5
exit

5.2MHA下载安装

5.2.1MHA下载

MySQL5.7对应的MHA版本是0.5.8,所以在GitHub上找到对应的rpm包进行下载,MHA manager和node的安装包需要分别下载 :
https://github.com/yoshinorim/mha4mysql-manager/releases/tag/v0.58
下载image.png
https://github.com/yoshinorim/mha4mysql-node/releases/tag/v0.58
下载image.png
下载完成后将Manager和Node的安装包分别上传到对应的服务器(可通过Xftp等工具)
注意:三台MySQL服务器需要安装node
MHA Manager服务器需要安装manager和node

提示:也可以使用wget命令在linux系统直接下载获取,例如 :
wget https://github.com/yoshinorim/mha4mysqlmanager/releases/download/v0.58/mha4mysql-manager-0.58-0.el7.centos.noarch.rpm

5.2.2MHA Node安装

在四台服务器上安装mha4mysql-node。MHA的Node依赖于perl-DBD-MySQL,所以要先安装perl-DBD-MySQL
yum install perl-DBD-MySQL -y
wget https://github.com/yoshinorim/mha4mysql-node/releases/download/v0.58/mha4mysql-node-0.58-0.el7.centos.noarch.rpm
rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm

5.2.3MHA Manager安装

在MHA Manager服务器安装mha4mysql-node和mha4mysql-manager。
MHA的manager又依赖了perl-Config-Tiny、perl-Log-Dispatch、perl-Parallel-ForkManager,也分别
进行安装。

wget http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
rpm -ivh epel-release-latest-7.noarch.rpm
yum install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager -y

wget https://github.com/yoshinorim/mha4mysql-node/releases/download/v0.58/mha4mysql-node-0.58-0.el7.centos.noarch.rpm
rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm

wget https://github.com/yoshinorim/mha4mysql-manager/releases/download/v0.58/mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm

提示:由于perl-Log-Dispatch和perl-Parallel-ForkManager这两个被依赖包在yum仓库找不到,因此安装epel-release-latest-7.noarch.rpm。在使用时,可能会出现下面异常:Cannot retrieve metalink for repository: epel/x86_64。可以尝试使用/etc/yum.repos.d/epel.repo,然后注释掉metalink,取消注释baseurl。

5.3MHA配置文件

MHA Manager服务器需要为每个监控的 Master/Slave 集群提供一个专用的配置文件,而所有的Master/Slave 集群也可共享全局配置。

5.3.1新建初始化配置目录

  1. #目录说明
  2. #/var/log (CentOS目录)
  3. # /mha (MHA监控根目录)
  4. # /app1 (MHA监控实例根目录)
  5. # /manager.log (MHA监控实例日志文件)
  6. mkdir -p /var/log/mha/app1
  7. touch /var/log/mha/app1/manager.log

5.3.2配置监控全局配置文件

vim /etc/masterha_default.cnf

  1. [server default]
  2. #主库用户名,在master mysql的主库执行下列命令建一个新用户
  3. #create user 'mha'@'%' identified by '123123';
  4. #grant all on *.* to mha@'%' identified by '123123';
  5. #flush privileges;
  6. user=mha
  7. password=123123
  8. port=3306
  9. #ssh登录账号
  10. ssh_user=root
  11. #从库复制账号和密码
  12. repl_user=root
  13. repl_password=root
  14. port=3306
  15. #ping次数
  16. ping_interval=1
  17. #二次检查的主机
  18. secondary_check_script=masterha_secondary_check -s 192.168.199.3 -s 192.168.199.4 -s 192.168.199.5

5.3.3配置监控实例配置文件

先使用 mkdir -p /etc/mha 命令创建目录,然后使用 vim /etc/mha/app1.cnf 命令编辑文件

  1. [server default]
  2. #MHA监控实例根目录
  3. manager_workdir=/var/log/mha/app1
  4. #MHA监控实例日志文件
  5. manager_log=/var/log/mha/app1/manager.log
  6. #[serverx] 服务器编号
  7. #hostname 主机名
  8. #candidate_master 可以做主库
  9. #master_binlog_dir binlog日志文件目录
  10. [server1]
  11. hostname=192.168.199.3
  12. candidate_master=1
  13. master_binlog_dir="/var/lib/mysql"
  14. [server2]
  15. hostname=192.168.199.4
  16. candidate_master=1
  17. master_binlog_dir="/var/lib/mysql"
  18. [server3]
  19. hostname=192.168.199.5
  20. candidate_master=1
  21. master_binlog_dir="/var/lib/mysql"

5.4 MHA 配置检测

执行ssh通信检测,在MHA Manager服务器上执行:
masterha_check_ssh —conf=/etc/mha/app1.cnf
image.png

5.5 检测MySQL主从复制

在MHA Manager服务器上执行:
masterha_check_repl —conf=/etc/mha/app1.cnf
出现“MySQL Replication Health is OK.”证明MySQL复制集群没有问题。
image.png

5.6 MHA Manager启动

在MHA Manager服务器上执行
nohup masterha_manager —conf=/etc/mha/app1.cnf —remove_dead_master_conf —ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &
image.png
查看监控状态命令如下:
masterha_check_status —conf=/etc/mha/app1.cnf

查看监控日志命令如下:
tail -f /var/log/mha/app1/manager.log

5.7 测试MHA故障转移

5.7.1模拟主节点崩溃

在MHA Manager服务器执行打开日志命令 :
tail -200f /var/log/mha/app1/manager.log

关闭Master MySQL服务器服务,模拟主节点崩溃
systemctl stop mysqld

查看MHA日志,可以看到哪台slave切换成了master
show master status;

image.png

5.7.2将原主启动切换回主

1.启动MySQL服务
systemctl start mysqld

2.挂到新主做从库
mysql> change master to master_host=’192.168.199.4’,master_port=3306,master_user=’root’,master_password
=’root’,master_log_file=’mysql-bin.000001’,master_log_pos=1092;
mysql> start slave; // 开启同步

提示:master_log_file和master_log_pos两个参数需要去新主库查看,show master status \G;

3.使用MHA在线切换命令将原主切换回来
//必须先停止mha进程
masterha_stop —conf=/etc/mha/app1.cnf
//执行在线切换主从命令

  1. masterha_master_switch --conf=/etc/mha/app1.cnf --master_state=alive --new_master_host=192.168.199.3 --new_master_port=3306 --orig_master_is_new_slave
  2. --running_updates_limit=10000

六、记坑

1.如果发现主库添加记录,从库复制不过来,先查看从库日志

cat /var/log/mysqld.log
image.png
同时结合从库命令:
mysql> show slave status\G
发现:
image.png
Slave_IO_Running为No

分析得到可能是由于两台从服务器的uuid一致,这时我们需要查看并且修改一台从服务器的uuid
执行命令:
vi /var/lib/mysql/auto.cnf
修改其中的一个uuid,然后重启mysql即可

2.如果上面步骤5.5出现 None of slaves can be master. Check failover configuration file or log-bin settings in my.cnf报错

image.png
那么可能是主库或从库(主库一般都配置了)没有配置bin-log,在从库my.cnf上配置
log_bin=mysql-bin
binlog-ignore-db=performance_schema
binlog-ignore-db=information_schema
binlog-ignore-db=sys 即可