13-MHA架构安装与配置

环境

192.168.17.141  manager
192.168.17.131  master
192.168.17.132  slave1
192.168.17.134  slave2

所有节点添加hosts

[root@manager ~]# vi /etc/hosts
192.168.17.141  manager
192.168.17.131  master
192.168.17.132  slave1
192.168.17.134  slave2

[root@master ~]# vi /etc/hosts
192.168.17.141  manager
192.168.17.131  master
192.168.17.132  slave1
192.168.17.134  slave2

[root@slave1 ~]# vi /etc/hosts
192.168.17.141  manager
192.168.17.131  master
192.168.17.132  slave1
192.168.17.134  slave2

[root@slave2 ~]# vi /etc/hosts
192.168.17.141  manager
192.168.17.131  master
192.168.17.132  slave1
192.168.17.134  slave2

修改mysql节点配置

[root@master ~]# vi /etc/my.cnf
server-id = 1               # 复制集群中的各节点的id均必须唯一
log-bin = mysql-bin        # 开启二进制日志
relay-log = relay-bin       # 开启中继日志
skip_name_resolve           # 关闭名称解析(非必须)

[root@slave1 ~]# vi /etc/my.cnf
server-id = 2               # 复制集群中的各节点的id均必须唯一;
relay-log = relay-bin       # 开启中继日志
log-bin = mysql-bin        # 开启二进制日志
read_only = ON              # 启用只读属性
relay_log_purge = 0         # 是否自动清空不再需要中继日志
skip_name_resolve           # 关闭名称解析(非必须)
log_slave_updates = 1       # 使得更新的数据写进二进制日志中

[root@slave2 ~]# vi /etc/my.cnf
server-id = 3               # 复制集群中的各节点的id均必须唯一;
relay-log = relay-bin       # 开启中继日志
log-bin = mysql-bin        # 开启二进制日志
read_only = ON              # 启用只读属性
relay_log_purge = 0         # 是否自动清空不再需要中继日志
skip_name_resolve           # 关闭名称解析(非必须)
log_slave_updates = 1       # 使得更新的数据写进二进制日志中

mysql节点上创建复制用户

先在master上创建同步用户

[root@master ~]# mysql -uroot -p000000
mysql> grant replication slave,replication client on *.* to 'mharepl'@'%' identified by '000000';
mysql> flush privileges;
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |      608 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.03 sec)

在slave节点上也创建同步用户

[root@slave1 ~]# mysql -uroot -p000000
mysql> grant replication slave,replication client on *.* to 'mharepl'@'%' identified by '000000';
mysql> flush privileges;

[root@slave2 ~]# mysql -uroot -p000000
mysql> grant replication slave,replication client on *.* to 'mharepl'@'%' identified by '000000';
mysql> flush privileges;

slave节点上配置同步

[root@slave1 ~]# mysql -uroot -p000000
mysql> CHANGE MASTER TO
    ->   MASTER_HOST='192.168.17.131',
    ->   MASTER_USER='mha',
    ->   MASTER_PASSWORD='000000',
    ->   MASTER_PORT=3306,
    ->   MASTER_LOG_FILE='mysql-bin.000003',
    ->   MASTER_LOG_POS=608;
mysql> start slave;
mysql> show slave status\G;

[root@slave2 ~]# mysql -uroot -p000000
mysql> CHANGE MASTER TO
    ->   MASTER_HOST='192.168.17.131',
    ->   MASTER_USER='mha',
    ->   MASTER_PASSWORD='000000',
    ->   MASTER_PORT=3306,
    ->   MASTER_LOG_FILE='mysql-bin.000003',
    ->   MASTER_LOG_POS=608;
mysql> start slave;
mysql> show slave status\G;

在master上进行授权

[root@master ~]# mysql -uroot -p000000
mysql> grant all privileges on *.* to 'mhaadmin'@'%' identified by '000000';
mysql> flush privileges;

准备ssh互通环境

必须保证所有集群都能ssh互通

manager创建公钥并发送到其他主机

[root@manager ~]# ssh-keygen -t rsa
[root@manager ~]# ssh-copy-id -i .ssh/id_rsa.pub root@master
[root@manager ~]# ssh-copy-id -i .ssh/id_rsa.pub root@slave1
[root@manager ~]# ssh-copy-id -i .ssh/id_rsa.pub root@slave2

master创建公钥并发送到其他主机

[root@master ~]# ssh-keygen -t rsa
[root@master ~]# ssh-copy-id -i .ssh/id_rsa.pub root@manager
[root@master ~]# ssh-copy-id -i .ssh/id_rsa.pub root@slave1
[root@master ~]# ssh-copy-id -i .ssh/id_rsa.pub root@slave2

slave1创建公钥并发送到其他主机

[root@slave1 ~]# ssh-keygen -t rsa
[root@slave1 ~]# ssh-copy-id -i .ssh/id_rsa.pub root@manager
[root@slave1 ~]# ssh-copy-id -i .ssh/id_rsa.pub root@master
[root@slave1 ~]# ssh-copy-id -i .ssh/id_rsa.pub root@slave2

slave2创建公钥并发送到其他主机

[root@slave2 ~]# ssh-keygen -t rsa
[root@slave2 ~]# ssh-copy-id -i .ssh/id_rsa.pub root@manager
[root@slave2 ~]# ssh-copy-id -i .ssh/id_rsa.pub root@master
[root@slave2 ~]# ssh-copy-id -i .ssh/id_rsa.pub root@slave1

下载MHA安装包

下载地址

https:# github.com/yoshinorim/mha4mysql-manager/releases
https:# github.com/yoshinorim/mha4mysql-node/releases

所有节点上安装mha4mysql-node

mysql节点上先安装mysql-community-libs-compat

[root@master src]# rpm -ivh mysql-community-libs-compat-5.7.26-1.el7.x86_64.rpm
[root@slave1 src]# rpm -ivh mysql-community-libs-compat-5.7.26-1.el7.x86_64.rpm
[root@slave2 src]# rpm -ivh mysql-community-libs-compat-5.7.26-1.el7.x86_64.rpm

所有节点安装依赖包

yum install -y perl-DBD-MySQL perl-ExtUtils-MakeMaker perl-CPAN
#解压
tar -zxvf mha4mysql-node-0.58.tar.gz
#移动到/usr/local/mha4mysql-node-0.58目录下
mv mha4mysql-node-0.58 /usr/local/mha4mysql-node-0.58
#编译
cd /usr/local/mha4mysql-node-0.58
perl Makefile.PL
#make并安装
make
make install

安装完成后会在/usr/local/bin/生成以下脚本文件,Node脚本说明:
这些工具通常由MHA Manager的脚本触发,无需人为操作

    save_binary_logs               # 保存和复制master的二进制日志
    apply_diff_relay_logs          # 识别差异的中继日志事件并将其差异的事件应用于其他的slave
    filter_mysqlbinlog             # 去除不必要的ROLLBACK事件(MHA已不再使用这个工具)
    purge_relay_logs               # 清除中继日志(不会阻塞SQL线程)

管理节点上安装mha4mysql-manager

#安装依赖包
yum -y install epel-release perl-CPAN* perl-DBD-MySQL  perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager
#解压
tar -zxf mha4mysql-manager-0.58.tar.gz
#移动目录
mv mha4mysql-manager-0.58 /usr/local/mha4mysql-manager-0.58

编译安装

cd /usr/local/mha4mysql-manager-0.58/
perl Makefile.PL
make
make install

安装完成后,在/usr/local/bin会多出以下相关的命令脚本:

    masterha_check_repl       # 检查MySQL复制健康状况
    masterha_check_ssh        # 检查ssh健康状况
    masterha_check_status     # 检测当前MHA运行状态
    masterha_conf_host        # 添加或者删除配置的server信息
    masterha_manager          # 启动MHA
    masterha_master_monitor   # 检测master是否宕机
    masterha_master_switch    # 控制故障转移(自动或者手动)
    masterha_secondary_check  # 如果从manager节点发现
    masterha_stop             # 停止MHA

在/usr/local/mha4mysql-manager-0.58/samples/scripts 目录下会有相关脚本

    master_ip_failover        # 自动切换时vip管理的脚本,不是必须,如果我们使用keepalived的,我们可以自己编写脚本完成对vip的管理,比如监控mysql,如果mysql异常,我们停止keepalived就行,这样vip就会自动漂移
    master_ip_online_change   # 在线切换时vip的管理,不是必须,同样可以可以自行编写简单的shell完成
    power_manager             # 故障发生后关闭主机的脚本,不是必须
    send_report               # 因故障切换后发送报警的脚本,不是必须,可自行编写简单的shell完成

定义MHA管理配置文件

MHA manager有两个配置文件模板,在路径$MHA_BASE/samples/conf/下的app1.cnf和masterha_default.cnf。

app1.cnf  #是对某个复制组的配置文件。
masterha_default.cnf   #MHA manager的全局配置文件,可以通过这一个配置文件管理多个复制组。
[root@manager mha4mysql-manager-0.58]# cp /usr/local/mha4mysql-manager-0.58/samples/conf/app1.cnf /etc/mha/

创建mha管理配置文件

[root@manager src]# mkdir /etc/mha
vi /etc/mha/app1.cnf
[server default]
#mha manager日志文件
manager_log=/usr/local/mha/app1/manager.log
#manager工作目录
manager_workdir=/usr/local/mha/app1
#master节点存放binlog日志路径,以便MHA找到binlog,这里就是MySQL的数据目录
master_binlog_dir=/var/lib/mysql
#发生切换时slave节点binlog日志存放路径
remote_workdir=/usr/local/mha/app1
#自动切换脚本
master_ip_failover_script=/usr/local/mha4mysql-manager-0.58/samples/scripts/master_ip_failover
#手动切换脚本
master_ip_online_change_script=/usr/local/mha4mysql-manager-0.58/samples/scripts/master_ip_online_change
#监控主节点时间间隔
ping_interval=1
#设置故障发生后关闭故障主机脚本(该脚本的主要作用是关闭主机防止发生脑裂,这里没有使用)
#shutdown_script=""
#数据库监控用户
user=mhaadmin
password=000000
#复制用户
repl_user=mha
repl_password=000000
#ssh登录用户
ssh_user=root

[server1]
hostname=192.168.17.131
port=3306

[server2]
#设置为候选master,如果设置该参数以后,发生主从切换以后将会将此从库提升为主库,即使这个主库不是集群中事件最新的slave
candidate_master=1
#默认情况下如果一个slave落后master 100M的relay logs的话,MHA将不会选择该slave作为一个新的master,因为对于这个slave的恢复需要花费很长时间,通过设置check_repl_delay=0,MHA触发切换在选择一个新的master的时候将会忽略复制延时,这个参数对于设置了candidate_master=1的主机非常有用,因为这个候选主在切换的过程中一定是新的master
check_repl_delay=0
hostname=192.168.17.132
port=3306

[server3]
hostname=192.168.17.134
port=3306

创建所需目录

[root@manager src]# mkdir -p /usr/local/mha/app1

对所有个节点进行检测

在manager上检测各节点间ssh互信通信配置是否ok

[root@manager ~]# /usr/local/bin/masterha_check_ssh --conf=/etc/mha/app1.cnf

检查管理的MySQL复制集群的连接配置参数是否OK

[root@manager ~]# /usr/local/bin/masterha_check_repl --conf=/etc/mha/app1.cnf

启动MHA

manager节点上执行以下命令来启动MHA

[root@manager ~]# nohup /usr/local/bin/masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover &> /usr/local/mha/manager.log &

启动成功以后,查看master节点的状态

[root@manager ~]# masterha_check_status --conf=/etc/mha/app1.cnf
mha (pid:18829) is running(0:PING_OK), master:192.168.17.131

停止MHA命令

[root@manager ~]# /usr/local/bin/masterha_stop --conf=/etc/mha/app1.cnf

创建自动清除relay log脚本

MHA在发生切换的过程中,从库的恢复过程中依赖于relay log的相关信息,所以这里要将relay log的自动清除设置为OFF,采用手动清除relay log的方式。在默认情况下,从服务器上的中继日志会在SQL线程执行完毕后被自动删除。但是在MHA环境中,这些中继日志在恢复其他从服务器时可能会被用到,因此需要禁用中继日志的自动删除功能。定期清除中继日志需要考虑到复制延时的问题。在ext3的文件系统下,删除大的文件需要一定的时间,会导致严重的复制延时。为了避免复制延时,需要暂时为中继日志创建硬链接,因为在linux系统中通过硬链接删除大文件速度会很快。(在mysql数据库中,删除大表时,通常也采用建立硬链接的方式)

MHA节点中包含了pure_relay_logs命令工具,它可以为中继日志创建硬链接,执行SET GLOBAL relay_log_purge=1,等待几秒钟以便SQL线程切换到新的中继日志,再执行SET GLOBAL relay_log_purge=0。

清理日志脚本:

[root@manager ~]# vi /usr/local/mha/purge_relay_log.sh
#!/bin/bash
#数据库用户名密码端口
user=root
passwd=000000
port=3306
#脚本日志存放路径
log_dir='/usr/local/mha/app1'
#指定创建relay log的硬链接的位置,默认是/var/tmp。由于系统不同分区创建硬链接文件会失败,故需要执行硬链接具体位置,成功执行脚本后,硬链接的中继日志文件被删除。
work_dir='/usr/local/mha'
#删除中继日志脚本
purge='/usr/local/bin/purge_relay_logs'

if [ ! -d $log_dir ]
then
   mkdir -p $log_dir
fi

#--disable_relay_log_purge :默认情况下,如果relay_log_purge=1,脚本会什么都不清理,自动退出。通过设定这个参数,当relay_log_purge=1的情况下会将relay_log_purge设置为0。清理relay log之后,最后将参数设置为OFF。
$purge --user=$user --password=$passwd --disable_relay_log_purge --port=$port --workdir=$work_dir >> $log_dir/purge_relay_logs.log 2>&1

授予可执行权限

[root@manager ~]# chmod +x purge_relay_log.sh 

添加至定时任务

00 03 * * * /bin/bash /usr/local/mha/purge_relay_log.sh

2种配置VIP的方式

使用keepalived配置VIP

keepalived安装略

在master和candidate master上安装,即在master、slave1上安装.

master的keepalived.conf

! Configuration File for keepalived

global_defs {
   router_id master
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 100
    nopreempt
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 000000
    }
    virtual_ipaddress {
        192.168.17.130
    }
}

slave1的keepalived.conf

! Configuration File for keepalived

global_defs {
   router_id slave1
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 90
    nopreempt
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 000000
    }
    virtual_ipaddress {
        192.168.17.130
    }
}

MHA引入keepalived

MySQL服务进程挂掉时通过MHA停止keepalived,需要修改切换是触发的脚本文件master_ip_failover即可,在该脚本中添加在master发生宕机时对keepalived的处理。

[root@manager scripts]# vi /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.17.130";
my $ssh_start_vip = "systemctl start keepalived";
my $ssh_stop_vip = "systemctl stop keepalived";

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";
}

使用脚本引入VIP

通过脚本的方式管理VIP。这里是修改/usr/local/bin/master_ip_failover。修改完成后内容如下,而且如果使用脚本管理vip的话,需要手动在master服务器上绑定一个vip。

/sbin/ifconfig ens160:1 10.238.162.100/24

通过脚本引入VIP的实验不在演示,我自己做了自动切换的实验是可以的。大家可以自己做做实验看看日志输出理解原理。脚本如下供参考,需要根据自己环境修改VIP与网卡等信息

    # cat 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.238.162.100/24';
    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";
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值