一、简介:

MHAMaster High Availability)由Perl脚本开发的,目前在MySQL高可用方面是一个相对成熟的解决方案,
是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用工具套装

从名称中,也可以看出,MHA关注的是主从复制的主DB

其主要功能是在MySQL主从复制架构下,完成故障切换,
和在众多从服务器中自动选取出新主服务器,并让其它从服务器和新选出的主服务器来行同步切换,
MySQL主服务器切换过程中,MHA可以做到高效的完成主从切换,基本保证在30秒可以完成所有切换操作,
并且在切换过程中,最大程度保证数据的一致性,避免丢失事务,达到真正意义的高可用


MHA提供了什么功能

  • 只能监控主数据库服务器是否可用
  • 当主DB不可用时,从多个从服务器中选举出新的主数据库服务器
  • 提供了主从切换和故障转移功能

MHA主从切换过程

1.MHA自动监控主DB,当主DB发生故障时,会尝试从出现故障的主数据库保存二进制日志
(而MMM不会去尝试保存最新的二进制日志,所以比MHA丢失数据的风险更高)。
但这一步并不是总是可以成功的,当主服务器硬件本身无法访问时,则不能去保存二进制日志

2.从多个可用从服务器中识别出最新更新的从服务器,并把这个服务器作为备选的主服务器来使用,
也就是说会把最接近原主服务器的从服务器,作为备选的主服务器
我们可以人为的设置一些服务器不参与选举
(在MMM中,只会使用原主服务器的主备服务器来作为新的服务器来使用,它不能保证主备服务器的数据是最新的,这也是MHA优于MMM的一个特性)

3.在备选主服务器和其他从服务器之间同步差异二进制日志,保证了各个从服务器上的数据一致

4.新选举出来的主,会存放刚才从老服务器上所保存下来的二进制日志(前提条件是能够保存下新的二进制日志)
在这一步如果出现错误,如重复的主键等,那么MHA就会停止进行故障转移

5.提升备选主DB服务器作为新的主DB服务器

6.迁移集群中的其它从DB作为新的主DB的从服务器


本文中我们会使用GTID模式


MHA架构图


优点

  • 同样是由Perl语言开发的开源工具
  • 可以支持基于GTID的复制模式
  • MHA在进行故障转移时更不易产生数据丢失
  • 同一个监控节点可以监控多个集群

缺点

  • 需要编写脚本或利用第三方工具来实现vip的配置
  • MHA启动后只会对主数据库进行监控
  • 需要基于SSH免认证配置,存在一定的安全隐患
  • 没有提供从服务器的读负载均衡功能MHA工具的缺点

二、MHA部署步骤介绍

具体部署架构图:


具体部署步骤

  • 配制集群内所有主机的SSH兔认证登陆
    比如故障转移过程中保存原主服务器二进制日志,
    配置虚拟IP地址等
  • 安装MHA-node(所有DB服务器安装)软件包和 MHA-manager(监控服务器安装) 软件包
    mha-monitor上安装MHA Manger依赖的perl模块
    yum install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes ncftp -y
    
  • 建立主从复制集群
    支持基于日志点的复制;支持基于GTD的复制(建议)
  • 配置MHA管理节点
    使用 masterha check sshmasterha_check_repl 对配置进行检验
  • 启动并测试MHA服务

三、MHA步骤演示

注意:如果是虚拟机复制的机子,记得修改my.cnf中的server-id
删除数据目录下的auto.cnf,重启mysql对配置文件生效,并初始化server uuid

修改配置,重启mysql后,为了主从复制生效还需要在从服务器重启主从链路:

mysql> stop slave;
mysql> start slave;
mysql> show slave status \G

1. 配置主数据库服务器

在主服务器,创建用于从服务器连接的帐号:

因为主从有可能切换,所以有可能成为主服务器的DB服务器,都必须创建这个复制帐号

mysql> grant replication slave on *.* to repl@'192.168.10.%' identified by '12345678';
Query OK, 0 rows affected, 1 warning (0.01 sec)

查看帐号授权情况

show grants for repl@'192.168.10.%';

主服务器配置
因为主从有可能切换,所以有可能成为主服务器的DB服务器,有些参数可能需要考虑以后成为主服务器的情况

bin_log = /usr/local/mysql/log/mysql-bin # 开启bin日志,并指定日志路径(建议日志和数据分开存放,能放在不同磁盘更好)
server_id=100


enforce_gtid_consistency = on # 启用enforce_gtid_consistency功能的时候,强制要求只允许复制事务安全的事务。 
                              # gtid_mode=on 时必须显式设置该项,如果不给定值,则默认为on。
                              #
                              # - 不能在事务内部创建和删除临时表( create temporary table)。
                              #   只能在事务外部进行,且autocommit需要设置为1。
                              # - 不能执行 create table ... select 语句。
                              # - 不能在事务内既更新事务表又更新非事务表。
                              #
                              # 应该尽量将该选项放在 gtid_mode 的前面,减少启动mysqld时的检查

gtid_mode = on                # 启用gtid模式,启用后就会记录每个事务的GTID标识符

log_slave_updates = on        # mysql5.7之前想要使用GTID模式,必须开启;5.7后主服务器就不需要强制开启了
                              # 主服务器会切换,所以建议都打开

所有DB服务器都必须开启GTID模式,可以用命令查看是否开启:

mysql> show variables like 'gtid_mode';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| gtid_mode     | ON    |
+---------------+-------+
1 row in set (0.11 sec)

配置好my.cnf,记得重启mysql


2. 从服务器配置

有可能切换为主服务器的从服务器,都要参照主服务器的参数进行配置

bin_log = mysql-bin
server_id = 101
relay_log = /usr/local/mysql/log/relay_log #  relay_log(中继日志),这个参数默认启用,但是默认名是主机名
gitd_mode = on    # 每个DB服务器都需要开启
enforce_gtid_consistency = on

read_only = on
log_slave_updates = on


# 这两个参数,指定从服务器连接主服务器的信息以及中继日志的存储方式,默认是存储在文件中(file),
# table方式,是存储在数据库的两个表中,这两个表是用的InnoDB存储引擎,当出现数据库奔溃时,
# 可以利用数据库InnoDB引擎事务的特点,对这两个表的信息进行恢复,以保证从服务器能从正确的位置重新同步数据
master_info_repository = TABLE
relay_log_info_repository = TABLE

3. 初始化从数据库数据

直接参考 GTID 模式篇文章

mysqldump --master-data=2 --single-transaction --triggers --routines --databases blog -uroot -p > blog.sql

4. 启动基于GTID的复制

master_auto_position=1,就是让数据库自动定位到同步位置,不需要我们指定位置

真实的参数数据:

change master to master_host='192.168.10.120',
master_user='repl',
master_password='12345678',
master_auto_position=1;

执行过程:(分别在两台从服务器上执行)

mysql> change master to master_host='192.168.10.120',
    -> master_user='repl',
    -> master_password='12345678',
    -> master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
$ start slave;
$ show slave status \G # 会显示 Auto_Position: 1

5. SSH免认证登陆

配置三台机器的ssh互信(三台都要操作)

$ ssh-keygen -t rsa
$ ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.10.120
$ ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.10.121
$ ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.10.122

现在可以通过ssh,无需密码相互登录了

$ ssh 192.168.10.120
Last login: Sun Sep  1 13:42:10 2019 from 192.168.10.121

6. 安装 EPEL

官方的rpm repository提供的rpm包往往是很滞后的,且提供的rpm包也不够丰富

EPEL恰恰可以解决这两方面的问题,
EPEL是由Fedora社区打造,装上了EPEL之后,就相当于添加了一个第三方源,


安装阿里云提供的 EPEL

wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

ncftp 软件包默认情况下就没有,需要在 EPEL 上查找


7. 安装MHA软件包

mha-monitor上安装MHA Manger依赖的perl模块(我们监控服务器就是:192.168.10.122):

yum install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes ncftp -y

上面所列的是监控节点的依赖的软件包,DB数据节点正常只要下面三个软件包就可以了:

yum install perl-DBD-MySQL perl-DBI  ncftp -y

直接去取git下载:
https://github.com/yoshinorim/mha4mysql-node/releases
https://github.com/yoshinorim/mha4mysql-manager/releases

使用到如下包:

mha4mysql-node-0.58-0.el7.centos.noarch.rpm     # 监控服务器安装的 监控管理包
mha4mysql-manager-0.58-0.el7.centos.noarch.rpm  # 所有DB服务器都需要安装的节点包

我在(192.168.10.122)下载:
下载正确的版本,我是CentOS7.6,所以mha下载的版本必须是 el7

wget https://github.com/yoshinorim/mha4mysql-node/releases/download/v0.58/mha4mysql-node-0.58-0.el7.centos.noarch.rpm
wget https://github.com/yoshinorim/mha4mysql-manager/releases/download/v0.58/mha4mysql-manager-0.58-0.el7.centos.noarch.rpm

node包是每个DB服务器需要安装的:

scp mha4mysql-node-0.58-0.el7.centos.noarch.rpm  root@192.168.10.120:/root
scp mha4mysql-node-0.58-0.el7.centos.noarch.rpm  root@192.168.10.121:/root

开始安装MHA软件包
必选先安装node,再安装manager

$ rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm # 所有DB数据节点都要安装
$ rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm # 只要在监控的服务器安装即可(我们测试直接同从服务器ip为122的安装一起)

8. 配置MHA监控

MHA配置文档:https://github.com/yoshinorim/mha4mysql-manager/wiki/Parameters

MHA只需要配置监控服务器(192.168.10.122)即可

我们把MHA配置文件放在

$ mkdir -p /etc/mha  # MHA配置目录

MHA工作中,可能需要从失败的主服务器下载一些二进制日志文件,也需要保存的地方,我们称之为工作目录

$ mkdir -p /home/mysql_mha  # MHA 工作目录,配置文件名:mysql_mha.cnf

查看配置内容(注意服务器上使用时,记得删除注释,以免报错):

$ vim /home/mysql_mha/mysql_mha.cnf

[server default]
user=mha            # 数据库建立的,用于MHA管理的数据库用户
password=12345678
manager_workdir=/home/mysql_mha  # 工作目录
manager_log=/home/mysql_mha/manager.log
remote_workdir=/home/mysql_mha   # 其它从数据库节点的工作目录,需要在其它节点新建这个目录; 设置远端mysql在发生切换时binlog的保存位置
ssh_user=root
repl_user=repl
repl_password=12345678
ping_interval=1  # 设置监控主库,发送ping包的时间间隔,默认是3秒,尝试三次没有回应的时候自动进行frailover
master_binlog_dir=/usr/local/mysql/var    # 需要下载master二进制日志,所以是master服务器mysql二进制日志路径
master_ip_failover_script=/user/bin/master_ip_failover # 可选,在完成主从切换之后,可以把主的 vip 转移到新主上;如果没有设置,需要使用第三方软件实现ip漂移
secondary_check_script=/usr/bin/masterha_secondary_check -s 192.168.10.121 -s 192.168.10.122 # mha 本身提供的脚本,默认只有监控的服务器去检测master服务器是否正常,加上这个配置,多个服务器可以对master进行检测是否正常
[server1]
hostname=192.168.10.120
candidate_master=1 # 允许选为主服务器;也就是候选主服务器
[server2]
hostname=192.168.10.121
candidate_master=1  
[server3]
hostname=192.168.10.122
no_master=1   # 禁止作为主服务器

直接在当前配置的主节点(192.168.10.120)服务器配置账户,
因为前面主从已经配置好,在主服务器创建帐号,会同步到其它从服务器

grant all privileges on *.* to mha@'192.168.10.%' identified by '12345678';

在其它DB服务器也要新建工作目录,作为配置文件的 remote_workdir的值

$ mkdir -p /home/mysql_mha

查看主服务器,二进制日志在 /usr/local/mysql/var/ 目录下
master_binlog_dir 配置使用:

mysql> show variables like '%log_bin%';
+---------------------------------+--------------------------------------+
| Variable_name                   | Value                                |
+---------------------------------+--------------------------------------+
| log_bin                         | ON                                   |
| log_bin_basename                | /usr/local/mysql/var/mysql-bin       |
| log_bin_index                   | /usr/local/mysql/var/mysql-bin.index |
| log_bin_trust_function_creators | OFF                                  |
| log_bin_use_v1_row_events       | OFF                                  |
| sql_log_bin                     | ON                                   |
+---------------------------------+--------------------------------------+
6 rows in set (0.00 sec)

必须给master_ip_failover有执行的权限,该文件放在文章底部

chmod -R 755 master_ip_failover

9. 测试MHA配置

安装完 MHA manager 后,监控服务器就有如下脚本:

$ cd /usr/bin
$ ls -al | grep masterha
masterha_check_repl
masterha_check_ssh
masterha_check_status
masterha_conf_host
masterha_manager
masterha_master_monitor
masterha_master_switch
masterha_secondary_check
masterha_stop

测试SSH免登陆是否正常,配置文件是否正常

$ masterha_check_ssh --conf=/etc/mha/mysql_mha.cnf 
Sun Sep  1 21:44:53 2019 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Sun Sep  1 21:44:53 2019 - [info] Reading application default configuration from /etc/mha/mysql_mha.cnf..
Sun Sep  1 21:44:53 2019 - [info] Reading server configuration from /etc/mha/mysql_mha.cnf..
Sun Sep  1 21:44:53 2019 - [info] Starting SSH connection tests..
Sun Sep  1 21:44:55 2019 - [debug] 
Sun Sep  1 21:44:54 2019 - [debug]  Connecting via SSH from root@192.168.10.121(192.168.10.121:22) to root@192.168.10.120(192.168.10.120:22)..
Sun Sep  1 21:44:54 2019 - [debug]   ok.
Sun Sep  1 21:44:54 2019 - [debug]  Connecting via SSH from root@192.168.10.121(192.168.10.121:22) to root@192.168.10.122(192.168.10.122:22)..
......
Sun Sep  1 21:44:55 2019 - [debug]   ok.
Sun Sep  1 21:44:56 2019 - [info] All SSH connection tests passed successfully.

查看当前主从复制结构和状态,ssh免登录状态,vip转移脚本测试等

$ masterha_check_repl --conf=/etc/mha/mysql_mha.cnf 
Sun Sep  1 21:46:44 2019 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Sun Sep  1 21:46:44 2019 - [info] Reading application default configuration from /etc/mha/mysql_mha.cnf..
Sun Sep  1 21:46:44 2019 - [info] Reading server configuration from /etc/mha/mysql_mha.cnf..
Sun Sep  1 21:46:44 2019 - [info] MHA::MasterMonitor version 0.58.
Sun Sep  1 21:46:45 2019 - [info] GTID failover mode = 1
Sun Sep  1 21:46:45 2019 - [info] Dead Servers:
Sun Sep  1 21:46:45 2019 - [info] Alive Servers:
Sun Sep  1 21:46:45 2019 - [info]   192.168.10.120(192.168.10.120:3306)
Sun Sep  1 21:46:45 2019 - [info]   192.168.10.121(192.168.10.121:3306)
Sun Sep  1 21:46:45 2019 - [info]   192.168.10.122(192.168.10.122:3306)
Sun Sep  1 21:46:45 2019 - [info] Alive Slaves:
Sun Sep  1 21:46:45 2019 - [info]   192.168.10.121(192.168.10.121:3306)  Version=5.7.22-log (oldest major version between slaves) log-bin:enabled
Sun Sep  1 21:46:45 2019 - [info]     GTID ON
Sun Sep  1 21:46:45 2019 - [info]     Replicating from 192.168.10.120(192.168.10.120:3306)
Sun Sep  1 21:46:45 2019 - [info]     Primary candidate for the new Master (candidate_master is set)
Sun Sep  1 21:46:45 2019 - [info]   192.168.10.122(192.168.10.122:3306)  Version=5.7.22-log (oldest major version between slaves) log-bin:enabled
Sun Sep  1 21:46:45 2019 - [info]     GTID ON
Sun Sep  1 21:46:45 2019 - [info]     Replicating from 192.168.10.120(192.168.10.120:3306)
Sun Sep  1 21:46:45 2019 - [info]     Not candidate for the new Master (no_master is set)
Sun Sep  1 21:46:45 2019 - [info] Current Alive Master: 192.168.10.120(192.168.10.120:3306)
Sun Sep  1 21:46:45 2019 - [info] Checking slave configurations..
Sun Sep  1 21:46:45 2019 - [info] Checking replication filtering settings..
Sun Sep  1 21:46:45 2019 - [info]  binlog_do_db= , binlog_ignore_db= 
Sun Sep  1 21:46:45 2019 - [info]  Replication filtering check ok.
Sun Sep  1 21:46:45 2019 - [info] GTID (with auto-pos) is supported. Skipping all SSH and Node package checking.
Sun Sep  1 21:46:45 2019 - [info] Checking SSH publickey authentication settings on the current master..
Sun Sep  1 21:46:45 2019 - [info] HealthCheck: SSH to 192.168.10.120 is reachable.
Sun Sep  1 21:46:45 2019 - [info] 
192.168.10.120(192.168.10.120:3306) (current master)
 +--192.168.10.121(192.168.10.121:3306)
 +--192.168.10.122(192.168.10.122:3306)

Sun Sep  1 21:46:45 2019 - [info] Checking replication health on 192.168.10.121..
Sun Sep  1 21:46:45 2019 - [info]  ok.
Sun Sep  1 21:46:45 2019 - [info] Checking replication health on 192.168.10.122..
Sun Sep  1 21:46:45 2019 - [info]  ok.
Sun Sep  1 21:46:45 2019 - [info] Checking master_ip_failover_script status:
Sun Sep  1 21:46:45 2019 - [info]   /usr/bin/master_ip_failover --command=status --ssh_user=root --orig_master_host=192.168.10.120 --orig_master_ip=192.168.10.120 --orig_master_port=3306 
Checking the Status of the script.. OK 
Sun Sep  1 21:46:46 2019 - [info]  OK.
Sun Sep  1 21:46:46 2019 - [warning] shutdown_script is not defined.
Sun Sep  1 21:46:46 2019 - [info] Got exit code 0 (Not master dead).

MySQL Replication Health is OK.

查看运行状态

$ masterha_check_status --conf=/etc/mha/mysql_mha.cnf
mysql_mha (pid:10301) is running(0:PING_OK), master:192.168.10.121

后台启动MHA manager
2>&1是将标准错误(2)重定向到标准输出(&1),标准输出(&1)再被重定向输入到out.log文件中

$ nohup masterha_manager --conf=/etc/mha/mysql_mha.cnf  > /home/mysql_mha/out.log 2>&1 &

因为后台运行,可以查看运行输出的

$ more /home/mysql_mha/out.log
nohup: ignoring input
Mon Sep  2 09:41:35 2019 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Mon Sep  2 09:41:35 2019 - [info] Reading application default configuration from /etc/mha/mysql_mha.cnf..
Mon Sep  2 09:41:35 2019 - [info] Reading server configuration from /etc/mha/mysql_mha.cnf..

四、故障切换,数据不一致、重新上线、手动切换主等问题

背景

因为主120服务器故障停止,主服务器转移到121服务器了,122服务器的主服务器也重新指向了121


问题1:

如果120重新启用,必须也指向到121服务器,把121作为120的主服务器,否则检查也会报错!
There are 2 non-slave servers!,两个非从服务器,也就是两个主服务器,会冲突!

$ masterha_check_repl --conf=/etc/mha/mysql_mha.cnf 
Mon Sep  2 01:06:40 2019 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Mon Sep  2 01:06:40 2019 - [info] Reading application default configuration from /etc/mha/mysql_mha.cnf..
Mon Sep  2 01:06:40 2019 - [info] Reading server configuration from /etc/mha/mysql_mha.cnf..
Mon Sep  2 01:06:40 2019 - [info] MHA::MasterMonitor version 0.58.
Mon Sep  2 01:06:41 2019 - [error][/usr/share/perl5/vendor_perl/MHA/ServerManager.pm, ln653] There are 2 non-slave servers! MHA manages at most one non-slave server. Check configurations.
Mon Sep  2 01:06:41 2019 - [error][/usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm, ln427] Error happened on checking configurations.  at /usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm line 329.
Mon Sep  2 01:06:41 2019 - [error][/usr/share/perl5/vendor_perl/MHA/MasterMonitor.pm, ln525] Error happened on monitoring servers.
Mon Sep  2 01:06:41 2019 - [info] Got exit code 1 (Not master dead).

问题2:

121作为主服务器后,修改了数据,并且同步到了122服务器。
此时120服务器故障解除,需要重新启用,但数据还是旧数据,怎样才能把主服务器迁移回120服务器?

121服务器导出最新数据,新数据重新给121初始化,这样三台服务器数据就都会一样了,
这样再切换服务器才能成功


MHA报错

Can't exec "mysqlbinlog": No such file or directory at /usr/local/share/perl5/MHA/BinlogManager.pm line 99.

解决方法

$ ln -s /usr/local/mysql/bin/mysqlbinlog /usr/local/bin/mysqlbinlog
$ ln -s /usr/local/mysql/bin/mysql /usr/local/bin/mysql

主缺失binlog的情况

mysql > show slave status \G
Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.'

由于种种原因,有可能主库上已经purge掉了一些binlog,从库去找不到数据,所以报错的

解决方法两种

  1. 把当前出错的从服务器的主服务器指向没有purge的从服务器上同步数据,同步结束后再切换到原先主服务器
  2. 如果所有主从服务器都已经purge了,那只能把slave上的gtid_purged设置为master还没有被purge掉的值,
    最后借助第三方一致性同步工具来做数据的一致性同步。

参考:https://www.cnblogs.com/moss_tan_jun/p/7860231.html


五、附件

master_ip_failover 文件:

#!/usr/bin/env perl

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

use Getopt::Long;
use MHA::DBHelper;

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


my $vip = '192.168.10.80/24';  # Virtual IP  自己定义虚拟ip
my $key = "1";
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";  # 修改为自己的网卡
my $ssh_stop_vip = "/sbin/ifconfig ens33:$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,
  'new_master_user=s'     => \$new_master_user,
  'new_master_password=s' => \$new_master_password,
);

exit &main();

sub main {
  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 "Disabling the VIP on old master: $orig_master_host \n";
      &stop_vip();
      # updating global catalog, etc
      $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"; 
    `ssh $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 $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";
}