共计 9391 个字符,预计需要花费 24 分钟才能阅读完成。
行业资讯
数据库
MHA 在线切换脚本 master_ip_online_change 如何结合 VIP
这篇文章主要介绍 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”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注丸趣 TV 行业资讯频道!
正文完