返回顶部
首页 > 资讯 > 数据库 >MHA在线切换脚本master_ip_online_change如何结合VIP
  • 422
分享到

MHA在线切换脚本master_ip_online_change如何结合VIP

2024-04-02 19:04:59 422人浏览 薄情痞子
摘要

这篇文章主要介绍MHA在线切换脚本master_ip_online_change如何结合VIP,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!结合vip的主库在线切换脚本master_

这篇文章主要介绍MHA在线切换脚本master_ip_online_change如何结合VIP,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

结合vip的主库在线切换脚本master_ip_online_change:

#!/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 $ssh_user = "dbMon";
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,   $app_vip, $netmask, $interface, 
);
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,
  'app_vip=s'                => \$app_vip,
  'netmask=i'                => \$netmask,
  'interface=s'              => \$interface,
);
my $ssh_start_vip = "sudo ip addr add $app_vip/$netmask dev $interface";
my $ssh_stop_vip = "sudo ip addr delete $app_vip/$netmask dev $interface";
my $ssh_flush_arp = "sudo arping -c 4 -A -I $interface $app_vip";
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} );
      }
      print "Disabling the app_vip on old master: $orig_master_host \n";
      &stop_vip(); 
      ## 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
      $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();
      ## Update master ip on the catalog database, etc
      print "Enabling the app_vip  on the new master - $new_master_host \n";
      &start_vip();
      $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 app_vip on the new master 
sub start_vip() {
    `ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
    `ssh $ssh_user\@$new_master_host \" $ssh_flush_arp \"`;
}
# A simple system call that disable the app_vip on the old_master
sub stop_vip() {
    `ssh $ssh_user\@$orig_master_host \" $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;
}

以上是“MHA在线切换脚本master_ip_online_change如何结合VIP”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注编程网数据库频道!

您可能感兴趣的文档:

--结束END--

本文标题: MHA在线切换脚本master_ip_online_change如何结合VIP

本文链接: https://lsjlt.com/news/67004.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • MHA在线切换脚本master_ip_online_change如何结合VIP
    这篇文章主要介绍MHA在线切换脚本master_ip_online_change如何结合VIP,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!结合vip的主库在线切换脚本master_...
    99+
    2024-04-02
  • MHA故障切换脚本master_ip_failover结合VIP
     MHA故障切换脚本master_ip_failover结合VIP:#!/usr/bin/env perl use strict; use warnings ...
    99+
    2024-04-02
  • MHA如何实现VIP切换用到脚本
    小编给大家分享一下MHA如何实现VIP切换用到脚本,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!在MHA Manager端配置中...
    99+
    2024-04-02
  • 如何实现IP动态切换bat脚本
    这篇文章将为大家详细讲解有关如何实现IP动态切换bat脚本,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。新建"IP切换脚本.bat"文件,将下列代码复制进去,保存,并加入启动项,这样每...
    99+
    2023-06-08
  • windows7如何快速切换IP的脚本整理
    我在家使用动态IP,在公司使用固定IP,所以经常需要来回切换IP设置,非常麻烦!今天实在忍无可忍,就整理了一份脚本以减轻来回切换IP的烦恼!恐有遗忘,谨作记录! [plain] @echo off rem //设置变量 ...
    99+
    2023-05-29
    win7 切换IP IP 脚本
  • 【Python】Windows如何在cmd中切换python版本
    相信很多小伙伴都会有像我一样经历,在windows中装了很多python版本,那么如果我们正式使用的时候应该如何切换呢? 【方法一】从环境变量中切换python第一步: 打开环境变量第二步:打...
    99+
    2023-09-07
    python windows 开发语言
  • shell如何结合expect写批量scp脚本工具
    这篇文章给大家分享的是有关shell如何结合expect写批量scp脚本工具的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。在部署一个任务时,其中有一项必须的过程就是将一些文件,如安装包发送到大量的服务器上去。虽然...
    99+
    2023-06-09
  • SpringBoot结合IDEA自带Maven插件如何快速切换profile
    目录一、前言二、配置详情2.1 pom.xml修改2.2 bootstrap.yml/application.yml修改一、前言 IDEA是目前 Java 开发者中使用最多的开发工具...
    99+
    2023-03-06
    Spring Boot切换profile Spring Boot maven插件切换profile
  • 如何在linux中切换php版本,注意是linux
    在Linux中切换PHP版本可以使用以下步骤: 安装多个PHP版本 在Linux中,可以使用不同的方式安装多个PHP版本,例如使用apt-get或yum安装不同的PHP版本。安装完成后,可以通过以下命令查看已安装的PHP版本: $ sudo...
    99+
    2023-09-06
    php linux apache
  • 如何在ubuntu中切换使用不同版本的python
    目录引言步骤总结引言 有时我们不得不在同一台 ubuntu 中使用不同版本的 python 环境。本文的介绍就是可以在 ubuntu 上同时安装几个不同版本的 python,然后你可...
    99+
    2023-02-22
    ubuntu切换Python版本 ubuntu切换python3 ubuntu切换Python环境
  • 如何结合ChatGPT PHP实现在线客服功能?
    如何结合ChatGPT PHP实现在线客服功能?在现代化的商业环境中,为了更好地满足用户的需求,许多企业选择在网站上提供在线客服功能。在线客服可以为用户提供实时的咨询和解答问题的服务,帮助用户更好地了解产品和服务。而ChatGPT是Open...
    99+
    2023-10-24
    在线客服 ChatGPT PHP
  • 如何编写一个shell for循环与case结合的脚本
    这篇文章主要讲解了“如何编写一个shell for循环与case结合的脚本”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何编写一个shell for循环与case结合的脚本”吧!核心代码:...
    99+
    2023-06-09
  • 手把手教你Windows如何在cmd中切换python版本
    目录【方法一】从环境变量中切换python第一步: 打开环境变量第二步:打开系统变量中Path变量第三步:将你想使用的Python版本提前第四步:使用pip安装第三方库【方法二】直接...
    99+
    2023-05-16
    cmd怎么切换python版本 windows切换python版本 更换python版本
  • 如何在宝塔面板中安装和切换PHP版本
    如何在宝塔面板中安装和切换PHP版本 PHP作为一种流行的服务器端脚本语言,在网站开发中起到至关重要的作用。为了适应不同的项目需求,我们经常需要在服务器上安装和切换不同版本的PHP。而...
    99+
    2024-03-05
    宝塔面板 php安装 php版本切换
  • Vue-router结合transition如何实现app前进后退动画切换效果
    这篇文章主要为大家展示了“Vue-router结合transition如何实现app前进后退动画切换效果”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Vue-r...
    99+
    2024-04-02
  • 如何在Shell中实现“多线程”执行脚本文件
    本篇内容介绍了“如何在Shell中实现“多线程”执行脚本文件”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!即比如我有100个可执行文件,互相...
    99+
    2023-06-09
  • 如何结合 Go 语言和 Shell 脚本解决 LeetCode 上的算法题?
    近年来,Go 语言和 Shell 脚本都成为了非常流行的编程语言。它们各自有其独特的特点和优势,但是在某些情况下,结合使用这两种语言可以更加高效地完成一些任务,比如解决 LeetCode 上的算法题。 在本文中,我们将介绍如何结合使用 Go...
    99+
    2023-07-21
    load shell leetcode
  • 如何使用vbs实现一个查看局域网在线IP的脚本
    这篇文章给大家分享的是有关如何使用vbs实现一个查看局域网在线IP的脚本的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。代码如下:strSubNet = "192.168.1." Set obj...
    99+
    2023-06-08
  • 如何在CentOS/RHEL系统上生成补丁合规报告的Bash脚本
    本篇文章为大家展示了如何在CentOS/RHEL系统上生成补丁合规报告的Bash脚本,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。如果你运行的是大型 Linux 环境,那么你可能已经将 Red Ha...
    99+
    2023-06-16
  • 如何实现用Shell脚本监控服务器在线状态和邮件报警
    本篇内容主要讲解“如何实现用Shell脚本监控服务器在线状态和邮件报警”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何实现用Shell脚本监控服务器在线状态和邮件报警”吧!对于服务器来说在线率...
    99+
    2023-06-09
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作