mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-28 17:15:44 +00:00
Rewrite how MasterSlave handles --recursion-methods.
This commit is contained in:
@@ -1872,66 +1872,6 @@ use warnings FATAL => 'all';
|
||||
use English qw(-no_match_vars);
|
||||
use constant PTDEBUG => $ENV{PTDEBUG} || 0;
|
||||
|
||||
sub new {
|
||||
my ( $class, %args ) = @_;
|
||||
my $self = {
|
||||
%args,
|
||||
replication_thread => {},
|
||||
};
|
||||
return bless $self, $class;
|
||||
}
|
||||
|
||||
sub get_slaves {
|
||||
my ($self, %args) = @_;
|
||||
my @required_args = qw(make_cxn recursion_method recurse DSNParser Quoter);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless exists $args{$arg};
|
||||
}
|
||||
my ($make_cxn, $methods, $recurse, $dp) = @args{@required_args};
|
||||
|
||||
my $slaves = [];
|
||||
|
||||
PTDEBUG && _d('Slave recursion method:', $methods);
|
||||
if ( !@$methods || grep { m/processlist|hosts/i } @$methods ) {
|
||||
my @required_args = qw(dbh dsn);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($dbh, $dsn) = @args{@required_args};
|
||||
|
||||
$self->recurse_to_slaves(
|
||||
{ dbh => $dbh,
|
||||
dsn => $dsn,
|
||||
dsn_parser => $dp,
|
||||
recurse => $recurse,
|
||||
method => $methods,
|
||||
callback => sub {
|
||||
my ( $dsn, $dbh, $level, $parent ) = @_;
|
||||
return unless $level;
|
||||
PTDEBUG && _d('Found slave:', $dp->as_string($dsn));
|
||||
push @$slaves, $make_cxn->(dsn => $dsn, dbh => $dbh);
|
||||
return;
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
elsif ( @$methods && $methods->[0] =~ m/^dsn=/i ) {
|
||||
(my $dsn_table_dsn = join ",", @$methods) =~ s/^dsn=//i;
|
||||
$slaves = $self->get_cxn_from_dsn_table(
|
||||
%args,
|
||||
dsn_table_dsn => $dsn_table_dsn,
|
||||
);
|
||||
}
|
||||
elsif ( !@$methods || $methods->[0] =~ m/none/i ) {
|
||||
PTDEBUG && _d('Not getting to slaves');
|
||||
}
|
||||
else {
|
||||
die "Unexpected recursion methods: @$methods";
|
||||
}
|
||||
|
||||
return $slaves;
|
||||
}
|
||||
|
||||
sub check_recursion_method {
|
||||
my ($methods) = @_;
|
||||
|
||||
@@ -1951,13 +1891,93 @@ sub check_recursion_method {
|
||||
}
|
||||
}
|
||||
|
||||
sub new {
|
||||
my ( $class, %args ) = @_;
|
||||
my @required_args = qw(OptionParser DSNParser Quoter);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my $self = {
|
||||
%args,
|
||||
replication_thread => {},
|
||||
};
|
||||
return bless $self, $class;
|
||||
}
|
||||
|
||||
sub get_slaves {
|
||||
my ($self, %args) = @_;
|
||||
my @required_args = qw(make_cxn);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($make_cxn) = @args{@required_args};
|
||||
|
||||
my $slaves = [];
|
||||
my $dp = $self->{DSNParser};
|
||||
my $methods = $self->_resolve_recursion_methods($args{dsn});
|
||||
|
||||
if ( grep { m/processlist|hosts/i } @$methods ) {
|
||||
my @required_args = qw(dbh dsn);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($dbh, $dsn) = @args{@required_args};
|
||||
|
||||
$self->recurse_to_slaves(
|
||||
{ dbh => $dbh,
|
||||
dsn => $dsn,
|
||||
callback => sub {
|
||||
my ( $dsn, $dbh, $level, $parent ) = @_;
|
||||
return unless $level;
|
||||
PTDEBUG && _d('Found slave:', $dp->as_string($dsn));
|
||||
push @$slaves, $make_cxn->(dsn => $dsn, dbh => $dbh);
|
||||
return;
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
elsif ( $methods->[0] =~ m/^dsn=/i ) {
|
||||
(my $dsn_table_dsn = join ",", @$methods) =~ s/^dsn=//i;
|
||||
$slaves = $self->get_cxn_from_dsn_table(
|
||||
%args,
|
||||
dsn_table_dsn => $dsn_table_dsn,
|
||||
);
|
||||
}
|
||||
elsif ( $methods->[0] =~ m/none/i ) {
|
||||
PTDEBUG && _d('Not getting to slaves');
|
||||
}
|
||||
else {
|
||||
die "Unexpected recursion methods: @$methods";
|
||||
}
|
||||
|
||||
return $slaves;
|
||||
}
|
||||
|
||||
sub _resolve_recursion_methods {
|
||||
my ($self, $dsn) = @_;
|
||||
my $o = $self->{OptionParser};
|
||||
if ( $o->got('recursion-method') ) {
|
||||
return $o->get('recursion-method');
|
||||
}
|
||||
elsif ( $dsn && ($dsn->{P} || 3306) != 3306 ) {
|
||||
PTDEBUG && _d('Port number is non-standard; using only hosts method');
|
||||
return [qw(hosts)];
|
||||
}
|
||||
else {
|
||||
return $o->get('recursion-method');
|
||||
}
|
||||
}
|
||||
|
||||
sub recurse_to_slaves {
|
||||
my ( $self, $args, $level ) = @_;
|
||||
$level ||= 0;
|
||||
my $dp = $args->{dsn_parser};
|
||||
my $dsn = $args->{dsn};
|
||||
my $dp = $self->{DSNParser};
|
||||
my $recurse = $args->{recurse} || $self->{OptionParser}->get('recurse');
|
||||
my $dsn = $args->{dsn};
|
||||
|
||||
if ( $args->{method} && lc($args->{method}->[0] || '') eq 'none' ) {
|
||||
my $methods = $self->_resolve_recursion_methods($dsn);
|
||||
PTDEBUG && _d('Recursion methods:', @$methods);
|
||||
if ( lc($methods->[0]) eq 'none' ) {
|
||||
PTDEBUG && _d('Not recursing to slaves');
|
||||
return;
|
||||
}
|
||||
@@ -1992,11 +2012,11 @@ sub recurse_to_slaves {
|
||||
|
||||
$args->{callback}->($dsn, $dbh, $level, $args->{parent});
|
||||
|
||||
if ( !defined $args->{recurse} || $level < $args->{recurse} ) {
|
||||
if ( !defined $recurse || $level < $recurse ) {
|
||||
|
||||
my @slaves =
|
||||
grep { !$_->{master_id} || $_->{master_id} == $id } # Only my slaves.
|
||||
$self->find_slave_hosts($dp, $dbh, $dsn, $args->{method});
|
||||
$self->find_slave_hosts($dp, $dbh, $dsn, $methods);
|
||||
|
||||
foreach my $slave ( @slaves ) {
|
||||
PTDEBUG && _d('Recursing from',
|
||||
@@ -2010,14 +2030,12 @@ sub recurse_to_slaves {
|
||||
sub find_slave_hosts {
|
||||
my ( $self, $dsn_parser, $dbh, $dsn, $methods ) = @_;
|
||||
|
||||
my @methods = $self->_resolve_recursion_methods($methods, $dsn);
|
||||
|
||||
PTDEBUG && _d('Looking for slaves on', $dsn_parser->as_string($dsn),
|
||||
'using methods', @methods);
|
||||
'using methods', @$methods);
|
||||
|
||||
my @slaves;
|
||||
METHOD:
|
||||
foreach my $method ( @methods ) {
|
||||
foreach my $method ( @$methods ) {
|
||||
my $find_slaves = "_find_slaves_by_$method";
|
||||
PTDEBUG && _d('Finding slaves with', $find_slaves);
|
||||
@slaves = $self->$find_slaves($dsn_parser, $dbh, $dsn);
|
||||
@@ -2028,15 +2046,6 @@ sub find_slave_hosts {
|
||||
return @slaves;
|
||||
}
|
||||
|
||||
sub _resolve_recursion_methods {
|
||||
my ($self, $methods, $dsn) = @_;
|
||||
|
||||
return @$methods if $methods && @$methods;
|
||||
return qw( processlist hosts ) if (($dsn->{P} || 3306) == 3306);
|
||||
PTDEBUG && _d('Port number is non-standard; using only hosts method');
|
||||
return qw( hosts );
|
||||
}
|
||||
|
||||
sub _find_slaves_by_processlist {
|
||||
my ( $self, $dsn_parser, $dbh, $dsn ) = @_;
|
||||
|
||||
@@ -2529,13 +2538,16 @@ sub reset_known_replication_threads {
|
||||
|
||||
sub get_cxn_from_dsn_table {
|
||||
my ($self, %args) = @_;
|
||||
my @required_args = qw(dsn_table_dsn make_cxn DSNParser Quoter);
|
||||
my @required_args = qw(dsn_table_dsn make_cxn);
|
||||
foreach my $arg ( @required_args ) {
|
||||
die "I need a $arg argument" unless $args{$arg};
|
||||
}
|
||||
my ($dsn_table_dsn, $make_cxn, $dp, $q) = @args{@required_args};
|
||||
my ($dsn_table_dsn, $make_cxn) = @args{@required_args};
|
||||
PTDEBUG && _d('DSN table DSN:', $dsn_table_dsn);
|
||||
|
||||
my $dp = $self->{DSNParser};
|
||||
my $q = $self->{Quoter};
|
||||
|
||||
my $dsn = $dp->parse($dsn_table_dsn);
|
||||
my $dsn_table;
|
||||
if ( $dsn->{D} && $dsn->{t} ) {
|
||||
@@ -3383,16 +3395,15 @@ sub main {
|
||||
|
||||
# Despite the name, recursing to slaves actually begins at the specified
|
||||
# server, so the named server may also be included.
|
||||
my $ms = new MasterSlave();
|
||||
my $ms = new MasterSlave(
|
||||
OptionParser => $o,
|
||||
DSNParser => $dp,
|
||||
Quoter => $q,
|
||||
);
|
||||
$ms->recurse_to_slaves(
|
||||
{ dbh => $dbh,
|
||||
dsn => $master_dsn,
|
||||
dsn_parser => $dp,
|
||||
recurse => $o->get('recurse'),
|
||||
method => $o->got('recursion-method')
|
||||
? $o->get('recursion-method')
|
||||
: [],
|
||||
callback => sub {
|
||||
{ dbh => $dbh,
|
||||
dsn => $master_dsn,
|
||||
callback => sub {
|
||||
my ( $dsn, $dbh, $level, $parent ) = @_;
|
||||
if ( !$parent ) {
|
||||
$root = $dsn;
|
||||
|
Reference in New Issue
Block a user