Merge fix-953141-recursion-method-array

This commit is contained in:
Daniel Nichter
2012-08-02 12:01:34 -06:00
12 changed files with 975 additions and 544 deletions

View File

@@ -3078,8 +3078,31 @@ use warnings FATAL => 'all';
use English qw(-no_match_vars);
use constant PTDEBUG => $ENV{PTDEBUG} || 0;
sub check_recursion_method {
my ($methods) = @_;
if ( @$methods != 1 ) {
if ( grep({ !m/processlist|hosts/i } @$methods)
&& $methods->[0] !~ /^dsn=/i )
{
die "Invalid combination of recursion methods: "
. join(", ", map { defined($_) ? $_ : 'undef' } @$methods) . ". "
. "Only hosts and processlist may be combined.\n"
}
}
else {
my ($method) = @$methods;
die "Invalid recursion method: " . ( $method || 'undef' )
unless $method && $method =~ m/^(?:processlist$|hosts$|none$|dsn=)/i;
}
}
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 => {},
@@ -3089,28 +3112,27 @@ sub new {
sub get_slaves {
my ($self, %args) = @_;
my @required_args = qw(make_cxn OptionParser DSNParser Quoter);
my @required_args = qw(make_cxn);
foreach my $arg ( @required_args ) {
die "I need a $arg argument" unless $args{$arg};
}
my ($make_cxn, $o, $dp) = @args{@required_args};
my ($make_cxn) = @args{@required_args};
my $slaves = [];
my $method = $o->get('recursion-method');
PTDEBUG && _d('Slave recursion method:', $method);
if ( !$method || $method =~ m/processlist|hosts/i ) {
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,
dsn_parser => $dp,
recurse => $o->get('recurse'),
method => $o->get('recursion-method'),
callback => sub {
{ dbh => $dbh,
dsn => $dsn,
callback => sub {
my ( $dsn, $dbh, $level, $parent ) = @_;
return unless $level;
PTDEBUG && _d('Found slave:', $dp->as_string($dsn));
@@ -3120,31 +3142,48 @@ sub get_slaves {
}
);
}
elsif ( $method =~ m/^dsn=/i ) {
my ($dsn_table_dsn) = $method =~ m/^dsn=(.+)/i;
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 ( $method =~ m/none/i ) {
elsif ( $methods->[0] =~ m/none/i ) {
PTDEBUG && _d('Not getting to slaves');
}
else {
die "Invalid --recursion-method: $method. Valid values are: "
. "dsn=DSN, hosts, or processlist.\n";
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 ( lc($args->{method} || '') 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;
}
@@ -3179,11 +3218,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',
@@ -3195,25 +3234,14 @@ sub recurse_to_slaves {
}
sub find_slave_hosts {
my ( $self, $dsn_parser, $dbh, $dsn, $method ) = @_;
my ( $self, $dsn_parser, $dbh, $dsn, $methods ) = @_;
my @methods = qw(processlist hosts);
if ( $method ) {
@methods = grep { $_ ne $method } @methods;
unshift @methods, $method;
}
else {
if ( ($dsn->{P} || 3306) != 3306 ) {
PTDEBUG && _d('Port number is non-standard; using only hosts method');
@methods = qw(hosts);
}
}
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);
@@ -3716,13 +3744,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} ) {
@@ -4054,7 +4085,11 @@ sub main {
my $dsn_defaults = $dp->parse_options($o);
my $dsn = $dp->parse($o->get('check-slave-lag'), $dsn_defaults);
$lag_dbh = $dp->get_dbh($dp->get_cxn_params($dsn), { AutoCommit => 1 });
$ms = new MasterSlave();
$ms = new MasterSlave(
OptionParser => $o,
DSNParser => $dp,
Quoter => $q,
);
}
# ########################################################################