mysql半同步复制和MHA搭建(一文搭建出来MHA架构)

一、搭建半同步复制关系。

要负责保存日志、比较中继日志,选择主备 MHA会通过Node监控MySQL数据库服务地节点信息,定期检测和返回Master角色地健康状态(健康检查) MHA通过将VIP定义在Master节点上,并且数据库的访问也从此VIP进入,当Master异常时,MHA会进行"故障切换",就是VIP漂移+二进制日志保存 漂移到主备节点后,会通过脚本命令来控制MySQL服务器角色的变更。

架构图如下
在这里插入图片描述

master IP:10.10.20.64
slave01 IP:10.10.20.65
slave02 IP:10.10.20.66


#关闭防火墙
systemctl disable firewalld
sed -i s#SELINUX=enforcing#SELINUX=disabled# /etc/selinux/config
reboot

#配置基础环境
hostnamectl set-hostname master

#从库
hostnamectl set-hostname slave01
hostnamectl set-hostname slave02

#所有机器
 yum install -y conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget vim net-tools
 
 #配置互信(所有节点执行)
 ssh-keygen -t rsa
 ssh-copy-id -i  /root/.ssh/id_rsa.pub root@10.10.20.64
 ssh-copy-id -i  /root/.ssh/id_rsa.pub root@10.10.20.65
 ssh-copy-id -i  /root/.ssh/id_rsa.pub root@10.10.20.66

#配置域名解析(所有节点执行)
cat >> /etc/hosts << EOF
10.10.20.64 master
10.10.20.65 slave01
10.10.20.66 slave02
EOF

#卸载系统数据库
rpm -qa|grep mariadb #包名填到下面
rpm -e --nodeps mariadb-libs-5.5.56-2.el7.x86_64 #包根据自己的来

#主节点下载
wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.6.44-linux-glibc2.12-x86_64.tar.gz
#两个从节点执行
scp master:/root/mysql-5.6.44-linux-glibc2.12-x86_64.tar.gz ./

#解压
tar xf mysql-5.6.44-linux-glibc2.12-x86_64.tar.gz -C /usr/local/

#软连接
ln -s /usr/local/mysql-5.6.44-linux-glibc2.12-x86_64/ /usr/local/mysql56

#添加用户
useradd -s /sbin/nologin mysql

#添加到环境变量
echo 'export PATH=/usr/local/mysql56/bin:$PATH' >>/etc/profile
source /etc/profile

#查看版本(能查看代表上面没有问题)
mysql -V

#初始化数据库
mkdir -p /data/mysql/data
mkdir -p /data/mysql/log
chown -R mysql.mysql /data

#编辑MySQL配置文件
cat >/etc/my.cnf<<EOF
[mysqld]
user=mysql
basedir=/usr/local/mysql56
datadir=/data/mysql/data
port=3306
socket=/tmp/mysql.sock
server_id=6            #每个数据库改成不同的
log_bin=/data/mysql/log/binlog
binlog_format=row
max_binlog_cache_size=2000M
max_binlog_size=1G
sync_binlog=1
log-slave-updates = true
#rpl_semi_sync_master_enabled=1
#rpl_semi_sync_master_timeout=1000 #ms
#rpl_semi_sync_slave_enabled=1

[mysql]
socket=/tmp/mysql.sock
EOF

#下载依赖包
yum install -y mariadb-libs
yum install -y libaio-devel
yum -y install autoconf make perl

#初始化
cd /usr/local/mysql56
./scripts/mysql_install_db  --defaults-file=/etc/my.cnf
 
 #启动
 mysqld --defaults-file=/etc/my.cnf &

#主实例创建
show master status\G #记录位点。填到同步任务里面

create user repl@'%' identified by '123456';
grant replication slave on *.* to repl@'%';

#从实例执行  #填写主实例记录的位点。
change master to master_host='slave01',
master_port=3306,
master_user='repl',
master_password='123456',
master_log_file='binlog.000017',  #填写记录的binlog
master_log_pos=120, 			  #填写记录的位点
master_connect_retry=30;          #延迟30S变异步

#设置备库只读
set global read_only='ON';

#启动主从关系
start slave;

#登录数据库
mysql
#启动半同步复制-主库
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';

set global rpl_semi_sync_master_enabled=1;

show status like '%semi%status%';

#启动半同步复制-从库
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';

set global rpl_semi_sync_slave_enabled=1;

show status like '%semi%status%';
二、搭建MHA
1、failover 脚本

建议直接用我文件里面提供的修改 我文档里面的位置/usr/local/master_ip_failover

cat >>/usr/local/master_ip_failover<< EOF
#!/usr/bin/env perl
use strict;
use Net::Ping;
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 $wk =  "eth0";
my $vip = "10.10.20.88"; 
my $key = "6";			  
my $ifctrl = "/sbin/ifconfig";
my $arpingd = "/sbin/arping";
my $ssh_start_vip = "$ifctrl $wk:$key $vip/24";
my $ssh_stop_vip = "$ifctrl $wk:$key down";
my $ssh_status_vip = "$ifctrl $wk:$key $vip/24";
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.
         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";
            &ping_check($vip);
            $exit_code = 0;
        };
        if ($@) {
            warn "Got Error: $@\n";
            exit $exit_code;
        }
        exit $exit_code;
}
elsif ( $command eq "start" ) {

        # all arguments are passed.
my $exit_code = 10;
        eval {
            print "\n\n\n***************************************************************\n";
            print "Enabling the VIP - $vip on new  master: $ssh_user\@$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_status_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 -o StrictHostKeyChecking=no \" $ssh_start_vip \"`;
}

# A simple system call that enable the VIP on the new master
sub stop_vip() {
    #return 0  unless  ($ssh_user);
    `ssh $ssh_user\@$orig_master_host -o StrictHostKeyChecking=no \" $ssh_stop_vip \"`;
}

sub ping_check{
    my $dest=shift;
    my $mp = Net::Ping->new("icmp");
    if($mp->ping($dest,3)){
        &stop_vip();
    }
    else {
        $exit_code = 0;
    }
    $mp->close;
}

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

#主节点
yum install perl-DBD-MySQL -y
yum install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes -y

#从节点
yum install perl-DBD-MySQL -y

#安装包下载(游览器执行并上传到主节点)
http://www.mysql.gr.jp/frame/modules/bwiki/index.php?plugin=attach&pcmd=open&file=mha4mysql-manager-0.56-0.el6.noarch.rpm&refer=matsunobu

http://www.mysql.gr.jp/frame/modules/bwiki/index.php?plugin=attach&pcmd=open&file=mha4mysql-node-0.56-0.el6.noarch.rpm&refer=matsunobu

#主节点安装
yum install mha4mysql-node-0.56-0.el6.noarch.rpm -y
yum install mha4mysql-manager-0.56-0.el6.noarch.rpm -y

#从节点安装node
scp master:/root/mha4mysql-node-0.56-0.el6.noarch.rpm ./
yum install mha4mysql-node-0.56-0.el6.noarch.rpm -y

2、写manager配置文件
cat >>/etc/app1.cnf<<EOF
[server default]
manager_workdir=/mha/app     #主要是存储binlog使用
manager_log=/var/log/masterha/app1/manager.log #manager错误日志
master_binlog_dir=/data/mysql/log  #主库binlog所在位置
master_ip_failover_script=/usr/local/master_ip_failover #自动故障转移脚本
#master_ip_online_change_script=/usr/local/bin/master_ip_online_change #手动故障转移脚本
#report_script=/usr/local/send_report  #告警脚本
#shutdown_script="" #设置故障发生后关闭故障主机脚本
user=mha	
password=123456
ping_interval=3
remote_workdir=/tmp
repl_user=repl
repl_password=123456
ssh_user=root

[server1]
hostname=master
port=3306

[server2]
hostname=slave01
port=3306
candidate_master=1 # 不管怎样都切到优先级高的主机,一般在主机性能差异的时候用
check_repl_delay=0 # 支持复制的检查,默认情况下如果一个slave落后master 100M的relay logs(中继日志)的话,MHA将不会选择该slave作为新的master,设置为0的话会忽略此规则

[server3]
hostname=slave02
port=3306
EOF


latest_priority
在默认情况下,和Master最接近的slave(一个slave从Master上获得了最一个binlog事件)是最有优先权成为新的master。 如果你想控制一下切换的策略(如: 先选择host2,如果不行,选host3;host3不行,选host4…) 那么设置latest_priority = 0 就可以了。


multi_tier_slave
从MHA 0.52开始, 多层复制可以支持了。在默认情况下,不支持三层或是更多层的复制配置。 如果: host2从host1上复制,host3从host2上复制。 在默认配置的情况下不支持写host{1,2,3},因为这是一个三层的复制,MHA Manager会停止报错。 当设置了multi_tier_slave, MHA Manager就不会在三层复制报错停止。 但是会忽略第三层的机器。也就是如果host1挂了,host2将会成为新的master,host3还是从host2上进行复制。


ping_interval
这个参数设置MHA Manager多长时间去ping一下master(执行一些SQL语句). 当失去和master三次偿试,MHA Manager会认为MySQL Master死掉了。也就是说,最大的故障切换时间是4次ping_interval的时间,默认是3秒。


ping_type=INSERT
(从MHA 0.53后开始支持) 在默认情况下, MHA manager和MySQL创建一个连接执行”select 1″(ping_type=select)用于检查master是否健康,同一个连接持续3S。 但有一些情况:每次检测都连接/然后断开会比较好一点,这样对于tcp方面的错误感知更快一点。设置ping_type=CONNECT 就行了。从MHA 0.56后pint_type=INSERT也被添加,同一个连接持续3S。


secondary_check_script
一般来讲, 非常推荐使用更多网络上机器是不同路由策略上的机器来检查MySQL Master是否存活。 默认情况下,只有MHA Manager通过一个路由来检查Master是否存活。这个也是不推荐的。MHA可以通过外部secondary_check_script配置的脚本来做到从多个路由策略下进行检查。
secondary_check_script = masterha_secondary_check -s remote_host1 -s remote_host2
secondary_check_script包含在MHA Manager发行包中。 MHA中内置的secondary_check_script在大多数情况下工作良好,但并不是任何地都可以使用这个脚本。
在上面的例子中, MHA Manager通过Manager->(A)->remote_host1->(B)->master_host 和Manager->(A)-remote_host2->(B)->master_host来检查MySQL master是否存活。如果在连接过程中通过A可以都成功,通过B是都失败,secondary_/check_/script返回0,而且认为master已经死掉,进行故障切换。如果通过A成功,但返回代码为: 2,则MHA manager有会认为是网络问题,则不会进行故障切换。如果A成功,B也成功,masterha_secondary_check 退出返回:3 则MHA Manager就为认为MySQL Master为存活状态, 则不会进行故障切换。
一般来讲, remote_host1和remote_host2是和MHA Manager及MySQL Server位于不同的网段中。
MHA会调用secondary_check_script声明的脚本并自动带上一些参数。 masterha_secondary_check在很多场景都是适用的,但是你也可以自已实现这个程序带有更多的功能。
3、初始化
#创建文件
mkdir -p /mha/app
mkdir -p  /var/log/masterha/app1/

#所有节点执行
ln -s /usr/local/mysql56/bin/mysqlbinlog  /usr/bin/mysqlbinlog
ln -s /usr/local/mysql56/bin/mysql  /usr/bin/mysql

#数据库里创建用户(主节点)
CREATE USER 'mha'@'master' IDENTIFIED BY '123456';
GRANT  all ON *.* TO 'mha'@'master';
CREATE USER 'mha'@'slave01' IDENTIFIED BY '123456';
GRANT  all ON *.* TO 'mha'@'slave01';
CREATE USER 'mha'@'slave02' IDENTIFIED BY '123456';
GRANT  all ON *.* TO 'mha'@'slave02';
FLUSH PRIVILEGES;
4、启动服务
检查互信
masterha_check_ssh --conf=/etc/app1.cnf

检测manager状态
masterha_check_status --conf=/etc/app1.cnf

启动前检测
masterha_check_repl --conf=/etc/app1.cnf

启动
nohup masterha_manager --conf=/etc/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null> /tmp/mha/logs/manager.log 2>&1 &

备注命令
5、故障后恢复步骤

1)启动故障的数据库

mysqld --defaults-file=/etc/my.cnf &

2)查看manager日志

cat /var/log/masterha/app1/manager.log在这里插入图片描述
3)根据上面的内容填写(#去故障的实例执行)

#从实例执行  #填写主实例记录的位点。
change master to master_host='master',  #主库ip
master_port=3306,						 #主库端口	
master_user='repl',						 #主库账号
master_password='123456',				 #主库密码
master_log_file='binlog.000032',  		 #同步到的主库binlog
master_log_pos=120; 			  		 #主库位点

4)启动同步任务

start slave;

5)编辑manager配置文件

vim /etc/app1.cnf

添加故障实例实例

[server1]
candidate_master=1
check_repl_delay=0
hostname=master
port=3306

6)启动前检测

masterha_check_repl --conf=/etc/app1.cnf #返回MySQL Replication Health is OK.就没有问题了

在这里插入图片描述

7) 启动

nohup masterha_manager --conf=/etc/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null> /tmp/mha/logs/manager.log 2>&1 &

8)检测manager状态

    masterha_check_status --conf=/etc/app1.cnf #返回 running(0:PING_OK)就成功了

在这里插入图片描述

6、手动切换脚本

建议直接使用我文件里面的然后修改下面我标记的内容

cat >>/usr/local/bin/master_ip_online_change<<EOF
#!/usr/bin/env perl
#  Copyright (C) 2011 DeNA Co.,Ltd.
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#  Foundation, Inc.,
#  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
## Note: This is a sample script and is not complete. Modify the script based on your environment.
use strict;
use warnings FATAL => 'all';
use Getopt::Long;
use MHA::DBHelper;
use MHA::NodeUtil;
use Time::HiRes qw( sleep gettimeofday tv_interval );
use Data::Dumper;
my $_tstart;
my $_running_interval = 0.1;
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,
);

##------------------------修改----------------------
my $vip = '10.10.20.88';  # Virtual IP
my $key = "2";
my $gateway = '10.10.20.255';
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip/24;/sbin/arping -I eth0 -c 3 -s $vip $gateway >/dev/null 2>&1";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";
my $sshuser = "root";
##--------------------------------------------------

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 current_time_us {
  my ( $sec, $microsec ) = gettimeofday();
  my $curdate = localtime($sec);
  return $curdate . " " . sprintf( "%06d", $microsec );
}
sub sleep_until {
  my $elapsed = tv_interval($_tstart);
  if ( $_running_interval > $elapsed ) {
    sleep( $_running_interval - $elapsed );
  }
}
sub get_threads_util {
  my $dbh                    = shift;
  my $my_connection_id       = shift;
  my $running_time_threshold = shift;
  my $type                   = shift;
  $running_time_threshold = 0 unless ($running_time_threshold);
  $type                   = 0 unless ($type);
  my @threads;
  my $sth = $dbh->prepare("SHOW PROCESSLIST");
  $sth->execute();
  while ( my $ref = $sth->fetchrow_hashref() ) {
    my $id         = $ref->{Id};
    my $user       = $ref->{User};
    my $host       = $ref->{Host};
    my $command    = $ref->{Command};
    my $state      = $ref->{State};
    my $query_time = $ref->{Time};
    my $info       = $ref->{Info};
    $info =~ s/^\s*(.*?)\s*$/$1/ if defined($info);
    next if ( $my_connection_id == $id );
    next if ( defined($query_time) && $query_time < $running_time_threshold );
    next if ( defined($command)    && $command eq "Binlog Dump" );
    next if ( defined($user)       && $user eq "system user" );
    next
      if ( defined($command)
      && $command eq "Sleep"
      && defined($query_time)
      && $query_time >= 1 );
    if ( $type >= 1 ) {
      next if ( defined($command) && $command eq "Sleep" );
      next if ( defined($command) && $command eq "Connect" );
    }
    if ( $type >= 2 ) {
      next if ( defined($info) && $info =~ m/^select/i );
      next if ( defined($info) && $info =~ m/^show/i );
    }
    push @threads, $ref;
  }
  return @threads;
}
sub main {
  if ( $command eq "stop" ) {
    ## Gracefully killing connections on the current master
    # 1. Set read_only= 1 on the new master
    # 2. DROP USER so that no app user can establish new connections
    # 3. Set read_only= 1 on the current master
    # 4. Kill current queries
    # * Any database access failure will result in script die.
    my $exit_code = 1;
    eval {
      ## Setting read_only=1 on the new master (to avoid accident)
      my $new_master_handler = new MHA::DBHelper();
      # args: hostname, port, user, password, raise_error(die_on_error)_or_not
      $new_master_handler->connect( $new_master_ip, $new_master_port,
        $new_master_user, $new_master_password, 1 );
      print current_time_us() . " Set read_only on the new master.. ";
      $new_master_handler->enable_read_only();
      if ( $new_master_handler->is_read_only() ) {
        print "ok.\n";
      }
      else {
        die "Failed!\n";
      }
      $new_master_handler->disconnect();
      # Connecting to the orig master, die if any database error happens
      my $orig_master_handler = new MHA::DBHelper();
      $orig_master_handler->connect( $orig_master_ip, $orig_master_port,
        $orig_master_user, $orig_master_password, 1 );
      ## Drop application user so that nobody can connect. Disabling per-session binlog beforehand
      $orig_master_handler->disable_log_bin_local();
      #print current_time_us() . " Drpping app user on the orig master..\n";
      #FIXME_xxx_drop_app_user($orig_master_handler);
      ## Waiting for N * 100 milliseconds so that current connections can exit
      my $time_until_read_only = 15;
      $_tstart = [gettimeofday];
      my @threads = get_threads_util( $orig_master_handler->{dbh},
        $orig_master_handler->{connection_id} );
      while ( $time_until_read_only > 0 && $#threads >= 0 ) {
        if ( $time_until_read_only % 5 == 0 ) {
          printf
"%s Waiting all running %d threads are disconnected.. (max %d milliseconds)\n",
            current_time_us(), $#threads + 1, $time_until_read_only * 100;
          if ( $#threads < 5 ) {
            print Data::Dumper->new( [$_] )->Indent(0)->Terse(1)->Dump . "\n"
              foreach (@threads);
          }
        }
        sleep_until();
        $_tstart = [gettimeofday];
        $time_until_read_only--;
        @threads = get_threads_util( $orig_master_handler->{dbh},
          $orig_master_handler->{connection_id} );
      }
      ## Setting read_only=1 on the current master so that nobody(except SUPER) can write
      print current_time_us() . " Set read_only=1 on the orig master.. ";
      $orig_master_handler->enable_read_only();
      if ( $orig_master_handler->is_read_only() ) {
        print "ok.\n";
      }
      else {
        die "Failed!\n";
      }
      ## Waiting for M * 100 milliseconds so that current update queries can complete
      my $time_until_kill_threads = 5;
      @threads = get_threads_util( $orig_master_handler->{dbh},
        $orig_master_handler->{connection_id} );
      while ( $time_until_kill_threads > 0 && $#threads >= 0 ) {
        if ( $time_until_kill_threads % 5 == 0 ) {
          printf
"%s Waiting all running %d queries are disconnected.. (max %d milliseconds)\n",
            current_time_us(), $#threads + 1, $time_until_kill_threads * 100;
          if ( $#threads < 5 ) {
            print Data::Dumper->new( [$_] )->Indent(0)->Terse(1)->Dump . "\n"
              foreach (@threads);
          }
        }
        sleep_until();
        $_tstart = [gettimeofday];
        $time_until_kill_threads--;
        @threads = get_threads_util( $orig_master_handler->{dbh},
          $orig_master_handler->{connection_id} );
      }
      ## Terminating all threads
      print current_time_us() . " Killing all application threads..\n";
      $orig_master_handler->kill_threads(@threads) if ( $#threads >= 0 );
      print current_time_us() . " done.\n";
      $orig_master_handler->enable_log_bin_local();
      $orig_master_handler->disconnect();
      ## After finishing the script, MHA executes FLUSH TABLES WITH READ LOCK
      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" ) {
    ## Activating master ip on the new master
    # 1. Create app user with write privileges
    # 2. Moving backup script if needed
    # 3. Register new master's ip to the catalog database
# We don't return error even though activating updatable accounts/ip failed so that we don't interrupt slaves' recovery.
# If exit code is 0 or 10, MHA does not abort
    my $exit_code = 10;
    eval {
      my $new_master_handler = new MHA::DBHelper();
      # args: hostname, port, user, password, raise_error_or_not
      $new_master_handler->connect( $new_master_ip, $new_master_port,
        $new_master_user, $new_master_password, 1 );
      ## Set read_only=0 on the new master
      $new_master_handler->disable_log_bin_local();
      print current_time_us() . " Set read_only=0 on the new master.\n";
      $new_master_handler->disable_read_only();
      ## Creating an app user on the new master
      #print current_time_us() . " Creating app user on the new master..\n";
      #FIXME_xxx_create_app_user($new_master_handler);
      $new_master_handler->enable_log_bin_local();
      $new_master_handler->disconnect();
      
      print "Enabling the VIP - $vip on the new master - $new_master_host \n";
      &start_vip(); 
      ## Update master ip on the catalog database, etc
      $exit_code = 0;
    };
    if ($@) {
      warn "Got Error: $@\n";
      exit $exit_code;
    }
    exit $exit_code;
  }
  elsif ( $command eq "status" ) {
    # do nothing
    exit 0;
  }
  else {
    &usage();
    exit 1;
  }
}
# A simple system call that enable the VIP on the new master
sub start_vip() {
    `ssh $sshuser\@$new_master_host  -o StrictHostKeyChecking=no \" $ssh_start_vip \"`;
}
# A simple system call that disable the VIP on the old_master
sub stop_vip() {
    `ssh $sshuser\@$orig_master_host  -o StrictHostKeyChecking=no \" $ssh_stop_vip \"`;
}
sub usage {
  print
"Usage: master_ip_online_change --command=start|stop|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";
  die;
}
EOF
7、手动切换命令
关闭监控
masterha_stop -conf=/etc/app1.cnf

手动切换命令
masterha_master_switch --conf=/etc/app1.cnf    --master_state=alive --new_master_host=slave01 --new_master_port=3306  --orig_master_is_new_slave

参数含义
--master_state=alive
    设置为 alive 模式,masterha_master_switch 开始在线主库切换操作。

--orig_master_is_new_slave
   此参数是将原master变为slave节点,如果不加此参数,原来的master将不启动 
   
--new_master_host=(hostname)
    新主机地址,可选参数,这个参数在你明确新的主库的主机,非常有用。(这就意味着你不需要让MHA来决定新的主库)。如果不设置此参数,MHA 将会利用自动failover的规则来选择新的主库。如果设置--new_master_host,MHA选择此主机为新的主库,如果不能成为主库,MHA将会退出
  • 12
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值