From 08a483df6bbe1631537a06b18a39ec0f212fc0ab Mon Sep 17 00:00:00 2001 From: frank-cizmich Date: Wed, 27 May 2015 18:36:13 -0300 Subject: [PATCH] pt-archiver multple slave lag and OptionParser repeatable option --- bin/pt-archiver | 61 +++++++++++++++++++++++++++++++++++---------- lib/OptionParser.pm | 25 +++++++++++++++---- 2 files changed, 68 insertions(+), 18 deletions(-) diff --git a/bin/pt-archiver b/bin/pt-archiver index 7de572c6..67941cb0 100755 --- a/bin/pt-archiver +++ b/bin/pt-archiver @@ -784,6 +784,7 @@ sub new { 'default' => 1, 'cumulative' => 1, 'negatable' => 1, + 'repeatable' => 1, # means it can be specified more than once ); my $self = { @@ -974,6 +975,7 @@ sub _pod_to_specs { desc => $para . (defined $attribs{default} ? " (default $attribs{default})" : ''), group => ($attribs{'group'} ? $attribs{'group'} : 'default'), + attributes => \%attribs }; } while ( $para = <$fh> ) { @@ -1027,6 +1029,7 @@ sub _parse_specs { $opt->{is_negatable} = $opt->{spec} =~ m/!/ ? 1 : 0; $opt->{is_cumulative} = $opt->{spec} =~ m/\+/ ? 1 : 0; + $opt->{is_repeatable} = $opt->{attributes}->{repeatable} ? 1 : 0; $opt->{is_required} = $opt->{desc} =~ m/required/ ? 1 : 0; $opt->{group} ||= 'default'; @@ -1170,11 +1173,21 @@ sub _set_option { return; } else { - $opt->{value} = $val; + if ($opt->{is_repeatable}) { + push @{$opt->{value}} , $val; + } + else { + $opt->{value} = $val; + } } } else { - $opt->{value} = $val; + if ($opt->{is_repeatable}) { + push @{$opt->{value}} , $val; + } + else { + $opt->{value} = $val; + } } $opt->{got} = 1; PTDEBUG && _d('Got option', $long, '=', $val); @@ -1628,6 +1641,14 @@ sub _read_config_file { $parse = 0; next LINE; } + + if ( $parse + && !$self->has('version-check') + && $line =~ /version-check/ + ) { + next LINE; + } + if ( $parse && (my($opt, $arg) = $line =~ m/^\s*([^=\s]+?)(?:\s*=\s*(.*?)\s*)?$/) ) { @@ -5713,17 +5734,23 @@ sub main { # ######################################################################## # Get lag dbh. # ######################################################################## - my $lag_dbh; + my @lag_dbh; my $ms; if ( $o->get('check-slave-lag') ) { 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( + my $lag_slaves_dsn = $o->get('check-slave-lag'); + $ms = new MasterSlave( OptionParser => $o, DSNParser => $dp, Quoter => $q, ); + # we get each slave's connection handler (and its id, for debug and reporting) + for my $slave (@$lag_slaves_dsn) { + my $dsn = $dp->parse($slave, $dsn_defaults); + my $lag_dbh = $dp->get_dbh($dp->get_cxn_params($dsn), { AutoCommit => 1 }); + my $lag_id = $ms->short_host($dsn); + push @lag_dbh , {'dbh' => $lag_dbh, 'id' => $lag_id} + } } # ######################################################################## @@ -6305,12 +6332,19 @@ sub main { } # Check slave lag and wait if slave is too far behind. - if ( $lag_dbh ) { - my $lag = $ms->get_slave_lag($lag_dbh); - while ( !defined $lag || $lag > $o->get('max-lag') ) { - PTDEBUG && _d('Sleeping: slave lag is', $lag); - sleep($o->get('check-interval')); - $lag = $ms->get_slave_lag($lag_dbh); + foreach my $lag_server (@lag_dbh) { + my $lag_dbh = $lag_server->{'dbh'}; + my $id = $lag_server->{'id'}; + if ( $lag_dbh ) { + my $lag = $ms->get_slave_lag($lag_dbh); + while ( !defined $lag || $lag > $o->get('max-lag') ) { + PTDEBUG && _d("Sleeping: slave lag for server '$id' is", $lag); + if ($o->got('progress')) { + _d("Sleeping: slave lag for server '$id' is", $lag); + } + sleep($o->get('check-interval')); + $lag = $ms->get_slave_lag($lag_dbh); + } } } } # ROW @@ -6883,9 +6917,10 @@ How often to check for slave lag if L<"--check-slave-lag"> is given. =item --check-slave-lag -type: string +type: string; repeatable: yes Pause archiving until the specified DSN's slave lag is less than L<"--max-lag">. +This option can be specified multiple times for checking more than one slave. =item --columns diff --git a/lib/OptionParser.pm b/lib/OptionParser.pm index 99a6fa8c..dbdff878 100644 --- a/lib/OptionParser.pm +++ b/lib/OptionParser.pm @@ -69,6 +69,7 @@ sub new { 'default' => 1, 'cumulative' => 1, 'negatable' => 1, + 'repeatable' => 1, # means it can be specified more than once ); my $self = { @@ -308,6 +309,7 @@ sub _pod_to_specs { desc => $para . (defined $attribs{default} ? " (default $attribs{default})" : ''), group => ($attribs{'group'} ? $attribs{'group'} : 'default'), + attributes => \%attribs }; } while ( $para = <$fh> ) { @@ -377,6 +379,7 @@ sub _parse_specs { $opt->{is_negatable} = $opt->{spec} =~ m/!/ ? 1 : 0; $opt->{is_cumulative} = $opt->{spec} =~ m/\+/ ? 1 : 0; + $opt->{is_repeatable} = $opt->{attributes}->{repeatable} ? 1 : 0; $opt->{is_required} = $opt->{desc} =~ m/required/ ? 1 : 0; $opt->{group} ||= 'default'; @@ -568,11 +571,23 @@ sub _set_option { return; } else { - $opt->{value} = $val; + # have to make value an array if it is 'repeatable' + if ($opt->{is_repeatable}) { + push @{$opt->{value}} , $val; + } + else { + $opt->{value} = $val; + } } } else { - $opt->{value} = $val; + # have to make value an array if it is 'repeatable' + if ($opt->{is_repeatable}) { + push @{$opt->{value}} , $val; + } + else { + $opt->{value} = $val; + } } $opt->{got} = 1; PTDEBUG && _d('Got option', $long, '=', $val); @@ -1135,9 +1150,9 @@ sub _read_config_file { # Silently ignore option [no]-version-check if it is unsupported and it comes from a config file # TODO: Ideally , this should be generalized for all unsupported options that come from global files - if ( $parse - && !$self->has('version-check') - && $line =~ /version-check/ + if ( $parse + && !$self->has('version-check') + && $line =~ /version-check/ ) { next LINE; }