Mysql高可用架构之MHA(基于GITDs的一主两从)

一、实验思路

1.MHA架构

1)数据库安装
2)一主两从(基于GITDS)
3)MHA搭建

2.故障模拟

1)主库失效
2)备选主库成为主库
3)原故障主库恢复重新加入到MHA成为从库

二、准备环境

1.服务器规划
服务器系统IP需要安装
MHA manager 节点服务器CentOS7.4(64 位)10.32.176.80Mysq5.7、MHA node 和 manager 组件
Master 节点服务器CentOS7.4(64 位)10.32.176.81mysql5.7、MHA node 组件
Slave1 节点服务器CentOS7.4(64 位)10.32.176.82mysql5.7、MHA node 组件
Slave2节点服务器CentOS7.4(64 位)10.32.176.86mysql5.7、MHA node 组件
2.关闭防火墙

操作节点:所有

systemctl stop firewalld
systemctl disable firewalld
setenforce 0

三、mysql安装

1.下载mysql安装包

MySQL 5.7 Linux安装包下载:https://dev.mysql.com/downloads/mysql/

2.查询并卸载系统自带的Mariadb
rpm -qa | grep mariadb 
rpm -e --nodeps 文件名
3.建立一个mysql用户和mysql用户组
# 添加mysql用户组 groupadd mysql 
# 添加mysql用户 useradd -g mysql mysql -d /home/mysql
# 修改mysql用户的登陆密码 passwd mysql
4.创建临时目录、数据目录和日志目录
mkdir -p /home/mysql/3306/data
mkdir -p /home/mysql/3306/log
mkdir -p /home/mysql/3306/tmp
5.安装包上传至服务器/usr/local目录下
# 解压缩 tar -xvf mysql-5.7.35-linux-glibc2.12-x86_64.tar
# 会得到一个mysql-5.7.35-linux-glibc2.12-x86_64.tar.gz文件,再解压缩 tar -zxvf mysql-5.7.35-linux-glibc2.12-x86_64.tar.gz
# 建立软链接,便于以后版本升级 ln -s mysql-5.7.35-linux-glibc2.12-x86_64 mysql 
# 修改mysql文件夹下所有文件的用户和用户组 chown -R mysql:mysql mysql/
6.创建配置文件
# 创建配置文件 cd /etc
# 在my.cnf文件中添加对应的配置项,文章末尾会提供一个默认的my.cnf配置 vi my.cnf
7.安装数据库
# 初始化数据库,并指定启动mysql的用户 ./mysqld --initialize --user=mysql

这里最好指定启动mysql的用户名,否则就会在启动MySQL时出现权限不足的问题

8.设置开机自启动服务
# 复制启动脚本到资源目录 cp ./support-files/mysql.server /etc/rc.d/init.d/mysqld
# 增加mysqld服务控制脚本执行权限 chmod +x /etc/rc.d/init.d/mysqld
# 将mysqld服务加入到系统服务 chkconfig --add mysqld 
# 检查mysqld服务是否已经生效 chkconfig --list mysqld 
# 切换至mysql用户,启动mysql service mysqld start
9.配置环境变量

为了更好的操作mysql,配置环境变量

# 切换至mysql用户 su - mysql
# 修改配置文件 
vi .bash_profile
export PATH=$PATH:/usr/local/mysql/bin
# 立即生效 
source .bash_profile
10.登陆 修改密码
# 登陆mysql mysql -uroot -p(注:安装完成后,在my.cnf中配置的datadir目录下生成一个error.log文件,里面记录了root用户的随机密码。)
# 修改root用户密码 set password for root@localhost=password("mect888!");

四、搭建基于GITDs的一主两从数据库集群

1.准备mysql的配置文件my.cnf

vim /etc/my.cnf

master my.cnf配置如下:

[client]                                       
port = 3306                                   
socket = /home/mysql/3306/tmp/mysql.sock                     

[mysqld]                                        

server-id = 1                                 
port = 3306                                    
basedir = /usr/local/mysql                      
datadir = /home/mysql/3306/data                     
tmpdir  = /home/mysql/3306/tmp                                
socket = /home/mysql/3306/tmp/mysql.sock       
pid-file = /home/mysql/3306/log/mysql.pid   

log_error = /home/mysql/3306/log/error.log     # 数据库错误日志文件
slow_query_log = 1                             # 慢查询sql日志设置
long_query_time = 1                            # 慢查询时间;超过1秒则为慢查询
slow_query_log_file = /home/mysql/3306/log/slow.log                  # 慢查询日志文件
log_queries_not_using_indexes = 1              # 检查未使用到索引的sql
log_throttle_queries_not_using_indexes = 5     # 用来表示每分钟允许记录到slow log的且未使用索引的SQL语句次数。该值默认为0,表示没有限制
min_examined_row_limit = 100                   # 检索的行数必须达到此值才可被记为慢查询,查询检查返回少于该参数指定行的SQL不被记录到慢查询日志
expire_logs_days = 5                           # MySQL binlog日志文件保存的过期时间,过期后自动删除

# 主从复制设置
log-bin = /home/mysql/3306/data/master
binlog_format = ROW                            # binlog记录内容的方式,记录被操作的每一行

log-slave-updates=1

gtid-mode=ON
enforce-gtid-consistency=ON

slave1 my.cnf配置如下:

[client]                                       
port = 3306                                   
socket = /home/mysql/3306/tmp/mysql.sock                     

[mysqld]                                        

server-id = 2                                 
port = 3306                                    
basedir = /usr/local/mysql                      
datadir = /home/mysql/3306/data                     
tmpdir  = /home/mysql/3306/tmp                                
socket = /home/mysql/3306/tmp/mysql.sock       
pid-file = /home/mysql/3306/log/mysql.pid   

log_error = /home/mysql/3306/log/error.log     # 数据库错误日志文件
slow_query_log = 1                             # 慢查询sql日志设置
long_query_time = 1                            # 慢查询时间;超过1秒则为慢查询
slow_query_log_file = /home/mysql/3306/log/slow.log                  # 慢查询日志文件
log_queries_not_using_indexes = 1              # 检查未使用到索引的sql
log_throttle_queries_not_using_indexes = 5     # 用来表示每分钟允许记录到slow log的且未使用索引的SQL语句次数。该值默认为0,表示没有限制
min_examined_row_limit = 100                   # 检索的行数必须达到此值才可被记为慢查询,查询检查返回少于该参数指定行的SQL不被记录到慢查询日志
expire_logs_days = 5                           # MySQL binlog日志文件保存的过期时间,过期后自动删除

# 主从复制设置
log-bin = /home/mysql/3306/data/slave1
binlog_format = ROW                            # binlog记录内容的方式,记录被操作的每一行

log-slave-updates=1

gtid-mode=ON
enforce-gtid-consistency=ON

slave2 my.cnf配置如下:

[client]                                       
port = 3306                                   
socket = /home/mysql/3306/tmp/mysql.sock                     

[mysqld]                                        

server-id = 3                                 
port = 3306                                    
basedir = /usr/local/mysql                      
datadir = /home/mysql/3306/data                     
tmpdir  = /home/mysql/3306/tmp                                
socket = /home/mysql/3306/tmp/mysql.sock       
pid-file = /home/mysql/3306/log/mysql.pid   

log_error = /home/mysql/3306/log/error.log     # 数据库错误日志文件
slow_query_log = 1                             # 慢查询sql日志设置
long_query_time = 1                            # 慢查询时间;超过1秒则为慢查询
slow_query_log_file = /home/mysql/3306/log/slow.log                  # 慢查询日志文件
log_queries_not_using_indexes = 1              # 检查未使用到索引的sql
log_throttle_queries_not_using_indexes = 5     # 用来表示每分钟允许记录到slow log的且未使用索引的SQL语句次数。该值默认为0,表示没有限制
min_examined_row_limit = 100                   # 检索的行数必须达到此值才可被记为慢查询,查询检查返回少于该参数指定行的SQL不被记录到慢查询日志
expire_logs_days = 5                           # MySQL binlog日志文件保存的过期时间,过期后自动删除

# 主从复制设置
log-bin = /home/mysql/3306/data/slave2
binlog_format = ROW                            # binlog记录内容的方式,记录被操作的每一行

log-slave-updates=1

gtid-mode=ON
enforce-gtid-consistency=ON
2.重新启动mysql

service mysql restart

3.在master和slave1授权
grant replication slave on *.* to 'rep'@'%' identified by '123';
flush privileges;
4.slave1和slave2配置为master的从
change master to master_host='10.32.176.81',master_port=3306,master_user='rep',master_password='123',master_auto_position=1;
start slave;

在 Slave1、Slave2 节点查看数据同步结果

show slave status\G

确保 IO 和 SQL 线程都是 Yes,代表同步正常。

五、MHA高可用搭建

1.MHA软件依赖安装

所有服务器上都安装 MHA 依赖的环境,首先安装 epel 源

yum install epel-release --nogpgcheck -y

yum install perl-DBD-MySQL \
perl-Config-Tiny \
perl-Time-HiRes \
perl-Mail-Sender \
perl-Mail-Sendmail \
perl-MIME-Base32 \
perl-MIME-Charset \
perl-MIME-EncWords \
perl-Params-Classify \
perl-Params-Validate.x86_64 \
perl-Log-Dispatch \
perl-Parallel-ForkManager \
net-tools -y
2.安装 MHA 软件包,先在所有服务器上必须先安装 node 组件

对于每个操作系统版本不一样,这里 CentOS7.6 选择 0.57 版本。
在所有服务器上必须先安装 node 组件,最后在 MHA-manager 节点上安装 manager 组件,因为 manager 依赖 node 组件。

cd /opt
tar zxvf mha4mysql-node-0.57.tar.gz
cd mha4mysql-node-0.57
perl Makefile.PL 
make && make install
3.在 MHA manager 节点上安装 manager 组件
cd /opt
tar zxvf mha4mysql-manager-0.57.tar.gz
cd mha4mysql-manager-0.57
perl Makefile.PL
make && make install
4.配置ssh互信

1)所有服务器上都使用root产生空密码密钥对

[root@mgr ~]# ssh-keygen -P "" -f /root/.ssh/id_rsa
[root@master ~]# ssh-keygen -P "" -f /root/.ssh/id_rsa
[root@slave1 ~]# ssh-keygen -P "" -f /root/.ssh/id_rsa
[root@slave2 ~]# ssh-keygen -P "" -f /root/.ssh/id_rsa

2)将master,slave1,slave2上产生的公钥拷给mgr管理节点上对应的路径

[root@master ~]# scp /root/.ssh/id_rsa.pub 10.32.176.80:/root/.ssh/master_id_pub
[root@slave1 ~]# scp /root/.ssh/id_rsa.pub 10.32.176.80:/root/.ssh/slave1_id_pub
[root@slave2 ~]# scp /root/.ssh/id_rsa.pub 10.32.176.80:/root/.ssh/slave2_id_pub

3)在mgr管理节点将所有的公钥(包括自己的)都追加到同一个authorized_keys文件里

[root@mgr ~]# cd /root/.ssh/

[root@mgr.ssh]# cat master_id_pub slave1_id_pub slave2_id_pub id_rsa.pub >> authorized_keys

4)在mgr管理节点上将authorized_keys文件分发给master,slave1,slave2上

[root@mgr.ssh]# for i in 81 82 86; do scp authorized_keys 10.32.176.$i:/root/.ssh/; done
5.在 manager 节点上配置 MHA

1)在 manager 节点上复制相关脚本到/usr/local/bin 目录

cp -rp /opt/mha4mysql-manager-0.57/samples/scripts /usr/local/bin
//拷贝后会有四个执行文件

ll /usr/local/bin/scripts/
master_ip_failover
master_ip_online_change 
power_manager
send_report
脚本名称作用
master_ip_failover自动切换时 VIP 管理的脚本
master_ip_online_change在线切换时 vip 的管理
power_manager故障发生后关闭主机的脚本
send_report因故障切换后发送报警的脚本

(2)复制上述的自动切换时 VIP 管理的脚本到 /usr/local/bin 目录,这里使用master_ip_failover脚本来管理 VIP 和故障切换

cp /usr/local/bin/scripts/master_ip_failover /usr/local/bin

(3)修改内容如下:(删除原有内容,直接复制并修改vip相关参数)

vim /usr/local/bin/master_ip_failover
#!/usr/bin/env 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
);
#############################添加内容部分#########################################
my $vip = '10.32.176.100';							    #指定vip的地址
my $brdc = '10.32.176.255';								#指定vip的广播地址
my $ifdev = 'ens192';								    #指定vip绑定的网卡
my $key = '1';										    #指定vip绑定的虚拟网卡序列号
my $ssh_start_vip = "/sbin/ifconfig ens192:$key $vip";	#代表此变量值为ifconfig ens192:1 10.32.176.100
my $ssh_stop_vip = "/sbin/ifconfig ens192:$key down";	#代表此变量值为ifconfig ens192:1 10.32.176.100 down
my $exit_code = 0;											#指定退出状态码为0
#my $ssh_start_vip = "/usr/sbin/ip addr add $vip/24 brd $brdc dev $ifdev label $ifdev:$key;/usr/sbin/arping -q -A -c 1 -I $ifdev $vip;iptables -F;";
#my $ssh_stop_vip = "/usr/sbin/ip addr del $vip/24 dev $ifdev label $ifdev:$key";
##################################################################################
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 \"`;
}
## A simple system call that disable the VIP on the old_master
sub stop_vip() {
`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";
}

(4)创建mha监控用户

​ master,slave1,slave2三台mysql服务器上创建mha监控用户, 需要对管理节点授权(授权时IP为管理节点IP)

mysql> grant all on *.* to mha@'10.32.176.80' identified by '123';
mysql> flush privileges;

(5)创建 MHA 软件目录并拷贝配置文件,这里使用app1.cnf配置文件来管理 mysql 节点服务器

mkdir /etc/mha

cp /opt/mha4mysql-manager-0.57/samples/conf/app1.cnf /etc/mha
vim /etc/masterha/app1.cnf

[server default]
# 设置监控用户和密码
user=mha
password=123
# 设置复制环境中的复制用户和密码
repl_user=rep
repl_password=123
# 设置ssh的登录用户名
ssh_user=root
# 设置监控主库,发送ping包的时间间隔,默认是 3 秒,尝试三次没有回应的时候自动进行failover
ping_interval=3
# 设置mgr的工作目录
manager_workdir=/data/mha/app1
# 设置mysql master 保存 binlog 的目录,以便 MHA 可以找到 master 的二进制日志
master_binlog_dir=/home/mysql/3306/data
# 设置 master 的 pid 文件
master_pid_file=/home/mysql/3306/log/mysql.pid
# 设置 mysql master 在发生切换时保存 binlog 的目录(在mysql master上创建这个目录)
remote_workdir=/tmp/data
# 设置 mgr 日志文件
manager_log=/data/mha/app1/app1-3306.log
# MHA 到 master 的监控之间出现问题,MHA Manager 将会尝试从slave1和slave2登录到master上
secondary_check_script=/usr/bin/masterha_secondary_check -s 10.32.176.82 -s 10.32.176.86 --user=root --port=22 --master_host=10.32.176.81 --master_port=3306
# 设置自动 failover 时候的切换脚本
master_ip_failover_script=/usr/local/bin/master_ip_failover

[server1]
hostname=10.32.176.81		
port=3306
candidate_master=1		
[server2]
hostname=10.32.176.82
port=3306
candidate_master=1
[server3]
hostname=10.32.176.86
port=3306
no_master=1

(6)第一次配置需要在master节点手动开启虚拟IP

/usr/sbin/ifconfig ens192:1 10.32.176.100/24

(7)检查ssh互信状态和集群状态

[root@mgr ~]# masterha_check_ssh --conf=/etc/mha/app1.conf
......
Wed May 25 10:40:41 2021 - [info] All SSH connection tests passed successfully.  
[root@mgr ~]# masterha_check_repl --conf=/etc/mha/app1.conf
......
MySQL Replication Health is OK.

(8)启动MHA-Mgr状态监控

先检查状态, 为NOT_RUNNING状态

[root@mgr ~]# masterha_check_status --conf=/etc/mha/app1.conf
app1 is stopped(2:NOT_RUNNING).

六、开启MHA Manager监控

[root@mgr ~]# nohup masterha_manager --conf=/etc/mha/app1.conf --ignore_last_failover &
[root@mgr ~]# masterha_check_status --conf=/etc/mha/app1.conf
app1 (pid:10121) is running(0:PING_OK), master:10.32.176.81

查看日志变化

tail -f /data/mha/app1/app1-3306.log

七、故障模拟

1.在 manager 节点上监控观察日志记录
tail -f /data/mha/app1/app1-3306.log
2.在 Master 节点上停止mysql服务

service mysqld stop

或者kill -9 pid

同时查看app1-3306.log的变化

ps:

正常自动切换一次后,MHA 进程会退出。HMA 会自动修改 app1.cnf 文件内容,将宕机的 mysql1 节点删除。

查看 mysql2 是否接管 VIP

八、故障修复

1.启动原master(模拟故障)的mysql服务

service mysqld start

2.进入数据库执行以下命令,配置为新的slave1
mysql> change master to master_host='10.32.176.82', master_user='rep',master_password='123',master_port=3306, master_auto_position=1;

mysql> start slave;

mysql> show slave status\G
Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.32.176.82	确认此IP为slave1的IP(也就是现在的master的IP)
                  Master_User: rep
                  Master_Port: 3306
				  ......
				  ......
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
3.重新检查ssh互信状态和集群状态
[root@mgr ~]# masterha_check_ssh --conf=/etc/mha/app1.conf
......
Wed May 25 10:40:41 2021 - [info] All SSH connection tests passed successfully.  


[root@mgr ~]# masterha_check_repl --conf=/etc/mha/app1.conf
......
MySQL Replication Health is OK.

4.启动MHA-Mgr状态监控

先检查状态, 为NOT_RUNNING状态

[root@mgr ~]# masterha_check_status --conf=/etc/mha/app1.conf
app1 is stopped(2:NOT_RUNNING).

开启MHA Manager监控

[root@mgr ~]# nohup masterha_manager --conf=/etc/mha/app1.conf --ignore_last_failover &
[root@mgr ~]# masterha_check_status --conf=/etc/mha/app1.conf
app1 (pid:10121) is running(0:PING_OK), master:10.32.176.82

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值