MySQL高可用之MHA的搭建

来源:互联网 发布:电力数据库 编辑:程序博客网 时间:2024/04/29 17:04

                     MySQL高可用之MHA的搭建

1.介绍

MySQL MHA架构介绍:

MHAMaster 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自动故障切换过程中,MHA试图从宕机的主服务器上保存二进制日志,最大程度的保证数据的不丢失,但这并不总是可行的。例如,如果主服务器硬件故障或无法通过ssh访问,MHA没法保存二进制日志,只进行故障转移而丢失了最新的数据。使用MySQL 5.5的半同步复制,可以大大降低数据丢失的风险。MHA可以与半同步复制结合起来。如果只有一个slave已经收到了最新的二进制日志,MHA可以将最新的二进制日志应用于其他所有的slave服务器上,因此可以保证所有节点的数据一致性。

 

目前MHA主要支持一主多从的架构,要搭建MHA,要求一个复制集群中必须最少有三台数据库服务器,一主二从,即一台充当master,一台充当备用master,另外一台充当从库,因为至少需要三台服务器,出于机器成本的考虑,淘宝也在该基础上进行了改造,目前淘宝TMHA已经支持一主一从。

 

2.实验环境:

RHEL6.5 系列 selinux and iptables disabled

实验主机:

Master:server1-172.25.4.1

Slave1(备用master):server4-172.25.4.4

Slave2:server3-172.25.4.3

Managerserver2-172.25.4.2

 

 

3.部署MHA

1)在所有节点安装MHA node所需的perl模块

yum install perl-DBD-MySQL -y

(2)在所有的节点安装mha node

yum install mha4mysql-node-0.56-0.el6.noarch.rpm -y

如果是源码安装

tar zxf mha4mysql-node-0.56.tar.gz

cd mha4mysql-node-0.56

perl Makefile.PL

make && make install

 

4.安装MHA Manager

1)安装MHA Manager软件包之前需要安装依赖。注意:在MHA Manager的主机也是需要安装MHA Node

 

yum install perl-* -y

 

2)安装MHA Manager

yum install mha4mysql-manager-0.56-0.el6.noarch.rpm -y

##mha manager 安装完成后会在/usr/bin 下面生成一些脚本:  

/usr/bin/masterha_check_repl         ##检查mysql复制状况  

/usr/bin/masterha_check_ssh         ##检查MHAssh配置状况  

/usr/bin/masterha_check_status       ##检测当前MHA运行状态  

/usr/bin/masterha_conf_host          ##添加或删除配置的server信息  

/usr/bin/masterha_manager           ##启动MHA  

/usr/bin/masterha_master_monitor    ##监测master是否宕机  

/usr/bin/masterha_master_switch     ##控制故障转移(自动或手动)  

/usr/bin/masterha_secondary_check  ##也是监测master是否宕机的脚本  

/usr/bin/masterha_stop               ##关闭MHA 

 

 

5.配置SSH登录无密码验证(使用key登录,工作中常用,最好不要禁掉密码登录,如果禁了,可能会有问题)

Manager

ssh-keygen  -t rsa

ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.25.4.1

ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.25.4.3

ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.25.4.4

然后在managerssh root@172.25.4.1不需要密码

其他每个服务器都需要配置

 

或者用下面这种办法快速同步

Shh-copy-id server2

Ssh-copy-id server1

Ssh-copy-id server4

Ssh-copy-id server3

Cd /root/.ssh

rsync  * -p server1:/root/.ssh   ##数据同步

rsync  * -p server4:/root/.ssh

rsync  * -p server3:/root/.ssh

6.搭建主从复制环境

注意:binlog-do-db 和 replicate-ignore-db 设置必须相同。 MHA 在启动时候会检测过滤规则,如果过滤规则不同,MHA 不启动监控和故障转移。

 

(1)在主master上执行备份

mysqldump --master-data=2 --single-transaction -R --triggers -A > all.sql

其中--master-data=2代表备份时刻记录masterBinlog位置和Position--single-transaction意思是获取一致性快照,-R意思是备份存储过程和函数,--triggres的意思是备份触发器,-A代表备份所有的库。更多信息请自行mysqldump --help查看。

2)在master和备master上创建同步用户,并给予权限

mysql -p

mysql>grant replication slave on *.* to test@'172.25.4.%' identified by 'Syx.123456';        #授予从机对test库有复制的权限

mysql>Flush privileges;    刷新数据使其生效

(3)查看主库备份时的binlog名称和位置,MASTER_LOG_FILEMASTER_LOG_POS

 head -n 30 all.sql | grep 'CHANGE MASTER TO'

(4)把备份复制到两个slave

Scp all.sql server3:

Scp all.sql server4:

(5)在两个slave上导入备份,执行复制相关命令

Mysql < all.sql

mysql> CHANGE MASTER TO MASTER_HOST='172.25.4.1',MASTER_USER='test', MASTER_PASSWORD='Syx.123456',MASTER_LOG_FILE='mysql-bin.000010',MASTER_LOG_POS=112;

查看复制状态(可以看见复制成功):

 mysql -pSyx.123456 -e 'show slave status\G' | grep 'Slave_IO|Slave_SQL'

Slave_IO_State: Waiting for master to send event

             Slave_IO_Running: Yes

            Slave_SQL_Running: Yes

(6)两台slave服务器设置read_only(从库对外提供读服务,只所以没有写进配置文件,是因为随时slave会提升为master

 mysql -pSyx.123456 -e 'set global read_only=1'

 

7)在主master和备master上创建监控用户

mysql -pSyx.123456

mysql> grant all privileges on *.* to 'root'@'172.25.4.%' identified by 'Syx.123456';

mysql> flush  privileges;

 

到这里整个集群环境已经搭建完毕,剩下的就是配置MHA软件了。

 

6.配置MHA(在manager

(1)创建MHA的工作目录,并且创建相关配置文件(在软件包解压后的目录里面有样例配置文件)。

mkdir -p /etc/masterha

vim /etc/masterha/app.cnf

[server default]

manager_workdir=/etc/masterha       //设置manager的工作目录

manager_log=/etc/masterha/mha.log  //设置manager的日志

master_binlog_dir=/var/lib/mysql       //设置master 保存binlog的位置,以便MHA可以找到master的日志,我这里的也就是mysql的数据目录

master_ip_failover_script=/etc/masterha/master_ip_failover   //设置自动failover时候的切换脚本

master_ip_online_change_script= /etc/masterha/master_ip_online_change  //设置手动切换时候的切换脚本

password=Syx.123456                  //设置mysqlroot用户的密码,这个密码是前文中创建监控用户的那个密码

user=root                              //设置监控用户root

ping_interval=1                        //设置监控主库,发送ping包的时间间隔,默认是3秒,尝试三次没有回应的时候自动进行railover

remote_workdir=/tmp                 //设置远端mysql在发生切换时binlog的保存位置

repl_password=Syx.123456          //设置复制用户的密码

repl_user=test                       //设置复制环境中的复制用户名

#report_script=/usr/local/send_report  //设置发生切换后发送的报警的脚本

secondary_check_script=/usr/bin/masterha_secondary_check -s 172.25.4.1 -s 172.25.4.4

#shutdown_script=""                //设置故障发生后关闭故障主机脚本(该脚本的主要作用是关闭主机放在发生脑裂,这里没有使用)

ssh_user=root                    //设置ssh的登录用户名

 

[server1]

hostname=172.25.4.4

port=3306

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

check_repl_delay=0  //默认情况下如果一个slave落后master 100Mrelay logs的话,MHA将不会选择该slave作为一个新的master,因为对于这个slave的恢复需要花费很长时间,通过设置check_repl_delay=0,MHA触发切换在选择一个新的master的时候将会忽略复制延时,这个参数对于设置了candidate_master=1的主机非常有用,因为这个候选主在切换的过程中一定是新的master

 

[server2]

hostname=172.25.4.1

port=3306

#candidate_master=1

#check_repl_delay=0

 

[server3]

hostname=172.25.4.3

no_master=1

port=3306

(2)设置relay log的清除方式(在每个slave节点上):

mysql -pSyx.123456 -e "set global relay_log_purge=0"

 

(3)设置定期清理relay脚本(两台slave服务器)

vim purge_relay_log.sh

#!/bin/bash

user=root

passwd=Syx.123456

port=3306

log_dir='/data/masterha/log'

work_dir='/data'

purge='/usr/local/bin/purge_relay_logs'

 

if [ ! -d $log_dir ]

then

   mkdir $log_dir -p

fi

 

$purge --user=$user --password=$passwd --disable_relay_log_purge --port=$port --workdir=$work_dir >> $log_dir/purge_relay_logs.log 2>&1

 

添加到crontab定期执行

Croontab -e

0 4 * * * /bin/bash /root/purge_relay_log.sh

 

purge_relay_logs脚本删除中继日志不会阻塞SQL线程。下面我们手动执行看看什么情况。

 

purge_relay_logs --user=root --password=Syx.123456 --port=3306 -disable_relay_log_purge --workdir=/data/

2017-08-05 03:19:33: purge_relay_logs script started.

 Found relay_log.info: /var/lib/mysql/relay-log.info

 Opening /var/lib/mysql/server3-relay-bin.000007 ..

 Opening /var/lib/mysql/server3-relay-bin.000008 ..

 Executing SET GLOBAL relay_log_purge=1; FLUSH LOGS; sleeping a few seconds so that SQL thread can delete older relay log files (if it keeps up); SET GLOBAL relay_log_purge=0; .. ok.

2017-08-05 03:19:36: All relay log purging operations succeeded.

 

8.检查SSH配置

检查MHA Manger到所有MHA NodeSSH连接状态:

Manager

masterha_check_ssh --conf=/etc/masterha/app.cnf

Sat Aug  5 01:53:08 2017 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.

Sat Aug  5 01:53:08 2017 - [info] Reading application default configuration from /etc/masterha/app.cnf..

Sat Aug  5 01:53:08 2017 - [info] Reading server configuration from /etc/masterha/app.cnf..

Sat Aug  5 01:53:08 2017 - [info] Starting SSH connection tests..

Sat Aug  5 01:53:10 2017 - [debug] 

Sat Aug  5 01:53:09 2017 - [debug]  Connecting via SSH from root@172.25.4.1(172.25.4.1:22) to root@172.25.4.4(172.25.4.4:22)..

Sat Aug  5 01:53:09 2017 - [debug]   ok.

Sat Aug  5 01:53:09 2017 - [debug]  Connecting via SSH from root@172.25.4.1(172.25.4.1:22) to root@172.25.4.3(172.25.4.3:22)..

Sat Aug  5 01:53:09 2017 - [debug]   ok.

Sat Aug  5 01:53:10 2017 - [debug] 

Sat Aug  5 01:53:09 2017 - [debug]  Connecting via SSH from root@172.25.4.4(172.25.4.4:22) to root@172.25.4.1(172.25.4.1:22)..

Sat Aug  5 01:53:09 2017 - [debug]   ok.

Sat Aug  5 01:53:09 2017 - [debug]  Connecting via SSH from root@172.25.4.4(172.25.4.4:22) to root@172.25.4.3(172.25.4.3:22)..

Sat Aug  5 01:53:10 2017 - [debug]   ok.

Sat Aug  5 01:53:10 2017 - [debug] 

Sat Aug  5 01:53:10 2017 - [debug]  Connecting via SSH from root@172.25.4.3(172.25.4.3:22) to root@172.25.4.1(172.25.4.1:22)..

Sat Aug  5 01:53:10 2017 - [debug]   ok.

Sat Aug  5 01:53:10 2017 - [debug]  Connecting via SSH from root@172.25.4.3(172.25.4.3:22) to root@172.25.4.4(172.25.4.4:22)..

Sat Aug  5 01:53:10 2017 - [debug]   ok.

Sat Aug  5 01:53:10 2017 - [info] All SSH connection tests passed successfully.

如果不是OK,证明你app.cnf配置文件内容有问题

 

 

9.检查整个复制环境状况

通过masterha_check_repl脚本查看整个集群的状态

masterha_check_repl --conf=/etc/masterha/app.cnf

 

MySQL Replication Health is OK.

 

如果是MySQL Replication Health is NOT OK!

就去app.cnf文件中#master_ip_failover_script=/etc/masterha/master_ip_failover

注释起来

 

10.检查MHA Manager的状态

通过master_check_status脚本查看Manager的状态:

masterha_check_status --conf=/etc/masterha/app.cnf

app is stopped(2:NOT_RUNNING).

注意:如果正常,会显示"PING_OK",否则会显示"NOT_RUNNING",这代表MHA监控没有开启。

 

10.开启MHA Manager监控

nohup masterha_manager --conf=/etc/masterha/app.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /etc/masterha/mha.log 2>&1 & 

[1] 2066

 

启动参数介绍:

--remove_dead_master_conf      该参数代表当发生主从切换后,老的主库的ip将会从配置文件中移除。

--manger_log                            日志存放位置

--ignore_last_failover                 在缺省情况下,如果MHA检测到连续发生宕机,且两次宕机间隔不足8小时的话,则不会进行Failover,之所以这样限制是为了避免ping-pong效应。该参数代表忽略上次MHA触发切换产生的文件,默认情况下,MHA发生切换后会在日志目录,也就是上面我设置的/data产生app1.failover.complete文件,下次再次切换的时候如果发现该目录下存在该文件将不允许触发切换,除非在第一次切换后收到删除该文件,为了方便,这里设置为--ignore_last_failover

 

再次查看MHA Manager监控是否正常:

 masterha_check_status --conf=/etc/masterha/app.cnfapp (pid:2066) is running(0:PING_OK), master:172.25.4.1

可以看见已经在监控了,而且master的主机为172.25.4.1

 

11.查看启动日志

tail -n20 /etc/masterha/mha.log 

 

其中"Ping(SELECT) succeeded, waiting until MySQL doesn't respond.."说明整个系统已经开始监控了。

 

 

 

12.关闭MHA Manage监控

关闭很简单,使用masterha_stop命令完成。

masterha_stop --conf=/etc/masterha/app.cnf

Stopped app successfully.

[1]+  Exit 1                  nohup masterha_manager --conf=/etc/masterha/app.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /etc/masterha/mha.log 2>&1

 

 

13.配置vip

MHA Manager修改脚本修改/etc/masterha/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 = '172.25.4.100/24';

my $ssh_start_vip = "/sbin/ip addr add $vip dev eth0";

my $ssh_stop_vip = "/sbin/ip addr del $vip dev eth0";

 

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

}

 

然后我们在去

vim /etc/masterha/app.cnf

master_ip_failover_script=/etc/masterha/master_ip_failover

把这一行的注释打开

我们现在打开在上面提到过的参数,再检查集群状态,看是否会报错。

masterha_check_repl --conf=/etc/masterha/app.cnf

 

MySQL Replication Health is OK.

可以看见已经没有报错了。

/etc/masterha/master_ip_failover添加或者修改的内容意思是当主库数据库发生故障时,会触发MHA切换

 

如果我们通过脚本的方式管理vip,就需要去master上手动绑定一个vip

/sbin/ip addr add 172.25.4.100 dev eth0

 

14.测试:

为了防止脑裂发生,推荐生产环境采用脚本的方式来管理虚拟ip,而不是使用keepalived来完成。到此为止,基本MHA集群已经配置完毕。接下来就是实际的测试环节了。通过一些测试来看一下MHA到底是如何进行工作的。下面将从MHA自动failover,我们手动failover,在线切换三种方式来介绍MHA的工作情况。

(1)自动Failover(必须先启动MHA Manager,否则无法自动切换,当然手动切换不需要开启MHA Manager监控。)

2)杀掉主库mysql进程,模拟主库发生故障,进行自动failover操作。 

/etc/init.d/mysqld stop

Stopping mysqld:                                  [  OK  ]

mysql> show slave status\G;

Master_Host: 172.25.4.4

Master已经切换到备主master server4-172.25.4.4上了

在去172.25.4.4上查看vip也已经切换过来了

3)在manager上查看MHA切换日志,了解整个切换过程。

然后去看slave2

看到最后的Master failover to 172.25.4.4(172.25.4.4:3306) completed successfully.说明备选master现在已经上位了。

 

从上面的输出可以看出整个MHA的切换过程,共包括以下的步骤:

1.配置文件检查阶段,这个阶段会检查整个集群配置文件配置

2.宕机的master处理,这个阶段包括虚拟ip摘除操作,主机关机操作(这个我这里还没有实现,需要研究)

3.复制dead maste和最新slave相差的relay log,并保存到MHA Manger具体的目录下

4.识别含有最新更新的slave

5.应用从master保存的二进制日志事件(binlog events

6.提升一个slave为新的master进行复制

7.使其他的slave连接新的master进行复制

 

最后启动MHA Manger监控,查看集群里面现在谁是master(在切换后监控就停止了,需要手动重新打开)

 

(2)手动FailoverMHA Manager必须没有运行)

手动failover,这种场景意味着在业务上没有启用MHA自动切换功能,当主服务器故障时,人工手动调用MHA来进行故障切换操作,具体命令如下:

注意:如果,MHA manager检测到没有deadserver,将报错,并结束failover

[info] Dead Servers:

[error][/usr/local/share/perl5/MHA/MasterFailover.pm, ln181] None of server is dead. Stop failover.

[error][/usr/local/share/perl5/MHA/ManagerUtil.pm, ln178] Got ERROR:  at /usr/local/bin/masterha_master_switch line 53

 

进行手动切换命令如下:

masterha_master_switch --master_state=dead --conf=/etc/masterha/app.cnf --dead_master_host=172.25.4.1 --dead_master_port=3306 --new_master_host=172.25.4.4 --new_master_port=3306 --ignore_last_failover

输出的信息会询问你是否进行切换

上述模拟了master宕机的情况下手动把172.25.4.4提升为主库的操作过程。

 

(3)在线进行切换

在许多情况下, 需要将现有的主服务器迁移到另外一台服务器上。 比如主服务器硬件故障,RAID 控制卡需要重建,将主服务器移到性能更好的服务器上等等。维护主服务器引起性能下降, 导致停机时间至少无法写入数据。 另外, 阻塞或杀掉当前运行的会话会导致主主之间数据不一致的问题发生。 MHA 提供快速切换和优雅的阻塞写入,这个切换过程只需要 0.5-2s 的时间,这段时间内数据是无法写入的。在很多情况下,0.5-2s 的阻塞写入是可以接受的。因此切换主服务器不需要计划分配维护时间窗口。

 

MHA在线切换的大概过程:

1.检测复制设置和确定当前主服务器

2.确定新的主服务器

3.阻塞写入到当前主服务器

4.等待所有从服务器赶上复制

5.授予写入到新的主服务器

6.重新设置从服务器 

 

注意,在线切换的时候应用架构需要考虑以下两个问题:

1.自动识别masterslave的问题(master的机器可能会切换),如果采用了vip的方式,基本可以解决这个问题。

2.负载均衡的问题(可以定义大概的读写比例,每台机器可承担的负载比例,当有机器离开集群时,需要考虑这个问题)

 

为了保证数据完全一致性,在最快的时间内完成切换,MHA的在线切换必须满足以下条件才会切换成功,否则会切换失败。

1.所有slaveIO线程都在运行

2.所有slaveSQL线程都在运行

3.所有的show slave status的输出中Seconds_Behind_Master参数小于或者等于running_updates_limit秒,如果在切换过程中不指定running_updates_limit,那么默认情况下running_updates_limit1秒。

4.master端,通过show processlist输出,没有一个更新花费的时间大于running_updates_limit秒。

 

在线切换步骤如下:

首先,停掉MHA监控:

masterha_stop --conf=/etc/masterha/app.cnf

其次,进行在线切换操作(模拟在线切换主库操作,原主库172.25.4.1变为slave172.25.4.4提升为新的主库)

masterha_master_switch --conf=/etc/masterha/app1.cnf --master_state=alive --new_master_host=172.25.4.4 --new_master_port=3306 --orig_master_is_new_slave --running_updates_limit=10000

最后查看日志,了解切换过程,输出信息如下:

其中参数的意思:

--orig_master_is_new_slave 切换时加上此参数是将原 master 变为 slave 节点,如果不加此参数,原来的 master 将不启动

--running_updates_limit=10000,故障切换时,候选master 如果有延迟的话, mha 切换不能成功,加上此参数表示延迟在此时间范围内都可切换(单位为s),但是切换的时间长短是由recover relay 日志的大小决定 

 

注意:由于在线进行切换需要调用到master_ip_online_change这个脚本,脚本如下:

#!/usr/bin/env perl

use strict;  

use warnings FATAL =>'all';  

  

use Getopt::Long;  

  

my $vip = '172.25.4.100/24';  # Virtual IP   

my $ssh_start_vip = "/sbin/ip addr add $vip dev eth0";  

my $ssh_stop_vip = "/sbin/ip addr del $vip dev eth0";  

my $exit_code = 0;  

  

my (  

  $command,              $orig_master_is_new_slave, $orig_master_host,  

  $orig_master_ip,       $orig_master_port,         $orig_master_user,  

  $orig_master_password, $orig_master_ssh_user,     $new_master_host,  

  $new_master_ip,        $new_master_port,          $new_master_user,  

  $new_master_password,  $new_master_ssh_user,  

);  

GetOptions(  

  'command=s'                => \$command,  

  'orig_master_is_new_slave' => \$orig_master_is_new_slave,  

  'orig_master_host=s'       => \$orig_master_host,  

  'orig_master_ip=s'         => \$orig_master_ip,  

  'orig_master_port=i'       => \$orig_master_port,  

  'orig_master_user=s'       => \$orig_master_user,  

  'orig_master_password=s'   => \$orig_master_password,  

  'orig_master_ssh_user=s'   => \$orig_master_ssh_user,  

  'new_master_host=s'        => \$new_master_host,  

  'new_master_ip=s'          => \$new_master_ip,  

  'new_master_port=i'        => \$new_master_port,  

  'new_master_user=s'        => \$new_master_user,  

  'new_master_password=s'    => \$new_master_password,  

  'new_master_ssh_user=s'    => \$new_master_ssh_user,  

);  

  

  

exit &main();  

  

sub main {  

  

#print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";  

  

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

  

        # $orig_master_host, $orig_master_ip, $orig_master_port are passed.  

        # If you manage master ip address at global catalog database,  

        # invalidate orig_master_ip here.  

        my $exit_code = 1;  

        eval {  

            print "\n\n\n***************************************************************\n";  

            print "Disabling the VIP - $vip on old master: $orig_master_host\n";  

            print "***************************************************************\n\n\n\n";  

&stop_vip();  

            $exit_code = 0;  

        };  

        if ($@) {  

            warn "Got Error: $@\n";  

            exit $exit_code;  

        }  

        exit $exit_code;  

}  

elsif ( $command eq "start" ) {  

  

        # all arguments are passed.  

        # If you manage master ip address at global catalog database,  

        # activate new_master_ip here.  

        # You can also grant write access (create user, set read_only=0, etc) here.  

my $exit_code = 10;  

        eval {  

            print "\n\n\n***************************************************************\n";  

            print "Enabling the VIP - $vip on new master: $new_master_host \n";  

            print "***************************************************************\n\n\n\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";  

        `ssh $orig_master_ssh_user\@$orig_master_host \" $ssh_start_vip \"`;  

        exit 0;  

}  

else {  

&usage();  

        exit 1;  

}  

}  

  

# A simple system call that enable the VIP on the new master  

sub start_vip() {  

`ssh $new_master_ssh_user\@$new_master_host \" $ssh_start_vip \"`;  

}  

# A simple system call that disable the VIP on the old_master  

sub stop_vip() {  

`ssh $orig_master_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)修复宕机的Master 

通常情况下自动切换以后,原master可能已经废弃掉,待原master主机修复后,如果数据完整的情况下,可能想把原来master重新作为新主库的slave,这时我们可以借助当时自动切换时刻的MHA日志来完成对原master的修复。下面是提取相关日志的命令:

grep -i "All other slaves should start" manager.log 

 

[info]  All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='172.25.4.4', MASTER_PORT=3306, MASTER_LOG_FILE='mysql-bin.000022', MASTER_LOG_POS=506716, MASTER_USER='test', MASTER_PASSWORD='xxx';

获取上述信息以后,就可以直接在修复后的master上执行change master to相关操作,重新作为从库了。 MySQL高可用之MHA的搭建

原创粉丝点击