之前搭建过MySQL5.7版本的MHA集群,因为一些需要,现进行MySQL8.0版本的MHA集群搭建,搭建步骤基本与5.7版本相似,所以某些测试部分、问题解决、安装包、mha的IP漂移配置文件可以参照我之前写的博文,但是有部分配置文件做了改动,且8.0版本的某些命令与5.7版本的也不尽相同,需要注意。
基于MySQL5.7安装部署MHA集群(一主一从)可查看MySQL高可用集群搭建(一主一从)-CSDN博客https://blog.csdn.net/qq_50948831/article/details/137970683?spm=1001.2014.3001.5501
操作系统:centos7.6
MySQL: mysql-8.0.30-el7-x86_64.tar.gz
node: mha4mysql-node-0.58-0.el7.centos.noarch.rpm
manager:mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
IP地址 |
主从同步角色 |
集群角色 |
主机名 |
11.146.121.21 |
管理主机 |
mha |
|
11.146.121.22 |
主库 |
当前主库 |
master |
11.146.121.23 |
从库 |
备用主库 |
slave1 |
11.146.121.24 |
从库 |
备用主库 |
slave2 |
11.146.121.25 |
虚拟IP |
VIP地址 |
vi /etc/hosts
#进入文件
11.146.121.21 mha
11.146.121.22 master
11.146.121.23 slave1
11.146.121.24 slave2
hostnamectl set-hostname mha
su
hostnamectl set-hostname master
su
hostnamectl set-hostname slave1
su
hostnamectl set-hostname slave2
su
systemctl stop firewalld #停止firewall
systemctl disable firewalld #禁止firewall开机启动
下面的部分是需要在总体部署完毕后开启防火墙,确保集群的安全
systemctl start firewalld #开启firewall
systemctl enable firewalld #开启firewall开机启动
安全增强型 Linux(Security-Enhanced Linux)简称 SELinux,它是一个 Linux 内核模块,也是 Linux 的一个安全子系统。
setenforce 0
sed -i 's/SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
linux资源限制配置文件是/etc/security/limits.conf;限制用户进程的数量对于Linux系统的稳定性非常重要。 limits.conf文件限制着用户可以使用的最大文件数,最大线程,最大内存等资源使用量。(之前我都没设置过,本次是在查一些资料时候发现的,就设置了一下,但是没什么感觉)
vi /etc/security/limits.conf
#进入文件
mysql soft nproc 65535
mysql hard nproc 65535
mysql soft nofile 65535
mysql hard nofile 65535
本次使用xftp连接到Linux服务器,将需要配置免密登录的服务器同时打开,以便同时发送命令。
(1)编辑每台服务器上的hosts文件:vi /etc/hosts,映射文件已经设置过,此处不再赘述。
(2)进入rsa公钥私钥的存放目录
cd /root/.ssh/
#如果是新装的服务器,需要自己先手动创建该目录:mkdir -p /root/.ssh/
(3)删除目录下的id_rsa,id_rsa.pub文件
rm -rf id_rsa
rm -rf id_rsa.pub
#删除前确认是否有被其他服务器使用
(4)在每台服务器上都生成新的公钥私钥文件,输入命令后需要连续输入三次回车
ssh-keygen -t rsa
(5)拷贝id_rsa.pub文件内容到authorized_keys文件中
cat id_rsa.pub >> authorized_keys
#新服务器需要自己手动创建authorized_keys:touch authorized_keys
每台服务器公钥私钥生产完成后,就需要将各自的密钥拷贝到其他服务器上,以11.146.121.21主机为例子:
(1)登录11.146.212.41服务器,进入公钥私钥存放的路径
cd /root/.ssh/
(2)拷贝其他公钥文件(id_rsa.pub)内容至其他服务器上:
#mha
ssh-copy-id -i master
ssh-copy-id -i slave1
ssh-copy-id -i slave2
#master
ssh-copy-id -i mha
ssh-copy-id -i slave1
ssh-copy-id -i slave2
#slave1
ssh-copy-id -i mha
ssh-copy-id -i master
ssh-copy-id -i slave2
#slave2
ssh-copy-id -i mha
ssh-copy-id -i master
ssh-copy-id -i slave1
此时要注意!配置免密的时候,大概率是需要互相通信主机的主机密码,这个主机密码我认为是xftp连接主机时候的密码(公司服务器需要找网络人员要主机密码),注意不是MySQL或者堡垒机的密码。
(3)同理在其他几台服务器上也进行相同的操作,将本机的公钥拷贝至其他服务器上的authorized_keys文件中。
(4)授权authorized_keys文件。
chmod 600 /root/.ssh/authorized_keys #此时已经完成集群内免密的设置。
MySQL需要对某些文件拥有权限,才能自行建库,存放文件等的,所以要给其一个用户,并设置权限,深入的问题可以上网自行搜索
(我们创建用户的时候会默认创建一个和用户名相同的用户组,但是有时有需求需要指定用户组,可以使用-g命令来完成用户创建,前提条件是指定的用户组已存在 示例:useradd -g mygroup myuser)
useradd mysql #相当于默认创建了和用户mysql名字一样的用户组
mysql passwd mysql #密码自行配置,这里用的密码是*****
这个安装目录可以自己设置,但是要记住,后续的文件配置需要这个目录
mkdir -p /data/{log,data,tmp,binlog,relaylog}
mariadb 是Linux 系统自带的数据库,可能会与MySQL 数据库的某些配置起冲突,所以需要先将其卸载。
rpm -e 卸载已安装的rpm包
rpm -e --nodeps 不管依赖,强行卸载
rpm -qa|grep mariadb #查看mariadb版本
rpm -e mariadb-libs-5.5.60-1.el7_5.x86_64 --nodeps
tar -xzvf /root/mysql-8.0.30-el7-x86_64.tar.gz -C /
mv /mysql-8.0.30-el7-x86_64 /mysql
chown -R mysql:mysql /mysql /data
#上一句递归改变文件用户所有权(这样好像是给MySQL用户全委托,以便MySQL在创建或者删除文件时候有权限有目录)
echo >这个符号表示将命令的输出重定向到一个文件中。如果文件不存在,它会被创建;如果文件已经存在,它的内容会被覆盖。例如,echo “hello” > file.txt 会将字符串 “hello” 写入到 file.txt 文件中,覆盖原有内容。
(此时还没有mysql.sh这个文件)
cp /mysql/support-files/mysql.server /etc/init.d/mysqld
echo "PATH=$PATH:/mysql/bin" > /etc/profile.d/mysql.sh
#为了添加路径在任何地方都可以启动MySQL
source /etc/profile.d/mysql.sh
#上一句设置的环境变量并没有真正生效,只是使用source 命令让临时运行,只能在当前终端生效,重新开启一个终端后该环境变量失效,重启即可 chkconfig mysqld on #chkConfig的用法, mysqld开机自启动
配置my.cnf
(此时还没有my.cnf这个文件)
vi /etc/my.cnf
#(master-1和slave-2只有server_id不同,这个我查是只作为一个标志,区分服务器,没有实际意义)
#master配置文件
[mysqld]
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
basedir=/mysql #mysql路径
datadir=/data/data
port = 3306
socket=/mysql/mysql.sock #socket 即 Unix 套接字文件,是一种客户端连接 MySQL 服务端的方式
character-set-server=utf8
log-error=/data/log/mysqld.log
pid-file = /data/log/mysqld.pid #pid 文件记录的是当前 mysqld 进程的 pid ,pid 亦即 Process ID,pid 文件的作用是防止启动多个进程副本
#GTID:
server_id=22 #服务器id
gtid_mode=on #开启gtid模式
enforce_gtid_consistency=on #强制gtid一致性,开启后对于特定create table不被支持
#binlog
log_bin=/data/binlog/master-binlog
log-slave-updates=1 #设置从节点应用relaylog后产生binlog
binlog_format=row #强烈建议,其他格式可能造成数据不一致
#relay log
relay_log=/data/relaylog/relaylog
skip_slave_start=1 #0为禁用skip-slave-start,slave进程会随着mysql启动而启动;skip-slave-start=1为开启
max_connect_errors=1000
default_authentication_plugin = 'mysql_native_password' #身份认证方式
#slave1配置文件
[mysqld]
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
basedir=/mysql #mysql路径
datadir=/data/data
port = 3306
socket=/mysql/mysql.sock
character-set-server=utf8
log-error=/data/log/mysqld.log
pid-file = /data/log/mysqld.pid
max_connect_errors=1000
#GTID:
gtid_mode=on
enforce_gtid_consistency=on
server_id=23
#binlog
log_bin=/data/binlog/slave1-binlog
log-slave-updates=1
binlog_format=row #强烈建议,其他格式可能造成数据不一致
#relay log
relay_log=/data/relaylog/relaylog
skip_slave_start=1
default_authentication_plugin = 'mysql_native_password'
#slave2配置文件
[mysqld]
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
basedir=/mysql #mysql路径
datadir=/data/data
port = 3306
socket=/mysql/mysql.sock
character-set-server=utf8
log-error=/data/log/mysqld.log
pid-file = /data/log/mysqld.pid
#GTID:
gtid_mode=on
enforce_gtid_consistency=on
server_id=24
#binlog
log_bin=/data/binlog/slave2-binlog
log-slave-updates=1
binlog_format=row #强烈建议,其他格式可能造成数据不一致
#relay log
relay_log=/data/relaylog/relaylog
skip_slave_start=1
default_authentication_plugin = 'mysql_native_password'
注意:MySQL8.0相较于MySQL5.7在sql_mode配置上少了NO_AUTO_CREATE_USER
/mysql/bin/mysqld --initialize --user=mysql --basedir=/mysql --datadir=/data/data
#注意此处需要保证--datadir目录为空,否在会报错,记住初始密码
启动前先创建mysql日志文件
su - mysql
#`su`命令(代表"switchuser")是用于切换用户的命令。 它允许当前登录的用户切换到另一个用户账户,并在该账户下执行命令。
touch /data/log/mysqld.log
#touch用来创建新的空文件
exit systemctl start mysqld
#确保启动没报错,ps -ef|grep mysql 可以看到进程
注意!此处强烈搭建小白将几台集群服务器的账号、密码设置为一样的,因为后续安装mha的时候会检查主机间的复制情况,这时会有三个用户需要填写到配置文件,此时搞不清哪个是哪个就会一直报错!所以设置为一致的,都一样也就间接避免了这个问题(大佬随意)
如果想在主库上执行一些操作,但不复制到slave库上,可以通过修改参数sql_log_bin来实现。0不复制,1复制。
USE语句可以通知MySQL把所指示的数据库作为当前数据库,只有使用USE语句来指定某个数据库作为当前数据库之后,才能对该数据库及其存储的数据对象执行操作。use命令可以让我们来使用数据库,其格式为:use<数据库名>。
#(主从节点均需执行,注意root密码)
# grep password /data/log/mysqld.log #用于root初始密码查找,上面记住了初始密码。就不用执行这一句了
mysql -uroot -p初始密码 #有特殊符号可以用双引号引起来“初始密码”
mysql>#SET SQL_LOG_BIN=off; #第一次不用注意这个,当sql_log_bin关闭后,主库服务器上的改动不记录bin log,不会复制到从库。如果是基于GTID复制,当关闭sql_log_bin后,任何修改,不会有GTID,也不会记录到bin log
mysql>ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '******'; #master\slave1\slave2均为此密码
mysql>FLUSH PRIVILEGES;
mysql>use mysql;
mysql>select host, user, authentication_string, plugin from user;
mysql>update user set host = '%' where user = 'root'; #Host列指定了允许用户登录所使用的IP,Host=%,表示所有IP都有连接权限
mysql>flush privileges;
mysql>#SET SQL_LOG_BIN=1; #第一次不用注意这个
mysql>#select user,host from mysql.user 可以查看当前已开放
#如查询后root没有开放权限,尝试使用
mysql>GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'; #执行授权
mysql>flush privileges;
mysql>ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '*****';
#授权远程
mysql>flush privileges;
注意!若此时出现了这个问题ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
解决方法如下:
1、通过find / -name mysql.sock
2、查询到结果,做一个软链接到/tmp目录下即可解决问题
ln -s /mysql/mysql.sock /tmp/mysql.sock
systemctl status mysqld //查看MySQL运行状态
systemctl start mysqld //启动MySQL服务
systemctl restart mysqld //重启MySQL服务
systemctl stop mysqld //停止MySQL服务
在所有主从上执行,因为每个机器都有可能使master
create user 'repluser'@'%' identified with mysql_native_password by '******';
grant replication slave on *.* to 'repluser'@'%';
flush privileges;
#ALTER USER 'repluser'@'%' IDENTIFIED WITH mysql_native_password BY '******';
#flush privileges;
2个从节点配置复制通道(slave1/slave2)
#salve1
mysql>change master to master_host='master',master_port=3306,master_user='repluser',master_password='******',MASTER_AUTO_POSITION=1;
#配置前看好配置信息!新手后续更改比较费劲,会了就不费劲了
#因为开启了gtid,可以设置MASTER_AUTO_POSITION=1使主从复制自动按照gtid的位置复制
#此处的root用户可以改成自己的MySQL用户
#salve2
mysql>change master to master_host='master',master_port=3306,master_user='repluser',master_password='******',MASTER_AUTO_POSITION=1;
#配置前看好配置信息!新手后续更改比较费劲,会了就不费劲了
#因为开启了gtid,可以设置MASTER_AUTO_POSITION=1使主从复制自动按照gtid的位置复制
#此处的root用户可以改成自己的MySQL用户
从节点启动复制进程并检查复制状态
#启动slave
mysql>START SLAVE;
#查看从库的状态
mysql>SHOW SLAVE STATUS\G;
#确保 :
#Slave_IO_Running: Yes
#Slave_SQL_Running: Yes
如需重新更改同步配置,如下:
从库
stop slave;
reset slave;
change master to MASTER_AUTO_POSITION=0;
flush privileges;
主库
flush logs;
show master status; #要重新查看内容更改
从库
exit
systemctl restart mysqld
stop slave;
reset slave;
change master to
master_host="master",
master_user="repluser",
master_password="******",
master_log_file="master-binlog.000003",
master_log_pos=277;
#看主库新的内容后更改file
change master to MASTER_AUTO_POSITION=1;
#change master to master_host='master',master_port=3306,master_user='repluser',master_password='******',master_log_file="master-binlog.000002",master_log_pos=3059,MASTER_AUTO_POSITION=1;
start slave;
show slave status \G
(1)
Slave_IO_Running: Connecting
Slave_SQL_Running: Yes
(2)
Slave_IO_Running: Yes
Slave_SQL_Running: No
出现上出问题可查看MySQL高可用集群搭建(一主一从)-CSDN博客,内有详细解决办法,在此不作赘述。
set global super_read_only=1;
上面完成设置同步,下面进行测试,新手上面安装没问题就先往后走,要不会卡住,不过确实建议试试。
#master上插入数据,检查slave1,slave2是否数据同步
主库
mysql>
show databases;
create database test;
use test;
create table test (id int primary key);
insert into test values(1);
insert into test values(2);
select * from test;
主库
DROP DATABASE [ IF EXISTS ] <数据库名>;
#从节点slave1:(新主节点)
mysql>
stop slave;
set global read_only=0;
#原主节点master:
mysql>
set global super_read_only=1;
change master to master_host='slave1',master_port=3306,master_user='repluser',master_password='******',MASTER_AUTO_POSITION=1;
start slave;
show slave status \G;
#从节点slave2:
mysql>
show slave status \G;
stop slave;
change master to master_host='db2',master_port=3306,master_user='rpl_user',master_password='******',MASTER_AUTO_POSITION=1;
start slave;
show slave status \G;
#slave1上插入数据,检查master,slave2是否数据同步
要先把需要的依赖先安装好,后面node和manager安装才不会报错
#未打开外网权限,已更新yum源
#安装node节点需要的依赖
yum -y install epel-release
yum -y install perl-DBD-MySQL perl-DBI ncftp
#安装manager节点需要的依赖
yum -y install epel-release
yum -y install perl-Config-Tiny perl-Time-HiRes perl-Parallel-ForkManager perl-Log-Dispatch perl-DBD-MySQL ncftp
tar zxf mha-node-dep.tar.gz #node依赖 rpm -ivh node/*
#管理节点mha安装Manager软件
#需要安装依赖
tar zxf mha-manager-dep.tar.gz #manager依赖 rpm -ivh manager/*
查看rpm包内容的方法有:
masterha_manager -v #注意此时就会报错,大概是安装依赖有问题什么的
用which is masterha_check_ssh,来看masterha_check_ssh命令的路径
之前已经配过就无需再配了
可以更改,但要记住,后面配置文件需要这个路径
mkdir -p /etc/mha/{conf,log,scripts}
vi /etc/mha/conf/mha.cnf
#注意修改里面的ip,路径,用户,密码等(password与repl_password均为mysql密码)
#进入
[server default]
#mha访问数据库的账号与密码
user=root
password=*****
port=3306
#指定mha的工作目录
manager_workdir=/etc/mha/log
#指定管理日志路径
manager_log=/etc/mha/log/manager.log
#指定master节点存放binlog的日志文件的目录 log_bin=mysql_bin默认是在/var/lib/mysql
master_binlog_dir=/data/binlog
#指定mha在远程节点上的工作目录
remote_workdir=/etc/mha/log
#指定主从复制的mysq用户和密码
repl_user=repluser
repl_password=*****
#指定检测间隔时间
ping_interval=1
#指定一个脚本,该脚本实现了在主从切换之后,将虚拟ip漂移到新的master上
master_ip_failover_script=/etc/mha/scripts/master_ip_failover
master_ip_online_change_script=/etc/mha/scripts/master_ip_online_change
#指定用于二次检查节点状态的节点,这里不要配置主节点的ip,否则主节点网络断掉或者机器断电就无法切换
#secondary_check_script=/usr/bin/masterha_secondary_check -s 10.8.40.68 -s 10.6.119.241
#用于故障切换的时候发送邮件提醒
#report_script=/data1/mysql_mha/send_mail
ssh_user=root
ssh_port=22
#master
[server1]
hostname=11.146.121.22
port=3306
ssh_user=root
candidate_master=1
#check_repl_delay=0
master_binlog_dir=/data/binlog
remote_workdir=/etc/mha/log
#slave1
[server2]
hostname=11.146.121.23
port=3306
ssh_user=root
candidate_master=1
#check_repl_delay=0
master_binlog_dir=/data/binlog
remote_workdir=/etc/mha/log
#注意,当下面节点和MHA manager部署在一台机器的时候下面的内容直接注释掉,否则校验不通过
#slave2
[server3]
hostname=11.146.121.24
ssh_user=root
port=3306
master_binlog_dir=/data/binlog
remote_workdir=/etc/mha/log
#将脚本文件移到./etc/mha/scripts/中
chmod a+x /etc/mha/scripts/*
#脚本中记着修改vip地址以及用户密码,均为后续需要登录的数据库密码,方便切换主从。
masterha_check_ssh --conf=/etc/mha/conf/mha.cnf
#输出如下
. . .
[info] All SSH connection tests passed successfully.
masterha_check_repl --conf=/etc/mha/conf/mha.cnf
#Result:Checking the Status of the script.. OK
# MySQL Replication Health is OK.
#not ok的话是出了一些问题
ln -s /usr/share/perl5/vendor_perl/MHA /usr/lib64/perl5/vendor_perl/
masterha_check_status --conf=/etc/mha/conf/mha.cnf
# mha is stopped(2:NOT_RUNNING).
此处还未启动,停止状态为正常结果。
show slave hosts; 查看从库
# 虚拟ip与之前在脚本中配置的保持一直,选用未占用的地址
# 用于切换主从时ip指向最新的主库
/sbin/ip addr add 11.146.121.25/24 dev ens160 label ens160:1(添加)
/sbin/ip addr del 11.146.121.25/24 dev ens160 label ens160:1(删除)(需要时再用,后续故障模拟时候会用到)
# 可参考/etc/mha/scripts/master_ip_failover中的命令,虚拟ip详细地址参选主机同网段空心地址,ens从ifconfig配置中查看本机网卡再填入
nohup masterha_manager --conf=/etc/mha/conf/mha.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /etc/mha/log/manager.log 2>&1 &
--remove_dead_master_conf 删除宕机主机配置
--ignore_last_failover 任何时间出现错误都会进行切换
# 检查日志
tail -f /etc/mha/log/manager.log
...
Ping(SELECT) succeeded, waiting until MySQL doesn't respond..
...
检查日志这时候可能会比较卡,可能是我服务器本身就比较卡,而且会报错VIP的问题
USE of uninitialized value $ssh_user in concatenation (.) or string at /etc/mha/scripts/master_ip_failover ;ine 77.
Failed to deactivate master IP eith return code 1:0
GOT ERROE: at /usr/bin/masterha_manager line 65.
got error so couldn't continue failover from here
这时检查复制状态,如果显示IO:NO,重启MySQL,再设置read_only为1
masterha_check_status --conf=/etc/mha/conf/mha.cnf
#mha (pid:20102) is running(0:PING_OK), master:11.146.123.22
masterha_stop --conf=/etc/mha/conf/mha.cnf
此部分参考MySQL高可用集群搭建(一主一从)-CSDN博客,在此不作赘述。
在进行MHA文件配置的时候,scripts文件夹下面的两个文件都需要配置VIP的信息,VIP是由自己设置的虚拟IP,可以根据自己集群的ip来设计,比如我这里是11.146.121.22、11.146.121.23、11.146.121.24,所以VIP就定为111.146.121.25,而且要确保25不与其他ip冲突,是一个无人使用的状态。VIP使用的网卡是配置VIP的主机网卡。而且在云桌面或者其他平台连接VIP时,要确保该平台到VIP的网络是通的。
ifconfig #查看网卡
至此,恭喜你已经完成“基于MySQL8.0安装部署MHA集群(一主两从)”的搭建,一路以来我们一起解决了很多问题,放松一下吧!