PS:楼主技术能力有限,如有更好的解决思路请留下评论哈,谢谢。
文章目录
前言
MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton(现就职于Facebook公司)开发,是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件。在MySQL故障切换过程中,MHA能做到在0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA能在最大程度上保证数据的一致性,以达到真正意义上的高可用。
该软件由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)
。MHA Manager可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署在一台slave节点上。MHA Node运行在每台MySQL服务器上,MHA Manager会定时探测集群中的master节点,当master出现故障时,它可以自动将最新数据的slave提升为新的master,然后将所有其他的slave重新指向新的master。整个故障转移过程对应用程序完全透明。
楼主此次搭建环境使用一主二从
的部署环境,MHA的manager节点单独部署在一台服务器中,另外因为这个环境要用在生产环境中担心manager节点出现单点故障问题,所以在其中一个slave服务器中部署多一个manager服务然后通过shell脚本监测manager节点的masterha进程,一旦masterha进程意外退出或者manager节点服务器意外宕机则自动启动slave节点中的manager服务对集群继续接管。
以下是本篇文章部署服务的大致结构
本文章mysql使用5.7.36版本
MHA版本使用0.58版本
主机IP | 节点/主机名 | 备注 |
---|---|---|
10.240.17.14 | manager | MHA管理节点 |
10.240.17.10 | master | Mysql-主库 |
10.240.17.11 | node01 | Mysql-从库 |
10.240.17.12 | node02 | Mysql-从库/MHA管理节点2 |
一、各服务器之间实现免密登录
1.添加各服务器间hosts指向
- manager节点(10.240.17.14)
编辑/etc/hosts文件,尾行加入:
10.240.17.10 master
10.240.17.11 node01
10.240.17.12 node02
- master节点(10.240.17.10)
编辑/etc/hosts文件,尾行加入:
10.240.17.14 manager
10.240.17.11 node01
10.240.17.12 node02
- node01节点(10.240.17.11)
编辑/etc/hosts文件,尾行加入:
10.240.17.14 manager
10.240.17.10 master
10.240.17.12 node02
- node02节点(10.240.17.12)
10.240.17.14 manager
10.240.17.10 master
10.240.17.11 node01
2.四台服务器中分别生成密钥文件
分别在四台服务器中执行以下命令,生成密钥文件,密码为空,并将每台服务器的pub公钥文件传到其他三台服务器中,同时将pub公钥
内容追加到authorized_keys
中,以达到免密登录的效果。
$ ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa
分别为四台服务器的公钥文件重命名,避免弄混乱了,并将pub文件传输到其他节点~/.ssh
目录下
manager:
$ mv ~/.ssh/id_rsa.pub ~/.ssh/id_rsa_manager.pub
$ for i in master node01 node02; do scp ~/.ssh/id_rsa_manager.pub ${i}:~/.ssh/ ; done
master:
$ mv ~/.ssh/id_rsa.pub ~/.ssh/id_rsa_master.pub
$ for i in manager node01 node02; do scp ~/.ssh/id_rsa_master.pub ${i}:~/.ssh/ ; done
node01:
$ mv ~/.ssh/id_rsa.pub ~/.ssh/id_rsa_node01.pub
$ for i in manager master node02; do scp ~/.ssh/id_rsa_node01.pub ${i}:~/.ssh/ ; done
node02:
$ mv ~/.ssh/id_rsa.pub ~/.ssh/id_rsa_node02.pub
$ for i in manager master node01; do scp ~/.ssh/id_rsa_node02.pub ${i}:~/.ssh/ ; done
分别将其他节点的pub公钥内容追加到本节点的authorized_keys
中
manager:
$ for i in master node01 node02; do cat ~/.ssh/id_rsa_${i}.pub >> ~/.ssh/authorized_keys; done
master:
$ for i in manager node01 node02; do cat ~/.ssh/id_rsa_${i}.pub >> ~/.ssh/authorized_keys; done
node01:
$ for i in master manager node02; do cat ~/.ssh/id_rsa_${i}.pub >> ~/.ssh/authorized_keys; done
node02:
$ for i in master manager node01; do cat ~/.ssh/id_rsa_${i}.pub >> ~/.ssh/authorized_keys; done
测试:分别ssh到其他节点服务器看是否可以达到免密登录的效果
二、3台数据库节点安装Mysql服务
Mysql官网下载
网盘下载
楼主使用的是Mysql5.7.36的版本,以下操作请分别在3台数据库节点中操作
楼主使用root进行Mysql启动和管理
数据库数据和日志存放于/data/mysql_data和/data/mysql_logs目录下
检查一下服务器中是否存在mysql或者mariadb等相关组件或服务,有的话建议清理干净再进行安装:
$ rpm -qa | grep mariadb
$ rpm -qa | grep mysql
卸载请用如下命令:
$ yum remove 服务名 -y
解压安装包并修改目录名:
$ tar -zxvf mysql-5.7.36-el7-x86_64.tar.gz -C /usr/local/ && mv /usr/local/mysql-5.7.36-el7-x86_64 /usr/local/mysql
master,node01,node02三个节点中分别设置好mysql的配置文件,具体如下:
- master
[client]
port = 3306
socket = /usr/local/mysql/mysql.sock
[mysqld]
user = root
server-id = 1
port = 3306
# 此项调整innodb的缓存池大小,属于mysql调优项,具体设置大小建议为系统内存的70%-80%左右即可
innodb_buffer_pool_size = 2800M
# 设置binlog日志保存7天,最大binlog日志大小500M
expire-logs-days = 7
max-binlog-size = 500M
innodb_log_file_size = 256M
# 开启慢查询日志,slow_query.log文件建议自行创建
slow_query_log = ON
slow_query_log_file=/data/mysql_logs/slow_query.log
# 以下这部分配置请根据你的环境自行修改
# 设置数据库默认编码为:UTF-8
character-set-server=utf8
collation-server=utf8_general_ci
# 设置MySQL的时间跟随系统
log_timestamps=SYSTEM
# 设置 数据库的最大连接数
max_connections=1000
# 设置所有线程打开的表的数目默认为64
table_open_cache=6000
# 开启事件调度器
event_scheduler=ON
# 设置group_concat_max_len连接字段长度为最大值
# group_concat_max_len=-1
socket = /usr/local/mysql/mysql.sock
basedir = /usr/local/mysql
datadir = /data/mysql_data
log_error = /data/mysql_logs/mysql-error.log
log-bin = /data/mysql_data/master-bin
log-slave-updates = true
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
pid-file = /data/mysql_data/master.pid
gtid-mode = ON
enforce-gtid-consistency = ON
- node01
[client]
port = 3306
socket = /usr/local/mysql/mysql.sock
[mysqld]
user = root
server-id = 2
port = 3306
# 此项调整innodb的缓存池大小,属于mysql调优项,具体设置大小建议为系统内存的70%-80%左右即可
innodb_buffer_pool_size = 2800M
# 设置binlog日志保存7天,最大binlog日志大小500M
expire-logs-days = 7
max-binlog-size = 500M
innodb_log_file_size = 256M
# 开启慢查询日志,slow_query.log文件建议自行创建
slow_query_log = ON
slow_query_log_file = /data/mysql_logs/slow_query.log
# 以下这部分配置请根据你的环境自行修改
# 设置数据库默认编码为:UTF-8
character-set-server=utf8
collation-server=utf8_general_ci
# 设置MySQL的时间跟随系统
log_timestamps=SYSTEM
# 设置 数据库的最大连接数
max_connections=1000
# 设置所有线程打开的表的数目默认为64
table_open_cache=6000
# 开启事件调度器
event_scheduler=ON
# 设置group_concat_max_len连接字段长度为最大值
# group_concat_max_len=-1
socket = /usr/local/mysql/mysql.sock
basedir = /usr/local/mysql
datadir = /data/mysql_data
log_error = /data/mysql_logs/mysql-error.log
pid-file = /data/mysql_data/node01.pid
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
log-bin = /data/mysql_data/master-bin
gtid-mode = ON
enforce-gtid-consistency = ON
- node02
[client]
port = 3306
socket = /usr/local/mysql/mysql.sock
[mysqld]
user = root
server-id = 3
port = 3306
# 此项调整innodb的缓存池大小,属于mysql调优项,具体设置大小建议为系统内存的70%-80%左右即可
innodb_buffer_pool_size = 2800M
# 设置binlog日志保存7天,最大binlog日志大小500M
expire-logs-days = 7
max-binlog-size = 500M
innodb_log_file_size = 256M
# 开启慢查询日志,slow_query.log文件建议自行创建
slow_query_log = ON
slow_query_log_file = /data/mysql_logs/slow_query.log
# 以下这部分配置请根据你的环境自行修改
# 设置数据库默认编码为:UTF-8
character-set-server=utf8
collation-server=utf8_general_ci
# 设置MySQL的时间跟随系统
log_timestamps=SYSTEM
# 设置 数据库的最大连接数
max_connections=1000
# 设置所有线程打开的表的数目默认为64
table_open_cache=6000
# 开启事件调度器
event_scheduler=ON
# 设置group_concat_max_len连接字段长度为最大值
# group_concat_max_len=-1
socket = /usr/local/mysql/mysql.sock
basedir = /usr/local/mysql
datadir = /data/mysql_data
log_error = /data/mysql_logs/mysql-error.log
pid-file = /data/mysql_data/node02.pid
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.indexc
read_only = 1
log-bin = /data/mysql_data/master-bin
gtid-mode = ON
enforce-gtid-consistency = ON
安装autoconf依赖包:
$ yum install -y autoconf
安装mysql
$ cd /usr/local/mysql/bin
$ ./mysqld --initialize --user=root --basedir=/usr/local/mysql --datadir=/data/mysql_data
没出现报错的话此时可以进入/data/mysql_logs/mysql-error.log
文件中最下面一行查看初始密码,可以使用该密码登录数据库进行修改密码操作。
拷贝mysql启动程序到/etc/init.d/
目录下
$ cp -a /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
启动mysql
service mysqld start
配置环境变量,方便使用mysql命令
$ vim /etc/profile # 编辑/etc/profile在文件末尾加入以下内容
#mysql
export MYSQL_HOME=/usr/local/mysql
export PATH=$PATH:$MYSQL_HOME/bin
使环境变量生效
$ source /etc/profile
用日志文件中记录的初始密码登录mysql,修改密码
$ mysql -uroot -p
mysql中修改密码为111111,建议大家尽量设置复杂密码哈
mysql> alter user 'root'@'localhost' identified by '111111';
mysql> flush privileges;
另外下面两条语句一条是放通所有主机远程访问mysql,一条是放通指定IP访问mysql,看你们自己的需求了哈,这里最少要放行manager服务器的IP,不然后期MHA无法监测到主从集群的状态,还需要放行node02服务器的IP,因为node02服务器需要运行监测脚本及备用mha服务
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '111111' WITH GRANT OPTION; # 放通所有主机通过root账户和111111密码访问mysql
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'指定的IP' IDENTIFIED BY '111111' WITH GRANT OPTION; # 放通指定IP通过root账户和111111密码访问mysql
常用的命令
$ service mysqld start #启动mysql
$ service mysqld stop #关闭mysql
$ service mysqld restart #重启mysql
$ service mysqld status #查看mysql运行状态
三、启动mysql主从集群
在主节点master数据库中创建主从复制使用的用户
mysql> create user slave_user;
mysql> grant replication slave on *.* to slave_user identified by '111111';
mysql> flush privileges;
mysql> grant all on *.* to root identified by '111111';
分别在两个从节点node01和node02数据库中执行
mysql> CHANGE MASTER TO MASTER_HOST='10.240.17.10',MASTER_PORT=3306,MASTER_AUTO_POSITION=1,MASTER_USER='slave_user',MASTER_PASSWORD='111111';
mysql> start slave;
mysql> show slave status\G
在主库中创建一个库做测试,可查看从库是否同时创建了相应的库
mysql> create database 123;
由于楼主业务环境要求,这里关闭mysql的自动提交功能
mysql> set autocommit=OFF;
四、安装MHA
安装epel扩展包
$ yum install -y epel-release
安装MHA依赖的perl包
$ yum install -y perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager
四个节点服务器都安装mha4mysql-node
包
$ rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm
manager节点服务器安装mha4mysql-manager
包
$ rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
在三个mysql服务器中添加mha监控用户并指定manager服务器的IP可访问
mysql> grant all privileges on *.* to 'mha'@'10.240.17.14' identified by '111111';
manager服务器/etc/masterha/mha.cnf
中添加MHA相关配置
[server default]
# MHA manager日志目录
manager_log=/usr/local/masterha/manager.log
# MHA manager工作目录
manager_workdir=/usr/local/masterha
# 指定mysql-master主节点的binlog日志存放位置
master_binlog_dir=/data/mysql_data/
# 指定故障时自动切换master服务器IP地址的脚本
master_ip_failover_script=/usr/local/bin/master_ip_failover
# 监控主库发送 ping 包的时间间隔,默认3秒,如果3秒内没有回应将自动进行故障切换,这里楼主设定为1秒
ping_interval=1
# mysql发生切换时,二进制日志文件的保存位置
remote_workdir=/usr/local/masterha/logbin
# 指定mha监控用户与密码
user=mha
password=111111
# mysql集群复制用户与密码
repl_user=slave_user
repl_password=111111
# ssh登录的用户
ssh_user=root
[server1]
hostname=10.240.7.134
port=3306
ssh_port=22
[server2]
candidate_master=1
check_repl_delay=0
hostname=10.240.7.132
port=3306
ssh_port=22
[server3]
hostname=10.240.7.133
port=3306
ssh_port=22
manager服务器/usr/local/bin
中添加master_ip_failover切换脚本
#!/usr/bin/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 = '10.240.17.15/24'; #VIP请填写你设定的VIP
my $brdc = '10.240.17.255';
my $ifdev = 'ens160'; #添加manager服务器的网卡名称
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig ens160:$key $vip"; #这里的网卡名称也记得要改哦
my $ssh_stop_vip = "/sbin/ifconfig ens160:$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" ) {
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();
$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() {
return 0 unless ($ssh_user);
`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";
}
到此MHA配置完成
五、Manage工具测试
- 检查管理节点到所有Node节点的ssh连接状态
$ masterha_check_ssh --conf=/etc/masterha/mha.cnf
以下输出表示正常,IP跟文章不一致不用管,楼主测试环境用的是其他IP
如果报Binlog setting check failed!错误,那么有可能是master服务器保存二进制日志文件地址错误
- 检查 manager 与数据库节点间的主从复制是否正常
$ masterha_check_repl --conf=/etc/masterha/mha.cnf
以下输出表示正常,IP跟文章不一致不用管,楼主测试环境用的是其他IP
master主节点服务器绑定VIP
$ ifconfig ens160:1 10.240.7.15/24 #绑定VIP
$ ifconfig ens160:1 del 10.240.7.15 #删除VIP
安装supervisor使用supervisor进行服务管理
$ yum install -y supervisor
在/etc/supervisord.d
目录中添加mha.ini配置文件
#项目名
[program:mha]
#脚本目录
directory=/bin
#脚本执行命令
command=masterha_manager --conf=/etc/masterha/mha.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /usr/local/masterha/manager.log 2>&1 &
#supervisor启动的时候是否随着同时启动,默认True
autostart=true
#当程序exit的时候,这个program不会自动重启,默认unexpected,设置子进程挂掉后自动重启的情况,有三个选项,false,unexpected和true。如果为false的时候,无论什么情况下,都不会被重新启动,如果为unexpected,只有当进程的退出码不在下面的exitcodes里面定义的
autorestart=false
#这个选项是子进程启动多少秒之后,此时状态如果是running,则我们认为启动成功了。默认值为1
startsecs=1
#脚本运行的用户身份
user = root
#日志输出
stderr_logfile=/var/log/supervisor/mha_stderr.log
stdout_logfile=/var/log/supervisor/mha_stdout.log
#把stderr重定向到stdout,默认 false
redirect_stderr = true
#stdout日志文件大小,默认 50MB
stdout_logfile_maxbytes = 20MB
#stdout日志文件备份数
stdout_logfile_backups = 20
启动supervisor服务
$ systemctl start supervisord
因配置了mha跟随supervisor服务启动因此启动了supervisor服务同时会把mha也启动了,现在可以直接查看mha的状态
$ supervisorctl status mha # 查看mha服务运行状态
$ supervisorctl start mha # 启动mha服务
$ supervisorctl stop mha # 停止mha服务
查看mha监测mysql集群的状态
$ masterha_check_status --conf=/etc/masterha/mha.cnf
至此,MHA部分安装完成,接下来进行高可用测试,楼主测试过程中发现manager节点一旦出现问题了就无法自动进行VIP的切换,因此在Node02节点中运行了一个循环脚本用于监测manager节点的masterha进程是否正常运行,一旦意外退出了或者manager服务器宕机了,就在Node02节点中启动masterha服务进行高可用的接管(楼主测试过同时启动两个masterha进程会失败,其中一个进程会提示已有服务在监控主库的运作,所以楼主这里采用shell脚本作为辅助)。
五、Shell脚本监测Manager节点解决单点故障问题
在Node02节点服务器中安装mha4mysql-manager
$ rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
在/etc/masterha
及/usr/local/bin
两个目录分别放入配置文件及切换VIP的脚本
Node02服务器中执行操作
$ rsync -avzP manager:/etc/masterha/mha.cnf /etc/masterha/ # 同步manager节点服务器mha配置文件到node02服务器/etc/masterha目录下
$ rsync -avzP manager:/usr/local/bin/master_ip_failover /usr/local/bin/ # 同步manager节点服务器切换VIP脚本到node02服务器/usr/local/bin/目录下
添加以下配置信息到supervisor配置目录下(/etc/supervisord.d/)
$ vim /etc/supervisord.d/mha.ini
#项目名
[program:mha]
#脚本目录
directory=/bin
#脚本执行命令
command=masterha_manager --conf=/etc/masterha/mha.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /usr/local/masterha/manager.log 2>&1 &
#因为作为备用的监测点,因此自动启动这项关闭,防止启动supervisor服务就启动了mha造成冲突,mha的服务启动由监测脚本按需启动
autostart=false
#当程序exit的时候,这个program不会自动重启,默认unexpected,设置子进程挂掉后自动重启的情况,有三个选项,false,unexpected和true。如果为false的时候,无论什么情况下,都不会被重新启动,如果为unexpected,只有当进程的退出码不在下面的exitcodes里面定义的
autorestart=false
#这个选项是子进程启动多少秒之后,此时状态如果是running,则我们认为启动成功了。默认值为1
startsecs=1
#脚本运行的用户身份
user = root
#日志输出
stderr_logfile=/var/log/supervisor/mha_stderr.log
stdout_logfile=/var/log/supervisor/mha_stdout.log
#把stderr重定向到stdout,默认 false
redirect_stderr = true
#stdout日志文件大小,默认 50MB
stdout_logfile_maxbytes = 20MB
#stdout日志文件备份数
stdout_logfile_backups = 20
添加shell监测脚本,用于监测manager节点中mha服务的运行状态,楼主脚本写得较为简单,有需要请根据环境自行修改
$ vim /root/monitor_masterha.sh
#!/bin/bash
#Author:Benson
#Blog:
#Time:2022-03-08 10:26:17
#Name:monitor_masterha.sh
#Version:V1.0
#Description:后台每5秒监测一次manager节点中masterha进程是否正常运行,如意外退出则启动本服务器中的masterha程序进行mha集群的监控
while true
do
time_node=$(date "+%Y-%m-%d %H:%M:%S")
ssh root@manager "ps aux | grep /etc/masterha/mha.cnf" | grep -v grep
if [ ${?} -eq "0" ];then
echo "于${time_node}时间节点,监测manager节点masterha进程运行正常" >> /root/monitor_masterha.log
else
/bin/rsync -avzP mysqlmha-manager:/etc/masterha/mha.cnf /etc/masterha/
/bin/supervisorctl start mha
echo "masterha于${time_node}启动了。" >> /root/monitor_masterha.log
exit 0
fi
sleep 5
done
同时添加脚本的supervisor配置文件利用supervisor管理启动脚本
$ vim /etc/supervisord.d/monitor_masterha.ini
#项目名
[program:monitor_masterha]
#脚本目录
directory=/root
#脚本执行命令
command=/usr/bin/bash /root/monitor_masterha.sh &
#supervisor启动的时候是否随着同时启动,默认True
autostart=true
#当程序exit的时候,这个program不会自动重启,默认unexpected,设置子进程挂掉后自动重启的情况,有三个选项,false,unexpected和true。如果为false的时候,无论什么情况下,都不会被重新启动,如果为unexpected,只有当进程的退出码不在下面的exitcodes里面定义的
autorestart=false
#这个选项是子进程启动多少秒之后,此时状态如果是running,则我们认为启动成功了。默认值为1
startsecs=1
#脚本运行的用户身份
user = root
#日志输出
stderr_logfile=/var/log/supervisor/monitor_masterha_stderr.log
stdout_logfile=/var/log/supervisor/monitor_masterha_stdout.log
#把stderr重定向到stdout,默认 false
redirect_stderr = true
#stdout日志文件大小,默认 50MB
stdout_logfile_maxbytes = 20MB
#stdout日志文件备份数
stdout_logfile_backups = 20
配置完成后启动monitor_masterha脚本即可,如manager节点mha服务退出就会启动node02服务器上的mha服务接管mha
$ supervisorctl start monitor_masterha
六、数据库集群的故障测试及切换测试
利用下面的脚本循环插入2万条数据到mysql集群中,在插入过程中测试关掉master节点的mysql服务,查看node01节点是否接管集群成为主库
$ vim /root/insert_mysql.sh
#!/bin/bash
#Author:Benson
#Blog:
#Time:2022-03-07 16:27:57
#Name:insert_sql.sh
#Version:V1.0
#Description:
HOSTNAME="10.240.17.15" # 集群VIP地址
PORT="3306"
USERNAME="root"
PASSWORD="111111" # mysql数据库root的密码
DBNAME="abc"
TABLENAME="test"
#创建数据库
create_db_sql="create database IF NOT EXISTS ${DBNAME}"
mysql -h${HOSTNAME} -P${PORT} -u${USERNAME} -p${PASSWORD} -e "${create_db_sql}"
#创建表
create_table_sql="create table IF NOT EXISTS ${TABLENAME} ( name varchar(20), id int(11) default 0 )"
mysql -h${HOSTNAME} -P${PORT} -u${USERNAME} -p${PASSWORD} ${DBNAME} -e"${create_table_sql}"
#插入数据
for i in {1..20000}
do
insert_sql="insert into ${TABLENAME} values('${i}',${i})"
mysql -h${HOSTNAME} -P${PORT} -u${USERNAME} -p${PASSWORD} ${DBNAME} -e"${insert_sql}"
echo "已插入第${i}条数据。"
echo "========================"
done
启动插入数据脚本插入数据到数据库
$ bash /root/insert_mysql.sh
查看node01和node02的数据库数据条数
数据同步插入中,集群正常,接下来停掉master节点mysql服务
$ service mysqld stop
此时查看node01节点状态,发现VIP已经切换到node01服务器上,并且node02查看mysql集群状态发现主库指向node01的IP,集群切换成功(中间恢复连接耗时约30秒左右)
接下来测试将原master服务器恢复数据库数据并重新加入集群成为从节点
具体恢复步骤:1.通过mysqldump备份node01服务器数据-->2.master服务器启动mysql服务通过source导入备份数据-->3.查询出node01的binlog日志中的pos值-->4.master服务器stop slave停止集群后通过change master to命令重新加入集群,然后再start slave启动集群-->5.添加mha配置信息被删掉的部分-->6.启动mha服务
现在查看master和node01的数据差异
- 通过mysqldump备份node01服务器数据
$ mysqldump -uroot -p -A --master-data=2 >/root/mysql.sql
该mysql.sql文件传输到master服务器中
- master服务器启动mysql服务通过source导入备份数据
$ service mysqld start
$ mysql -uroot -p
mysql> source /root/mysql.sql;
- 查询出node01的binlog日志中的pos值
master服务器中执行或node01服务器中执行都可,主要查询的是导出的备份文件mysql.sql
$ grep MASTER_LOG_FILE ./mysql.sql | grep master-bin.000004 # master-bin.xxxxxx这个值请在从节点中登录mysql输入show slave status\G查看集群的Master_Log_File记录的值
- master服务器stop slave停止集群后通过change master to命令重新加入集群,然后再start slave启动集群
mysql> stop slave;
mysql> CHANGE MASTER TO MASTER_HOST='10.240.7.132', MASTER_PORT=3306, MASTER_LOG_FILE='master-bin.000004', MASTER_LOG_POS=399358, MASTER_USER='root', MASTER_PASSWORD='111111';
mysql> start slave;
mysql> show slave status\G
再次对比master与node01节点的数据差异,目前已恢复一致
- 添加mha配置信息被删掉的部分
$ vim /etc/masterha/mha.cnf
[server default]
manager_log=/usr/local/masterha/manager.log
manager_workdir=/usr/local/masterha
master_binlog_dir=/data/mysql_data/
master_ip_failover_script=/usr/local/bin/master_ip_failover
password=111111
ping_interval=1
remote_workdir=/usr/local/masterha/logbin
repl_password=111111
repl_user=slave_user
ssh_user=root
user=mha
[server1]
hostname=10.240.17.11
port=3306
ssh_port=22
[server2] # 这部分是另外添加的,mha切换完VIP后会删除掉master的配置,重新启动mha前要在配置我呢见中加入被删掉的主机信息并作为从库使用
candidate_master=1
check_repl_delay=0
hostname=10.240.17.10
port=3306
ssh_port=22
[server3]
hostname=10.240.17.12
port=3306
ssh_port=22
- 重新启动mha服务
$ supervisorctl start mha
最后请自行测试以下同时关掉master节点的mysql服务和manager的mha服务,这时监测脚本就会在node02节点中启动mha服务将VIP切换到node01中
楼主使用prometheus进行mysql集群的监控和告警,如有需要请自行写告警脚本进行告警哈
总结
到此Mysql高可用集群搭建完毕,楼主个人能力有限,脚本写得简易,请勿喷,另外如果有什么问题欢迎指出,谢谢。