MHA安装配置

一、配置主从同步

1. 本例中主从ip及端口

Master:10.1.5.8:3306             

Slave1:10.1.5.9:3306 (候选master)

Slave2:10.1.5.195:3306

 

角色

主机名

IP

主机

IP



Master

mysql28

10.15.224.28

mysql100

10.15.224.100



Slave1(候选Master)

mysql38

10.15.224.38

mysql101

10.15.224.101



Slave2

mysql48

10.15.224.48

mysql102(manager)

10.15.224.102



VIP







2. Slave配置参数

log-bin = mysql-bin

log-bin-index = mysql-bin.index

read_only=1 

relay_log_purge=0  #(一主一丛不需要此项,两从及以上建议开次参数,防止切换为成主库的从库自动删除中继日志后,无法给其他从库应用这部分日志)

 

3. 配置主从同步

步骤略。

4. 其他建议

可切换成主库的从库,建议配置成半同步。

 

详细的主从配置见:

http://blog.csdn.net/lichangzai/article/details/50423906

  MySQL的异步复制和半同步复制【笔记 半同步复制】

二、配置ssh公钥互信

1. 本例中manager节点和node节点ip

manager:10.1.5.8

node1:10.1.5.8

node2:10.1.5.9

node3:10.1.5.195

 

注:manager节点可以安装独立的服务器上,本例为了节省机器,manager安装在了主库(10.1.5.8)上.

 

2. 配置manager和node各节点间的root用户的ssh公钥互信

详细配置见:“配置ssh免密码连入”章节

http://blog.csdn.net/lichangzai/article/details/8206834

linux配置ssh互信-sometimeixpub-ChinaUnix博客

1 *  *  *  *  /usr/sbin/ntpdate  10.0.24.42


三、安装 MHA 包

1. 下载MHA安装包

下载网址:

https://code.google.com/p/mysql-master-ha/wiki/Downloads?tm=2

 

下载rpm包或tarall均可,建议用rpm包,因为安装简单。

https://github.com/yoshinorim/mha4mysql-manager

 https://github.com/yoshinorim/mha4mysql-node

https://github.com/yoshinorim/mha4mysql-manager/wiki/Downloads

2. 安装 MHA Node

在manager和node的所有节点均需安装MHA Node。

rpm安装方式:

# yum install perl-DBD-MySQL

# rpm -ivh mha4mysql-node-0.56-0.el5.noarch.rpm

 

tarall的安装方式:cd

tar -zxf mha4mysql-node-0.56.tar.gz

cd mha4mysql-node-0.56

perl Makefile.PL

make

make install

 

按安装顺序整理如下:

compat-db43-4.3.29-15.el6,perl-Mail-Sender-0.8.16-3.el6,perl-Mail-Sendmail-0.79-12.el6,perl-Config-Tiny-2.12-7.1.el6,perl-Parallel-ForkManager-0.7.9-1.el6,perl-Log-Dispatch-2.27-1.el6

其中,在安装perl-Log-Dispatch-2.27-1.el6包时还会遇到有模块的包需要安装,按安装顺序整理如下:

perl-TimeDate-1.16-11.1.el6,perl-MIME-Types-1.28-2.el6,perl-MailTools-2.04-4.el6,perl-Email-Date-Format-1.002-5.el6,perl-Params-Validate-0.92-3.el6,perl-MIME-Lite-3.027-2.el6

之后便可以正常安装mha4mysql-manager-0.56-0.el6.noarch

rpm -ivh mha4mysql-manager-0.56-0.el6.noarch.rpm

---整理安装的RPM包命令如下

rpm -ivh perl-Config-Tiny-2.12-7.1.el6.noarch.rpm

rpm -ivh mha4mysql-node-0.56-0.el6.noarch.rpm

rpm -ivh perl-DBD-MySQL-4.013-3.el6.i686.rpm

rpm -ivh compat-db43-4.3.29-15.el6.x86_64.rpm

rpm -ivh perl-Mail-Sender-0.8.16-3.el6.noarch.rpm

rpm -ivh perl-Parallel-ForkManager-0.7.9-1.el6.noarch.rpm

rpm -ivh perl-TimeDate-1.16-11.1.el6.noarch.rpm

rpm -ivh perl-MIME-Types-1.28-2.el6.noarch.rpm

rpm -ivh perl-MailTools-2.04-4.el6.noarch.rpm

rpm -ivh perl-Email-Date-Format-1.002-5.el6.noarch.rpm

rpm -ivh perl-Params-Validate-0.92-3.el6.

rpm -ivh perl-Params-Validate-0.92-3.el6.x86_64.rpm

rpm -ivh perl-MIME-Lite-3.027-2.el6.noarch.rpm

rpm -ivh perl-Mail-Sendmail-0.79-12.el6.noarch.rpm

rpm -ivg perl-Log-Dispatch-2.27-1.el6.noarch.rpm

rpm -ivh mha4mysql-manager-0.56-0.el6.noarch.rpm

http://fr2.rpmfind.net/linux/rpm2html/search.php?query=perl-Log-Dispatch&submit=Search+...&system=&arch=

使用 rpmfind.net 查找结果直接安装

http://blog.sina.com.cn/s/blog_54904e1c0102v2i2.html

(1)CentOS,RedHat 6.4版本下,MHA安装_绿龙_新浪博客

3. 安装 MHA Manager

# yum install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager

# rpm -ivh mha4mysql-node-0.56-0.el5.noarch.rpm

# rpm -ivh mha4mysql-manager-0.56-0.el5.noarch.rpm

 

注:

上面有些包需要先安装附加软件包(EPEL)才能使用yum安装,

安装EPEL源详细见:“yum安装”章节

http://blog.csdn.net/lichangzai/article/details/39272469

 

MHA Manager另一种安装方式:

MHA Manager 0.56 tarball源码安装

tar -zxf mha4mysql-manager-0.56.tar.gz

cd mha4mysql-manager-0.56

perl Makefile.PL

make

make install

 

四、MHA Manager 端配置

各参数含义:https://code.google.com/p/mysql-master-ha/wiki/Parameters#no_master

MHA Manager端配置,建议使用root操作系统用户执行,因为涉及到vip 启停。

 


mkdir -p /etc/masterha/app102

vi /etc/masterha/app102/app102.cnf


[server default]

manager_workdir=/etc/masterha/app102

manager_log=/etc/masterha/app102/manager.log

user=root

password=root

ssh_user=root

repl_user=repl

repl_password=oracle

#ping_interval=10

#master_ip_failover_script=/etc/masterha/app102/master_ip_failover #master failover时执行,不配置vip时不用配

#shutdown_script=/etc/masterha/power_manager

#report_script=/etc/masterha/app102/send_report  #master failover时执行,可选

#master_ip_online_change_script=/etc/masterha/app102/master_ip_online_change #masterswitchover时执行,不配置vip时不用配

[server1]

hostname=10.15.224.100

port=3306

master_binlog_dir=/d01/db/mysql/binlog

candidate_master=1

check_repl_delay=0

[server2]

hostname=10.15.224.101

port=3306

master_binlog_dir=/d01/db/mysql/binlog

candidate_master=1  #如果候选master有延迟的话,relay日志超过100m,failover切换不能成功,加上此参数后会忽略延迟日志大小。

check_repl_delay=0

[server3]

hostname=10.15.224.102

port=3306

master_binlog_dir=/d01/db/mysql/binlog

ignore_fail=1  #如果这个节点挂了,mha将不可用,加上这个参数,slave挂了一样可以用

no_master=1    #从不将这台主机转换为master





# mkdir -p /etc/masterha/app1

# vi /etc/masterha/app1/app1.cnf 

[server default]

manager_workdir=/etc/masterha/app1

manager_log=/etc/masterha/app1/manager.log

 

user=root

password=root

 

ssh_user=root

 

repl_user=repl_user

repl_password=licz

 

#ping_interval=10

#master_ip_failover_script=/etc/masterha/app1/master_ip_failover #master failover时执行,不配置vip时不用配

#shutdown_script=/etc/masterha/power_manager

#report_script=/etc/masterha/app1/send_report  #master failover时执行,可选

#master_ip_online_change_script=/etc/masterha/app1/master_ip_online_change #masterswitchover时执行,不配置vip时不用配

 

[server1]

hostname=10.1.5.8

port=3306

master_binlog_dir=/var/lib/mysql

candidate_master=1

check_repl_delay=0

 

[server2]

hostname=10.1.5.9

port=3306

master_binlog_dir=/var/lib/mysql

candidate_master=1  #如果候选master有延迟的话,relay日志超过100mfailover切换不能成功,加上此参数后会忽略延迟日志大小。

check_repl_delay=0

 

[server3]

hostname=10.1.5.195

port=3306

master_binlog_dir=/var/lib/mysql

ignore_fail=1  #如果这个节点挂了,mha将不可用,加上这个参数,slave挂了一样可以用

no_master=1  #从不将这台主机转换为master

 

2. 检查SSH配置

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

 

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

Tue Jan  5 17:16:40 2016 - [warning] Globalconfiguration file /etc/masterha_default.cnf not found. Skipping.

Tue Jan  5 17:16:40 2016 - [info] Reading applicationdefault configuration from /etc/masterha/app1/app1.cnf..

Tue Jan  5 17:16:40 2016 - [info] Reading serverconfiguration from /etc/masterha/app1/app1.cnf..

Tue Jan  5 17:16:40 2016 - [info] Starting SSHconnection tests..

Tue Jan  5 17:16:41 2016 - [debug]

Tue Jan  5 17:16:40 2016 - [debug]  Connecting via SSH fromroot@10.1.5.8(10.1.5.8:22) to root@10.1.5.9(10.1.5.9:22)..

Tue Jan  5 17:16:40 2016 - [debug]   ok.

Tue Jan  5 17:16:40 2016 - [debug]  Connecting via SSH fromroot@10.1.5.8(10.1.5.8:22) to root@10.1.5.195(10.1.5.195:22)..

......

Tue Jan  5 17:16:41 2016 - [debug]  Connecting via SSH fromroot@10.1.5.195(10.1.5.195:22) to root@10.1.5.9(10.1.5.9:22)..

Tue Jan  5 17:16:41 2016 - [debug]   ok.

Tue Jan  5 17:16:41 2016 - [info] All SSH connectiontests passed successfully.

成功!

 

3. 检查MHA配置

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

 

# masterha_check_repl --conf=/etc/masterha/app1/app1.cnf

Tue Jan  5 10:50:16 2016 - [warning] Globalconfiguration file /etc/masterha_default.cnf not found. Skipping.

Tue Jan  5 10:50:16 2016 - [info] Reading applicationdefault configuration from /etc/masterha/app1/app1.cnf..

Tue Jan  5 10:50:16 2016 - [info] Reading serverconfiguration from /etc/masterha/app1/app1.cnf..

Tue Jan  5 10:50:16 2016 - [info] MHA::MasterMonitorversion 0.56.

Tue Jan  5 10:50:16 2016 - [info] GTID failover mode =0

Tue Jan  5 10:50:16 2016 - [info] Dead Servers:

Tue Jan  5 10:50:16 2016 - [info] Alive Servers:

Tue Jan  5 10:50:16 2016 - [info]   10.1.5.8(10.1.5.8:3306)

Tue Jan  5 10:50:16 2016 - [info]   10.1.5.9(10.1.5.9:3306)

Tue Jan  5 10:50:16 2016 - [info]   10.1.5.195(10.1.5.195:3306)

Tue Jan  5 10:50:16 2016 - [info] Alive Slaves:

Tue Jan  5 10:50:16 2016 - [info]   10.1.5.9(10.1.5.9:3306)  Version=5.6.28-log (oldest major versionbetween slaves) log-bin:enabled

.......

Tue Jan  5 13:34:16 2016 - [info] Slaves settingscheck done.

Tue Jan  5 13:34:16 2016 - [info]

10.1.5.8(10.1.5.8:3306)(current master)

 +--10.1.5.9(10.1.5.9:3306)

 +--10.1.5.195(10.1.5.195:3306)

 

Tue Jan  5 13:34:16 2016 - [info] Checking replicationhealth on 10.1.5.9..

Tue Jan  5 13:34:16 2016 - [info]  ok.

Tue Jan  5 13:34:16 2016 - [info] Checking replicationhealth on 10.1.5.195..

Tue Jan  5 13:34:16 2016 - [info]  ok.

Tue Jan  5 13:34:16 2016 - [warning]master_ip_failover_script is not defined.

Tue Jan  5 13:34:16 2016 - [warning] shutdown_scriptis not defined.

Tue Jan  5 13:34:16 2016 - [info] Got exit code 0 (Notmaster dead).

 

MySQL Replication Health is OK.

成功!

 

注意:期间可能会遇到一些问题,可见另一文章的问题总结:

 

4. MHA Manager 端日常主要操作步骤

① 检查是否有下列文件,有则删除。

  发生主从切换后,MHAmanager服务会自动停掉,且在manager_workdir目录下面生成文件app1.failover.complete,若要启动MHA,必须先确保无此文件)

   # ll /etc/masterha/app1/app1.failover.complete

   # ll /etc/masterha/app1/app1.failover.error

  

② 检查MHA当前置:

   # masterha_check_repl --conf=/etc/masterha/app1/app1.cnf

  

③ 启动MHA:

   # nohup masterha_manager --conf=/etc/masterha/app1/app1.cnf > /etc/masterha/app1/mha_manager.log 2>&1 &

  

   当有slave 节点宕掉时,默认是启动不了的,加上 --ignore_fail_on_start 即使有节点宕掉也能启动MHA,如下:

   # nohup masterha_manager --conf=/etc/masterha/app1/app1.cnf --ignore_fail_on_start >/etc/masterha/app1/mha_manager.log 2>&1 &

  

④ 检查状态:

   # masterha_check_status --conf=/etc/masterha/app1/app1.cnf

 

⑤ 检查日志:

   #tail -f /etc/masterha/app1/manager.log

  

⑥ 主从切换后续工作

   主库切换后,把原主库修复成新从库,然后重新执行以上5步。原主库数据文件完整的情况下,可通过以下方式找出最后执行的CHANGE MASTER命令:

   # grep "CHANGE MASTER TO MASTER" /etc/masterha/app1/manager.log | tail -1

   CHANGE MASTER TO MASTER_HOST='10.1.5.9',MASTER_PORT=3306, MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=120,MASTER_USER='repl_user', MASTER_PASSWORD='xxx';

   --最后启动新从库

   # start slave;

   # show slave status\G

 

五、Failover应用场景测试

自动failover测试

应用场景1:master dead后,MHA当时已经开启,候选Master库(Slave)会自动failover为Master.

--shutdown mysql master node

# service mysql stop

--check new master node

mysql> show master status\G;

*************************** 1.row ***************************

             File: master-bin.000001

         Position: 330

--check slave node

 

mysql> show slave status\G;

*************************** 1.row ***************************

               Slave_IO_State: Waiting formaster to send event

                  Master_Host: 10.1.5.9

                  Master_User: repl_user

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File:master-bin.000001

 

--check manager.log

[root@host8 ~]# tail -100f  /etc/masterha/app1/manager.log

----- Failover Report -----

 

app1: MySQL Master failover10.1.5.8(10.1.5.8:3306) to 10.1.5.9(10.1.5.9:3306) succeeded

 

Master 10.1.5.8(10.1.5.8:3306)is down!

 

Check MHA Manager logs athost8.localdomain:/etc/masterha/app1/manager.log for details.

 

Startedautomated(non-interactive) failover.

The latest slave10.1.5.9(10.1.5.9:3306) has all relay logs for recovery.

Selected10.1.5.9(10.1.5.9:3306) as a new master.

10.1.5.9(10.1.5.9:3306): OK:Applying all logs succeeded.

10.1.5.195(10.1.5.195:3306): Thishost has the latest relay log events.

Generating relay diff filesfrom the latest slave succeeded.

10.1.5.195(10.1.5.195:3306):OK: Applying all logs succeeded. Slave started, replicating from10.1.5.9(10.1.5.9:3306)

10.1.5.9(10.1.5.9:3306):Resetting slave info succeeded.

Master failover to10.1.5.9(10.1.5.9:3306) completed successfully.

 

--最后把原主库修复成一个新的slave

# grep "CHANGE MASTER TO MASTER"  /etc/masterha/app1/manager.log | tail -1

   CHANGE MASTER TO MASTER_HOST='10.1.5.9',MASTER_PORT=3306, MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=120,MASTER_USER='repl_user', MASTER_PASSWORD='xxx';

mysql> CHANGE MASTER TO MASTER_HOST='10.1.5.9', MASTER_PORT=3306,MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=120,MASTER_USER='repl_user', MASTER_PASSWORD='licz';

Query OK, 0 rows affected, 2warnings (0.17 sec)

 

mysql> start slave;

 

mysql> show slave status\G;

*************************** 1.row ***************************

               Slave_IO_State: Waiting formaster to send event

                  Master_Host: 10.1.5.9

                  Master_User: repl_user

 

手动Failover

应用场景2:master dead,但是当时MHA没有开启,可以通过手工failover。

1.检查是否有下列文件,有则删除。

   # ll /etc/masterha/app1/app1.failover.complete

   # ll /etc/masterha/app1/app1.failover.error

2. 如果MHA在运行,需先停止MHA:  masterha_stop--conf=/etc/masterha/app1/app1.cnf

3. 检查MHA当前置: masterha_check_repl --conf=/etc/masterha/app1/app1.cnf

4. 手动切换:masterha_master_switch--conf=/etc/masterha/app1/app1.cnf --master_state=dead --dead_master_host=10.1.5.9 --dead_master_port=3306 

# 接以上的

 

以下为切换时指定了new_master_host和new_master_port,如果不指定new_master_host,则根据配置文件app1.cnf选出new_master_host,但new_master_port默认是3306。

# masterha_master_switch --conf=/etc/masterha/app1/app1.cnf --master_state=dead  --dead_master_host=10.1.5.9 --dead_master_port=3306  --new_master_host=10.1.5.8 --new_master_port=3306

 

六、Swithover 应用场景测试

Scheduled(Online) Master Switch(手动在线主库切换)

应用场景1:master和slave正常,MHA正常开启,维护操作时(例如更换新主机硬件、添加/删除列或主键)手动在线切换master到其他主机。

1. 如果MHA在运行,需先停止MHA

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

2. 检查MHA当前置

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

3. 手动切换

masterha_master_switch --master_state=alive --conf=/etc/masterha/app1/app1.cnf --orig_master_is_new_slave --running_updates_limit=3600 --interactive=0

注意:执行masterha_master_switch调用的不是master_ip_failover_script脚本,而是master_ip_online_change_script脚本,可把启动和停止VIP放到这个脚本中,如果没有配置VIP,则需要手动执行VIP切换,如下:

ssh  root@$orig_master_ip   /sbin/ifconfig  eth0:1 down

ssh  root@$new_master_ip   /sbin/ifconfig  eth0:1 10.1.5.21/24

 

以下为切换时指定了new_master_host和new_master_port,如果不指定new_master_host,则根据配置文件app1.cnf选出new_master_host,但new_master_port默认是3306。

masterha_master_switch --master_state=alive --conf=/etc/masterha/app1/app1.cnf --orig_master_is_new_slave --running_updates_limit=3600 --interactive=0--new_master_host=10.1.5.9 --new_master_port=3306

参数 --running_updates_limit 如果现在的master执行写操作的执行时间大于这个参数,或者任何一台slave的Seconds_Behind_Master大于这个参数,那么master switch将自动放弃。默认参数为1s

参数 --interactive=0 非交互切换,建议加上,可大大加快切换速度,加上后库不忙时大概3秒内切换完成。

 

 

七、定期删除中继日志

由于在第一步中,每个slave上设置了参数relay_log_purge=0,所以slave节点需要定期删除中继日志,建议每个slave节点删除中继日志的时间错开。

corntab -e

0 5 * * *  /usr/bin/purge_relay_logs --user=root--password=123456 --port=3306 --disable_relay_log_purge >> /var/lib/mysql/purge_relay.log  2>&1

删除中继日志可参考:https://code.google.com/p/mysql-master-ha/wiki/Requirements#Replication_user_must_exist_on_candidate_masters

 

--查看purge_relay_logs命令帮助

# purge_relay_logs -h

Option h is ambiguous (help,host)

Usage:

    purge_relay_logs --user=root--password=rootpass --host=127.0.0.1

 

    See online reference

   (http://code.google.com/p/mysql-master-ha/wiki/Requirements#purge_relay_

    logs_script) for details.

八、用VIP实现MHA的自动切换

通过配置配置MHA中的app1.cnf中的参数

配置MHA中的app1.cnf中的master_ip_failover_script和master_ip_online_change_script两个参数

参数中脚本的内容见:

master_ip_failover(perl)脚本


[root@host8 app1]# 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.1.5.21/24';  # Virtual IP

my $key = "1";

my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";

my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";

my $exit_code = 0;


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" ) {


        # $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 $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=po

rt –new_master_host=host –new_master_ip=ip –new_master_port=port\n";

}



master_ip_online_change(perl)脚本


[root@host8 app1]# cat master_ip_online_change

#!/usr/bin/env perl

use strict;

use warnings FATAL =>'all';


use Getopt::Long;


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

my $key = "1";

my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";

my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";

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=po

rt –new_master_host=host –new_master_ip=ip –new_master_port=port\n";

}



master_ip_online_change(shell)脚本



#以下是重用写的master_ip_online_change(shell)脚本


[root@host8 app1]# cat master_ip_online_change.sh

#/bin/bash

source /root/.bash_profile


vip=`echo '10.1.5.21/24'`  # Virtual IP

key=`echo '1'`


command=`echo "$1" | awk -F = '{print $2}'`

orig_master_host=`echo "$2" | awk -F = '{print $2}'`

new_master_host=`echo "$7" | awk -F = '{print $2}'`

orig_master_ssh_user=`echo "${12}" | awk -F = '{print $2}'`

new_master_ssh_user=`echo "${13}" | awk -F = '{print $2}'`


stop_vip=`echo "ssh root@$orig_master_host /sbin/ifconfig  eth0:$key  down"`

start_vip=`echo "ssh root@$new_master_host /sbin/ifconfig  eth0:$key  $vip"`


if [ $command = 'stop' ]

   then

   echo -e "\n\n\n***************************************************************\n"

   echo -e "Disabling the VIP - $vip on old master: $orig_master_host\n"

   $stop_vip

   if [ $? -eq 0 ]

      then

      echo "Disabled the VIP successfully"

   else

      echo "Disabled the VIP failed"

   fi

   echo -e "***************************************************************\n\n\n\n"

fi


if [ $command = 'start' -o $command = 'status' ]

   then

   echo -e "\n\n\n***************************************************************\n"

   echo -e "Enabling the VIP - $vip on new master: $new_master_host \n"

   $start_vip

   if [ $? -eq 0 ]

      then

      echo "Enabled the VIP successfully"

   else

      echo "Enabled the VIP failed"

   fi

   echo -e "***************************************************************\n\n\n\n"

fi



send_report(shell)脚本


[root@host8 app1]# cat send_report

#/bin/bash

source /root/.bash_profile


orig_master_host=`echo "$1" | awk -F = '{print $2}'`

new_master_host=`echo "$2" | awk -F = '{print $2}'`

new_slave_hosts=`echo "$3" | awk -F = '{print $2}'`

subject=`echo "$4" | awk -F = '{print $2}'`

body=`echo "$5" | awk -F = '{print $2}'`


#判断日志结尾是否有successfully,有则表示切换成功,成功与否都发邮件。

tac /etc/masterha/app1/manager.log | sed -n 2p | grep 'successfully' > /dev/null

if [ $? -eq 0 ]

    then

    echo -e "MHA $subject 主从切换成功\n master:$orig_master_host --> $new_master_host \n $body \n 当前从库:$new_slave_hosts" | mutt

 -s "MySQL实例宕掉,MHA $subject 切换成功" -- 94097532@qq.com

else

    echo -e "MHA $subject 主从切换失败\n master:$orig_master_host --> $new_master_host \n $body" | mutt -s "MySQL实例宕掉,MHA $subje

ct 切换失败" -- 94097532@qq.com

fi




通过Keepalieved实现vip切换:

详细配置见文章:

如果我们使用的MHA时,app1.cnf 中的master_ip_failover_script和master_ip_online_change_script两项没有配,即没有使用MHA的VIP方式,可使用keepalived来设置VIP。


本例中keepalived的master端和backup端ip:


master:10.1.5.8


backup:10.1.5.9


 


MHA配置见:http://blog.csdn.net/lichangzai/article/details/50470771


 


1. 安装keepalived

 


linux6自带keepalived,yum installkeepalived安装,配置样本是vi /etc/keepalived/keepalived.conf


linux5需下载安装,如下:


下载:http://www.keepalived.org/download.html


# tar zxvf keepalived-1.2.19.tar.gz


# cd keepalived-1.2.19


# ./configure --prefix=/usr/local/keepalived --with-kernel-dir=/usr/src/kernels/2.6.39-300.26.1.el5uek


如遇到configure: error: No SO_MARK declaration in headers,则用./configure --prefix=/usr/local/keepalived --disable-fwmark


# make


# make install


# cp /usr/local/keepalived/sbin/keepalived /usr/sbin/


# cp /usr/local/keepalived/etc/rc.d/init.d/keepalived  /etc/init.d/


# cp /usr/local/keepalived/etc/sysconfig/keepalived  /etc/sysconfig/


 


 


2. 配置keepalived

 


# mkdir /etc/keepalived


 


master配置:


# cat/etc/keepalived/keepalived.conf


! Configuration File forkeepalived


 


global_defs {

   notification_email {

     licz@umessage.com.cn


     94097432@qq.com


     lichangzai@163.com


   }


   notification_email_fromroot@localhost.localdomain


   smtp_server 127.0.0.1


   smtp_connect_timeout 30


   router_id LVS_DEVEL


}


 


vrrp_instance VI_1 {

    state BACKUP


    interface eth0


    virtual_router_id 51


    priority 100


    nopreempt


    advert_int 1


    authentication {

        auth_type PASS


        auth_pass 1234


    }


    virtual_ipaddress {

        10.1.5.21/24


    }


}


 


 


backup配置:


# cat /etc/keepalived/keepalived.conf


! Configuration File forkeepalived


 


global_defs {

   notification_email {

     licz@umessage.com.cn


     94097432@qq.com


     lichangzai@163.com


   }


   notification_email_fromroot@localhost.localdomain


   smtp_server 127.0.0.1


   smtp_connect_timeout 30


   router_id LVS_DEVEL


}


 


vrrp_instance VI_1 {

    state BACKUP


    interface eth0


    virtual_router_id 51


    priority 90


    advert_int 1


    authentication {

        auth_type PASS


        auth_pass 1234


    }


    virtual_ipaddress {

        10.1.5.21/24


    }


}


 


 


3.用脚本实现定时检查MySQL实例是否存活


安装keepalieved的节点,定时检查MySQL实例是否存活,宕掉时自动杀掉keepalived进程,从而实现VIP转移到backup节点。


# crontab -l


* * * * * /data/mysqldata/scripts/check_keepalived.sh > /dev/null  2>&1 &


 


# cat /data/mysqldata/scripts/check_keepalived.sh


#/bin/bash


source /root/.bash_profile


# source /data/mysqldata/scripts/mysql_env.ini


MYSQL_CMD=/usr/local/mysql/bin/mysql


CHECK_TIME=3  #check 3 times


MYSQL_OK=1    #MYSQL_OK values to 1 when mysql servicework,else values to 0


 


function check_mysql_health (){

   $MYSQL_CMD -uroot -p123456 -S /var/lib/mysql/mysql.sock -e "show status;" > /dev/null 2>&1


   if [ $? = 0 ]


   then


      MYSQL_OK=1


      /etc/init.d/keepalived start


   else


      MYSQL_OK=0


   fi


   return $MYSQL_OK


}


 


while [ $CHECK_TIME -ne 0 ]


do


   let "CHECK_TIME -=1"


   check_mysql_health


   if [ $MYSQL_OK = 1 ]


   then


      CHECK_TIME=0


      exit 0


   fi


   if [ $MYSQL_OK -eq 0 ] && [$CHECK_TIME -eq 0 ] 


   then


      /etc/init.d/keepalived stop


      echo "mysql 3306实例宕掉,keepalived已关闭" |mutt  -s "master keepalived已关闭"94097532@qq.com


      exit 1


   fi


   sleep 1


done




评论 (0)

发表评论