MHA实现MySQL主从复制高可用

一、MHA介绍

1.1 MHA概述

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

1.2 MHA组成

  • MHA Manager(管理节点)
    • 用来接收外部信号,监控下方数据节点的工作状态
  • MHA Node(数据节点)
    • 工作的单位,负责具体的工作

1.3 MHA的特点

  • 自动故障切换过程中,MHA试图从宕机的主服务器上保存二进制日志,最大程度的保证数据的不丢失
  • 使用 MySQL55的半同步复制,可以大大降低数据丢失的风险
  • 目前MHA支持一主多从架构,最少三台服务,即一主两从

二、MHA实验

2.1 实验目的

  • 通过MHA监控MySQL数据库,在故障时自动进行切换,不影响业务
  • 当主库失效时,备选主库自动成为主库

2.2 实验拓扑图

2.3.实验思路

1) 安装 MySQL 数据库
2) 配置 MySQL 一主两从
3) 安装 MHA 软件
4) 配置无密码认证
5) 配置 MySQL MHA 高可用
6) 模拟 master 故障切换

2.3.1 安装mysql

在三台 MySQL 节点上分别安装数据库,MySQL 版本请使用 5.6.36,cmake 版本请使
用 2.8.6。之前博客有详细安装mysql步骤,这边不再说明。

2.3.2 搭建mysql主从复制环境

  • 参考之前的博客:

https://www.cnblogs.com/bushilengmo/p/13668756.html

  • 所有数据库授权mha用户对数据库的操作权限,每一个mysql数据库都要设置
1 在所有数据库节点上授权两个用户,一个是从库同步使用,另外一个是 manager 使用。
2 mysql> grant replication slave on *.* to 'myslave'@'192.168.195.%' identified by '123';
3 mysql> grant all privileges on *.* to 'mha'@'192.168.195.%' identified by 'manager';
4 mysql> flush privileges;

2.3.3 在 Mysql1 主机上查看二进制文件和同步点

mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 |     1215 |              |                  |                   |
+-------------------+----------+--------------+------------------+-------------------+

2.3.4 接下来在 Mysql2 和 Mysql3 分别执行同步。

mysql> change master to master_host='192.168.195.129',master_user='myslave',master_password='123',master_log_file='master-bin.000001',master_log_pos=1215; 
mysql> start slave;

2.3.5 查看 IO 和 SQL 线程都是 yes 代表同步是否正常。

mysql> show slave statusG;
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

必须设置两个从库为只读模式:
mysql> set global read_only=1;

2.4 所有节点安装环境和Node组件和Manager组件

  • 所有服务器上都要安装mha依赖的环境,此处仅展示mha_manager的安装
[root@mha_manager ~]# yum install epel-release --nogpgcheck -y
[root@mha_manager ~]# yum install -y perl-DBD-MySQL 
perl-Config-Tiny 
perl-Log-Dispatch 
perl-Parallel-ForkManager 
perl-ExtUtils-CBuilder 
perl-ExtUtils-MakeMaker 
perl-CPAN
  • 所有服务器都安装安装node组件,此处仅展示master服务器的安装
[root@master ~]# tar zxvf /mnt/shuju数据库/mha/mha4mysql-node-0.57.tar.gz 
[root@master ~]# cd mha4mysql-node-0.57/
[root@master mha4mysql-node-0.57]# yum install perl-Module-Install -y
[root@master mha4mysql-node-0.57]# perl Makefile.PL 
==> Auto-install the 1 mandatory module(s) from CPAN? [y] y    '//输入y'
[root@master mha4mysql-node-0.57]# make
[root@master mha4mysql-node-0.57]# make install
  • 仅mha_manager服务器安装manager组件
[root@mha_manager ~]# tar zxvf /mnt/shuju数据库/mha/mha4mysql-manager-0.57.tar.gz 
[root@mha_manager ~]# cd mha4mysql-manager-0.57/
[root@mha_manager mha4mysql-manager-0.57]# perl Makefile.PL 
[root@mha_manager mha4mysql-manager-0.57]# make
[root@mha_manager mha4mysql-manager-0.57]# make install

2.5 配置节点间SSH免交互登陆

  • mha_manager主机配置到所有数据库节点的密钥对验证
[root@MHA-manager ~]# ssh-keygen -t rsa //一路按回车键
[root@MHA-manager ~]# ssh-copy-id 192.168.195.129
[root@MHA-manager ~]# ssh-copy-id 192.168.195.130
[root@MHA-manager ~]# ssh-copy-id 192.168.195.131
  • 在master上配置到数据库节点slave1和slave2的免密验证
[root@Mysql1 ~]# ssh-keygen -t rsa
[root@Mysql1 ~]# ssh-copy-id 192.168.195.130
[root@Mysql1 ~]# ssh-copy-id 192.168.195.131
  • 在slave1上配置到数据库节点master和slave2的免密验证
[root@Mysql2 ~]# ssh-keygen -t rsa
[root@Mysql2 ~]# ssh-copy-id 192.168.195.129
[root@Mysql2 ~]# ssh-copy-id 192.168.195.131
  • 在slave2上配置到数据库节点master和slave1的免密验证
[root@Mysql3 ~]# ssh-keygen -t rsa
[root@Mysql3 ~]# ssh-copy-id 192.168.195.129
[root@Mysql3 ~]# ssh-copy-id 192.168.195.130

2.6 配置MHA-Manager组件

  • 在 manager 节点上复制相关脚本到/usr/local/bin 目录
[root@mha_manager ~]# cp -ra /root/mha4mysql-manager-0.57/samples/scripts /usr/local/bin
[root@mha_manager samples]# ls -l /usr/local/bin/scripts/
-rwxr-xr-x. 1 1001 1001  3648 5月  31 2015 master_ip_failover  自动切换时 VIP管理的脚本
-rwxr-xr-x. 1 1001 1001  9870 5月  31 2015 master_ip_online_change  在线切换VIP的管理 
-rwxr-xr-x. 1 1001 1001 11867 5月  31 2015 power_manager  故障发生后关闭主机的脚本
-rwxr-xr-x. 1 1001 1001  1360 5月  31 2015 send_report  因故障切换后发送报警的脚本
[root@mha_manager ~]# cp /usr/local/bin/scripts/master_ip_failover /usr/local/bin/    '//自动切换时 VIP管理的脚本'
  • 修改master_ip_failover 脚本
[root@mha_manager ~]# 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 = '192.168.195.200';
my $brdc = '192.168.195.255';
my $ifdev = 'ens33';
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down";
my $exit_code = 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 "

IN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===

";

if ( $command eq "stop" || $command eq "stopssh" ) {

my $exit_code = 1;
eval {
print "Disabling the VIP on old master: $orig_master_host 
";
&stop_vip();
$exit_code = 0;
};
if ($@) {
warn "Got Error: $@
";
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 
";
&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 
";
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
";
}
  • 创建MHA软件目录并拷贝配置文件
[root@MHA-manager ~]# mkdir /etc/masterha
[root@MHA-manager ~]# cp /root/mha4mysql-manager-0.57/samples/conf/app1.cnf /etc/masterha/
[root@MHA-manager ~]# vim /etc/masterha/app1.cnf
[server default]
manager_workdir=/var/log/masterha/app1.log               ##manager工作目录
manager_log=/var/log/masterha/app1/manager.log            #manager日志
master_binlog_dir=/usr/local/mysql/data/                #master保存binlog的位置,这里的路径要与master里配置的binlog的路径一致,以便mha能找到
#master_ip_failover_script= /usr/local/bin/master_ip_failover    #设置自动failover时候的切换脚本,也就是上边的哪个脚本
master_ip_online_change_script= /usr/local/bin/master_ip_online_change  #设置手动切换时候的切换脚本
password=manager      #设置mysql中root用户的密码,这个密码是前文中创建监控用户的那个密码
user=mha        #设置监控用户root
ping_interval=1      #设置监控主库,发送ping包的时间间隔,默认是3秒,尝试三次没有回应的时候自动进行railover
remote_workdir=/tmp    #设置远端mysql在发生切换时binlog的保存位置
repl_password=123        #设置复制用户的密码
repl_user=myslave           #设置复制用户的用户
report_script=/usr/local/send_report      //设置发生切换后发送的报警的脚本
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.195.130 -s 192.168.195.131
shutdown_script=""  #设置故障发生后关闭故障主机脚本(该脚本的主要作用是关闭主机放在发生脑裂,这里没有使用)
ssh_user=root      #设置ssh的登录用户名

[server1]
hostname=192.168.195.129
port=3306

[server2]
hostname=192.168.195.130
port=3306
candidate_master=1    #//设置为候选master,如果设置该参数以后,发生主从切换以后将会将此从库提升为主库,即使这个主库不是集群中事件最新的slave
check_repl_delay=0    

[server3] hostname=192.168.195.131 port=3306

2.7 测试 ssh 无密码认证,如果正常最后会输出 successfully,如下所示

[root@MHA-manager ~]# masterha_check_ssh -conf=/etc/masterha/app1.cnf

Tue Nov 26 23:09:45 2019 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Tue Nov 26 23:09:45 2019 - [info] Reading application default configuration from /etc/masterha/app1.cnf..
Tue Nov 26 23:09:45 2019 - [info] Reading server configuration from /etc/masterha/app1.cnf..
Tue Nov 26 23:09:45 2019 - [info] Starting SSH connection tests..
Tue Nov 26 23:09:46 2019 - [debug] 
Tue Nov 26 23:09:45 2019 - [debug]  Connecting via SSH from root@192.168.195.130(192.168.195.130:22) to root@192.168.195.131(192.168.195.131:22)..
Tue Nov 26 23:09:46 2019 - [debug]   ok.
Tue Nov 26 23:09:47 2019 - [debug] 
Tue Nov 26 23:09:46 2019 - [debug]  Connecting via SSH from root@192.168.195.131(192.168.195.131:22) to root@192.168.195.130(192.168.195.130:22)..
Tue Nov 26 23:09:47 2019 - [debug]   ok.
Tue Nov 26 23:09:47 2019 - [info] All SSH connection tests passed successfully.

2.8 启动MHA

  • 第一次配置需要去master上手动开启虚拟IP
[root@Mysql1 ~]# /sbin/ifconfig ens33:1 192.168.195.200/24
  • 启动mha
[root@MHA-manager ~]# nohup masterha_manager --conf=/etc/masterha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1 &
[1] 129929

三、验证实验

1 [root@MHA-manager ~]#tailf /var/log/masterha/app1/manager.log     //启用监控观察日志记录
2 [root@Mysql1 ~]# pkill -9 mysql         //查看master变化

3.1 故障模拟:

  • 在主库上:pkill mysqld

可以看到从库的状态,其中之一肯定有切换到主库的
切换备选主库的算法:
1.一般判断从库的是从(position/GTID)判断优劣,数据有差异,最接近于master的slave,成为备选主。
2.数据一致的情况下,按照配置文件顺序,选择备选主库。
3.设定有权重(candidate_master=1),按照权重强制指定备选主。
1)默认情况下如果一个slave落后master 100M的relay logs的话,即使有权重,也会失效。
2)如果check_repl_delay=0的话,即使落后很多日志,也强制选择其为备选主。

3.2 故障修复步骤:

  • 修复db
/etc/init.d/mysqld start
  • 修复主从
>change master to master_host='192.168.195.130',master_user='myslave',master_password='123',master_log_file='master-bin.000002',master_log_pos=154;
>start slave;
  • 修改配置文件(再把这个记录添加进去,因为它检测掉失效时候会自动消失)
vi /etc/masterha/app1.cnf
[server1]
hostname=192.168.195.129
port=3306
  • 启动manager(在manager那台机器上)
nohup masterha_manager --conf=/etc/masterha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1 &
道阻且长,行则将至!加油! --不是冷漠
原文地址:https://www.cnblogs.com/bushilengmo/p/13854411.html