MySQL8.0 高可用方案之MHA

MHA简介

MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,由日本DeNA公司youshimaton(现就职于Facebook公司)开发,是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件。

在MySQL故障切换过程中,MHA能做到在0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA能在最大程度上保证数据的一致 性,以达到真正意义上的高可用。

MHA是构建MySQL高可用架构的一种选择方案

该软件由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。

MHA Manager

  • MHA Manager可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署在一台slave节点上。MHA Node运行在每台MySQL服务器上,MHA Manager会定时探测集群中的master节点,当master出现故障时,它可以自动将最新数据的slave提升为新的master,然后将所有其他的slave重新指向新的master。

MHA Node

  • MHA Node 部署在所有运行MySQL的服务器上,无论是master还是slave。主要作用有三个。

故障转移过程

  • 在MHA自动故障切换过程中,MHA试图从宕机的主服务器上最大限度的保存二进制日志,最大程度的保证数据的不丢失,但这并不总是可行的。例如,主服务器硬件故障或无法通过ssh访问,MHA没法保存二进制日志,只进行故障转移而丢失了最新的数据。

MHA的工作原理

  1. 从宕机崩溃的master保存二进制日志事件(binlog events)
  2. 识别含有最新更新的slave
  3. 应用差异的中继日志(relay log)到其他的slave
  4. 应用从master保存的二进制日志事件(binlog events)
  5. 提升一个slave为新的master
  6. 使其他的slave连接新的master进行主从复制

环境准备

测试环境:
这个根据自己的资源而定,一般使用一主2从就可以了
已经提前搭好主从复制架构,如有安装问题,可以参考MYSQL8.0主从复制

操作系统:centos7
mysql版本:mysql 8.0.31
mha版本:0.58

IP Role
10.10.64.151 Master , MHA Manager
10.10.64.152 Slave , MHA Node
10.10.64.153 Slave , MHA Node
10.10.64.154 Slave , MHA Node
10.10.64.155 Slave , MHA Node
10.10.64.156 Slave , MHA Node
10.10.64.157 Slave , MHA Node
10.10.64.158 Slave , MHA Node

配置ssh密钥登入各个机器使得相互之间可以免密登录
部署节点安装ansible及准备ssh免密登陆
所有机器都要执行

[root@localhost ~]# yum install -y ansible
#生成密钥
[root@localhost ~]# ssh-keygen
#安装sshpass工具
[root@localhost ~]# yum install -y sshpass
[root@localhost ~]# vi ssh-copy-key.sh 
#!/bin/bash
IP="
10.10.64.151
10.10.64.152
10.10.64.153
10.10.64.154
10.10.64.155
10.10.64.156
10.10.64.157
10.10.64.158
"

for node in ${IP};
do
  sshpass -p 123456 ssh-copy-id  ${node} -o StrictHostKeyChecking=no
  if [ $? -eq 0 ];then
    echo "${node} 秘钥copy完成"
  else
    echo "${node} 秘钥copy失败"
  fi
done
[root@localhost ~]# bash ssh-copy-key.sh 

安装及配置MHA

下载地址:
https://github.com/yoshinorim/mha4mysql-node/releases/tag/v0.58
在所有数据库执行,因为每个机器都有可能使master

#修改配置文件,开启GTID
[root@localhost ~]# vi /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log_bin=/var/lib/mysql/logs/mysql-bin-1.log
relay_log=/var/lib/mysql/logs/mysql-relay-bin
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
server-id=1
binlog_format=row
slave_exec_mode=IDEMPOTEN
explicit_defaults_for_timestamp=true
max_allowed_packet = 200M
#Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
default_authentication_plugin=mysql_native_password
#开启GTID
gtid_mode=ON
enforce_gtid_consistency=ON
character-set-server = utf8
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8

#登录
[root@localhost ~]# mysql -uroot -p
Enter password: 
mysql> create user 'repl'@'%' identified with mysql_native_password by '123456';
Query OK, 0 rows affected (0.01 sec)

mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
Query OK, 0 rows affected (0.00 sec)
#创建mha用户
mysql> create user 'mha'@'%' identified with mysql_native_password by '123456';
Query OK, 0 rows affected (0.01 sec)

mysql> grant all privileges on *.* to 'mha'@'%';
Query OK, 0 rows affected (0.01 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)

所有服务器都需要安装依赖包

[root@localhost ~]# yum -y install epel-release
[root@localhost ~]# yum -y install perl-DBD-MySQL perl-DBI ncftp

安装mha:
所有服务器都需要安装

[root@localhost ~]# wget https://qiniu.wsfnk.com/mha4mysql-node-0.58-0.el7.centos.noarch.rpm
[root@localhost ~]# rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm

安装mha监控manager,只需要在manager节点上面安装

[root@localhost ~]# yum -y install epel-release
#安装依赖
[root@localhost ~]# yum -y install perl-Config-Tiny perl-Time-HiRes perl-Parallel-ForkManager perl-Log-Dispatch perl-DBD-MySQL ncftp
#安装manager
[root@localhost ~]# wget https://qiniu.wsfnk.com/mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
[root@localhost ~]# rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm

在manager管理机器上配置管理节点

[root@localhost ~]# mkdir /etc/mha
[root@localhost ~]# mkdir /home/mysql_mha
[root@localhost ~]# vim /etc/mha/mysql_mha.cnf
[server default]
#mha访问数据库的账号与密码
user=mha
password=123456
#指定mha的工作目录
manager_workdir=/home/mysql_mha
#指定管理日志路径
manager_log=/home/mysql_mha/manager.log
#指定mha在远程节点上的工作目录
remote_workdir=/home/mysql_mha
#可以使用ssh登入的用户
ssh_user=root
ssh_port=22
#指定主从复制的mysq用户和密码
repl_user=repl
repl_password=123456
#指定检测间隔时间
ping_interval=1
#指定master节点存放binlog的日志文件的目录
master_binlog_dir=/var/lib/mysql/logs
#指定一个脚本,该脚本实现了在主从切换之后,将虚拟ip漂移到新的master上
master_ip_failover_script=/usr/bin/master_ip_failover
#指定用于二次检查节点状态的节点
secondary_check_script=/usr/bin/masterha_secondary_check -s 10.10.64.151 -s 10.10.64.152 -s 10.10.64.153 -s 10.10.64.154 -s 10.10.64.155 -s 10.10.64.156 -s 10.10.64.157 -s 10.10.64.158
#配置集群中的节点
[server1]
hostname=10.10.64.151
#指定该节点可以参与master选举
candidate_master=1

[server2]
hostname=10.10.64.152
candidate_master=1

[server3]
hostname=10.10.64.153
#指定该节点不参与master选举
no_master=1

[server4]
hostname=10.10.64.154
#指定该节点不参与master选举
no_master=1

[server5]
hostname=10.10.64.155
#指定该节点不参与master选举
candidate_master=1

[server6]
hostname=10.10.64.156
#指定该节点不参与master选举
candidate_master=1

[server7]
hostname=10.10.64.157
#指定该节点不参与master选举
no_master=1

[server8]
hostname=10.10.64.158
#指定该节点不参与master选举
no_master=1

编写配置文件中的/usr/bin/master_ip_failover脚本

[root@localhost ~]# vim /usr/bin/master_ip_failover
#!/usr/bin/env perl

use strict;
use warnings FATAL => 'all';

use Getopt::Long;

my (
    $command, $orig_master_host, $orig_master_ip,$ssh_user,
    $orig_master_port, $new_master_host, $new_master_ip,$new_master_port,
    $orig_master_ssh_port,$new_master_ssh_port,$new_master_user,$new_master_password
);

# 这里定义的虚拟IP可以根据实际情况进行修改
my $vip = '10.10.64.175/24';
my $key = '1';
# 这里的网卡名称 “ens192” 需要根据你机器的网卡名称进行修改
my $ssh_start_vip = "sudo /sbin/ifconfig ens192:$key $vip";
my $ssh_stop_vip = "sudo /sbin/ifconfig ens192:$key down";
my $ssh_Bcast_arp= "sudo /sbin/arping -I bond0 -c 3 -A $vip";

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,
    'orig_master_ssh_port=i' => \$orig_master_ssh_port,
    'new_master_host=s'  => \$new_master_host,
    'new_master_ip=s'    => \$new_master_ip,
    'new_master_port=i'  => \$new_master_port,
    'new_master_ssh_port' => \$new_master_ssh_port,
    'new_master_user' => \$new_master_user,
    'new_master_password' => \$new_master_password

);

exit &main();

sub main {
    $ssh_user = defined $ssh_user ? $ssh_user : 'root';
    print "\n\nIN SCRIPT TEST====$ssh_user|$ssh_stop_vip==$ssh_user|$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();
        &start_arp();
            $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() {
    `ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}

sub start_arp() {
    `ssh $ssh_user\@$new_master_host \" $ssh_Bcast_arp \"`;
}
sub usage {
    print
    "Usage: master_ip_failover --command=start|stop|stopssh|status --ssh_user=user --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";
}

给脚本添加可执行权限

chmod a+x /usr/bin/master_ip_failover

在其他所有节点上创建mha的工作目录

mkdir /home/mysql_mha

在manager进行检测工作,检测ssh免密和mysql主从同步

#检测ssh免密
[root@localhost ~]# masterha_check_ssh --conf=/etc/mha/mysql_mha.cnf
#检测mysql主从同步
[root@localhost ~]# masterha_check_repl --conf=/etc/mha/mysql_mha.cnf

MySQL8.0 高可用方案之MHA_第1张图片
出现MySQL Replication Health is OK,证明mysql 主从同步 OK !!!
MySQL8.0 高可用方案之MHA_第2张图片
出现All SSH connection tests passed successfully,证明ssh免密 OK !!!

检测没有报错,在manager上启动MHA

nohup masterha_manager --conf=/etc/mha/mysql_mha.cnf >/dev/null 2>/dev/null &

检测有没有运行

[root@localhost ~]# ps -ef|grep mha
root      6879  3531  0 16:27 pts/0    00:00:00 perl /usr/bin/masterha_manager --conf=/etc/mha/mysql_mha.cnf
root      6939  3531  0 16:28 pts/0    00:00:00 grep --color=auto mha
[root@localhost ~]#  masterha_check_status --conf=/etc/mha/mysql_mha.cnf 
mysql_mha (pid:26963) is running(0:PING_OK), master:10.10.64.151

第一次启动的时候,需要给master机器设置vip:

ifconfig ens192:1 10.10.64.175/24  #绑定VIP
ifconfig ens192:1 del 10.10.64.175/24  #删除VIP

测试MHA服务

使用VIP地址和mha账号进行登录

mysql -umha -h 10.10.64.175 -p -e "show variables like 'server_id'"

查看日志信息

[root@mysql1 mysql_mha]# tail -f /home/mysql_mha/manager.log
Invalidated master IP address on 10.10.64.151(10.10.64.151:3306)
The latest slave 10.10.64.152(10.10.64.152:3306) has all relay logs for recovery.
Selected 10.10.64.152(10.10.64.152:3306) as a new master.
10.10.64.152(10.10.64.152:3306): OK: Applying all logs succeeded.
10.10.64.152(10.10.64.152:3306): OK: Activated master IP address.
10.10.64.153(10.10.64.153:3306): This host has the latest relay log events.
Generating relay diff files from the latest slave succeeded.
10.10.64.153(10.10.64.153:3306): OK: Applying all logs succeeded. Slave started, replicating from 10.10.64.152(10.10.64.152:3306)
10.10.64.152(10.10.64.152:3306): Resetting slave info succeeded.
Master failover to 10.10.64.152(10.10.64.152:3306) completed successfully.

你可能感兴趣的:(mysql,mysql,数据库,服务器)