diff --git a/bin/pt-config-diff b/bin/pt-config-diff index e2ea45a3..f4d7be39 100755 --- a/bin/pt-config-diff +++ b/bin/pt-config-diff @@ -2138,23 +2138,24 @@ sub new { } my $self = { - dsn => $dsn, - dbh => $args{dbh}, - dsn_name => $dp->as_string($dsn, [qw(h P S)]), - hostname => '', - set => $args{set}, - NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, - dbh_set => 0, - OptionParser => $o, - DSNParser => $dp, + dsn => $dsn, + dbh => $args{dbh}, + dsn_name => $dp->as_string($dsn, [qw(h P S)]), + hostname => '', + set => $args{set}, + NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, + dbh_set => 0, + OptionParser => $o, + DSNParser => $dp, is_cluster_node => undef, + parent => $args{parent}, }; return bless $self, $class; } sub connect { - my ( $self ) = @_; + my ( $self, %opts ) = @_; my $dsn = $self->{dsn}; my $dp = $self->{DSNParser}; my $o = $self->{OptionParser}; @@ -2165,11 +2166,18 @@ sub connect { $dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: "); $self->{asked_for_pass} = 1; } - $dbh = $dp->get_dbh($dp->get_cxn_params($dsn), { AutoCommit => 1 }); + $dbh = $dp->get_dbh( + $dp->get_cxn_params($dsn), + { + AutoCommit => 1, + %opts, + }, + ); } - PTDEBUG && _d($dbh, 'Connected dbh to', $self->{name}); - return $self->set_dbh($dbh); + $dbh = $self->set_dbh($dbh); + PTDEBUG && _d($dbh, 'Connected dbh to', $self->{hostname},$self->{dsn_name}); + return $dbh; } sub set_dbh { @@ -2192,6 +2200,11 @@ sub set_dbh { $self->{hostname} = $hostname; } + if ( $self->{parent} ) { + PTDEBUG && _d($dbh, 'Setting InactiveDestroy=1 in parent'); + $dbh->{InactiveDestroy} = 1; + } + if ( my $set = $self->{set}) { $set->($dbh); } @@ -2201,6 +2214,13 @@ sub set_dbh { return $dbh; } +sub lost_connection { + my ($self, $e) = @_; + return 0 unless $e; + return $e =~ m/MySQL server has gone away/ + || $e =~ m/Lost connection to MySQL server/; +} + sub dbh { my ($self) = @_; return $self->{dbh}; @@ -2219,12 +2239,21 @@ sub name { sub DESTROY { my ($self) = @_; - if ( $self->{dbh} - && blessed($self->{dbh}) - && $self->{dbh}->can("disconnect") ) { - PTDEBUG && _d('Disconnecting dbh', $self->{dbh}, $self->{name}); + + PTDEBUG && _d('Destroying cxn'); + + if ( $self->{parent} ) { + PTDEBUG && _d($self->{dbh}, 'Not disconnecting dbh in parent'); + } + elsif ( $self->{dbh} + && blessed($self->{dbh}) + && $self->{dbh}->can("disconnect") ) + { + PTDEBUG && _d($self->{dbh}, 'Disconnecting dbh on', $self->{hostname}, + $self->{dsn_name}); $self->{dbh}->disconnect(); } + return; } diff --git a/bin/pt-deadlock-logger b/bin/pt-deadlock-logger index 56114eb6..d7a78adc 100755 --- a/bin/pt-deadlock-logger +++ b/bin/pt-deadlock-logger @@ -2518,9 +2518,10 @@ sub connect { }, ); } - PTDEBUG && _d($dbh, 'Connected dbh to', $self->{name}); - return $self->set_dbh($dbh); + $dbh = $self->set_dbh($dbh); + PTDEBUG && _d($dbh, 'Connected dbh to', $self->{hostname},$self->{dsn_name}); + return $dbh; } sub set_dbh { @@ -2583,14 +2584,17 @@ sub name { sub DESTROY { my ($self) = @_; + PTDEBUG && _d('Destroying cxn'); + if ( $self->{parent} ) { - PTDEBUG && _d('Not disconnecting dbh in parent'); + PTDEBUG && _d($self->{dbh}, 'Not disconnecting dbh in parent'); } elsif ( $self->{dbh} && blessed($self->{dbh}) && $self->{dbh}->can("disconnect") ) { - PTDEBUG && _d('Disconnecting dbh', $self->{dbh}, $self->{name}); + PTDEBUG && _d($self->{dbh}, 'Disconnecting dbh on', $self->{hostname}, + $self->{dsn_name}); $self->{dbh}->disconnect(); } @@ -4256,9 +4260,9 @@ sub main { if ( my $src_dsn_string = shift @ARGV ) { $src = Cxn->new( dsn_string => $src_dsn_string, + parent => $o->get('daemonize'), DSNParser => $dp, OptionParser => $o, - parent => $o->get('daemonize'), ); } @@ -4267,9 +4271,9 @@ sub main { $dst = Cxn->new( dsn => $dst_dsn, prev_dsn => ($src ? $src->dsn : undef), + parent => $o->get('daemonize'), DSNParser => $dp, OptionParser => $o, - parent => $o->get('daemonize'), ); } @@ -4331,7 +4335,13 @@ sub main { $daemon->make_PID_file(); } - # Let Cxn::DESTROY() disconenct the dbh. + # If we daemonized, the parent has already exited and we're the child. + # We shared a copy of every Cxn with the parent, and the parent's copies + # were destroyed but the dbhs were not disconnected because the parent + # attrib was true. Now, as the child, set it false so the dbhs will be + # disconnected when our Cxn copies are destroyed. If we didn't daemonize, + # then we're not really a parent (since we have no children), so set it + # false to auto-disconnect the dbhs when our Cxns are destroyed. $src->{parent} = 0; $dst->{parent} = 0 if $dst; diff --git a/bin/pt-fk-error-logger b/bin/pt-fk-error-logger index 86a27456..64491d01 100755 --- a/bin/pt-fk-error-logger +++ b/bin/pt-fk-error-logger @@ -1639,23 +1639,24 @@ sub new { } my $self = { - dsn => $dsn, - dbh => $args{dbh}, - dsn_name => $dp->as_string($dsn, [qw(h P S)]), - hostname => '', - set => $args{set}, - NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, - dbh_set => 0, - OptionParser => $o, - DSNParser => $dp, + dsn => $dsn, + dbh => $args{dbh}, + dsn_name => $dp->as_string($dsn, [qw(h P S)]), + hostname => '', + set => $args{set}, + NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, + dbh_set => 0, + OptionParser => $o, + DSNParser => $dp, is_cluster_node => undef, + parent => $args{parent}, }; return bless $self, $class; } sub connect { - my ( $self ) = @_; + my ( $self, %opts ) = @_; my $dsn = $self->{dsn}; my $dp = $self->{DSNParser}; my $o = $self->{OptionParser}; @@ -1666,11 +1667,18 @@ sub connect { $dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: "); $self->{asked_for_pass} = 1; } - $dbh = $dp->get_dbh($dp->get_cxn_params($dsn), { AutoCommit => 1 }); + $dbh = $dp->get_dbh( + $dp->get_cxn_params($dsn), + { + AutoCommit => 1, + %opts, + }, + ); } - PTDEBUG && _d($dbh, 'Connected dbh to', $self->{name}); - return $self->set_dbh($dbh); + $dbh = $self->set_dbh($dbh); + PTDEBUG && _d($dbh, 'Connected dbh to', $self->{hostname},$self->{dsn_name}); + return $dbh; } sub set_dbh { @@ -1693,6 +1701,11 @@ sub set_dbh { $self->{hostname} = $hostname; } + if ( $self->{parent} ) { + PTDEBUG && _d($dbh, 'Setting InactiveDestroy=1 in parent'); + $dbh->{InactiveDestroy} = 1; + } + if ( my $set = $self->{set}) { $set->($dbh); } @@ -1727,12 +1740,21 @@ sub name { sub DESTROY { my ($self) = @_; - if ( $self->{dbh} - && blessed($self->{dbh}) - && $self->{dbh}->can("disconnect") ) { - PTDEBUG && _d('Disconnecting dbh', $self->{dbh}, $self->{name}); + + PTDEBUG && _d('Destroying cxn'); + + if ( $self->{parent} ) { + PTDEBUG && _d($self->{dbh}, 'Not disconnecting dbh in parent'); + } + elsif ( $self->{dbh} + && blessed($self->{dbh}) + && $self->{dbh}->can("disconnect") ) + { + PTDEBUG && _d($self->{dbh}, 'Disconnecting dbh on', $self->{hostname}, + $self->{dsn_name}); $self->{dbh}->disconnect(); } + return; } @@ -3705,6 +3727,7 @@ sub main { if ( my $src_dsn_string = shift @ARGV ) { $src = Cxn->new( dsn_string => $src_dsn_string, + parent => $o->get('daemonize'), DSNParser => $dp, OptionParser => $o, ); @@ -3714,7 +3737,8 @@ sub main { if ( my $dst_dsn = $o->get('dest') ) { $dst = Cxn->new( dsn => $dst_dsn, - prev_dsn => $src ? $src->dsn : undef, + prev_dsn => ($src ? $src->dsn : undef), + parent => $o->get('daemonize'), DSNParser => $dp, OptionParser => $o, ); @@ -3765,6 +3789,16 @@ sub main { $daemon->make_PID_file(); } + # If we daemonized, the parent has already exited and we're the child. + # We shared a copy of every Cxn with the parent, and the parent's copies + # were destroyed but the dbhs were not disconnected because the parent + # attrib was true. Now, as the child, set it false so the dbhs will be + # disconnected when our Cxn copies are destroyed. If we didn't daemonize, + # then we're not really a parent (since we have no children), so set it + # false to auto-disconnect the dbhs when our Cxns are destroyed. + $src->{parent} = 0; + $dst->{parent} = 0 if $dst; + # ######################################################################## # Do the version-check # ######################################################################## diff --git a/bin/pt-kill b/bin/pt-kill index c3a7331d..39a6a6f9 100755 --- a/bin/pt-kill +++ b/bin/pt-kill @@ -4969,23 +4969,24 @@ sub new { } my $self = { - dsn => $dsn, - dbh => $args{dbh}, - dsn_name => $dp->as_string($dsn, [qw(h P S)]), - hostname => '', - set => $args{set}, - NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, - dbh_set => 0, - OptionParser => $o, - DSNParser => $dp, + dsn => $dsn, + dbh => $args{dbh}, + dsn_name => $dp->as_string($dsn, [qw(h P S)]), + hostname => '', + set => $args{set}, + NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, + dbh_set => 0, + OptionParser => $o, + DSNParser => $dp, is_cluster_node => undef, + parent => $args{parent}, }; return bless $self, $class; } sub connect { - my ( $self ) = @_; + my ( $self, %opts ) = @_; my $dsn = $self->{dsn}; my $dp = $self->{DSNParser}; my $o = $self->{OptionParser}; @@ -4996,11 +4997,18 @@ sub connect { $dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: "); $self->{asked_for_pass} = 1; } - $dbh = $dp->get_dbh($dp->get_cxn_params($dsn), { AutoCommit => 1 }); + $dbh = $dp->get_dbh( + $dp->get_cxn_params($dsn), + { + AutoCommit => 1, + %opts, + }, + ); } - PTDEBUG && _d($dbh, 'Connected dbh to', $self->{name}); - return $self->set_dbh($dbh); + $dbh = $self->set_dbh($dbh); + PTDEBUG && _d($dbh, 'Connected dbh to', $self->{hostname},$self->{dsn_name}); + return $dbh; } sub set_dbh { @@ -5023,6 +5031,11 @@ sub set_dbh { $self->{hostname} = $hostname; } + if ( $self->{parent} ) { + PTDEBUG && _d($dbh, 'Setting InactiveDestroy=1 in parent'); + $dbh->{InactiveDestroy} = 1; + } + if ( my $set = $self->{set}) { $set->($dbh); } @@ -5032,6 +5045,13 @@ sub set_dbh { return $dbh; } +sub lost_connection { + my ($self, $e) = @_; + return 0 unless $e; + return $e =~ m/MySQL server has gone away/ + || $e =~ m/Lost connection to MySQL server/; +} + sub dbh { my ($self) = @_; return $self->{dbh}; @@ -5050,12 +5070,21 @@ sub name { sub DESTROY { my ($self) = @_; - if ( $self->{dbh} - && blessed($self->{dbh}) - && $self->{dbh}->can("disconnect") ) { - PTDEBUG && _d('Disconnecting dbh', $self->{dbh}, $self->{name}); + + PTDEBUG && _d('Destroying cxn'); + + if ( $self->{parent} ) { + PTDEBUG && _d($self->{dbh}, 'Not disconnecting dbh in parent'); + } + elsif ( $self->{dbh} + && blessed($self->{dbh}) + && $self->{dbh}->can("disconnect") ) + { + PTDEBUG && _d($self->{dbh}, 'Disconnecting dbh on', $self->{hostname}, + $self->{dsn_name}); $self->{dbh}->disconnect(); } + return; } @@ -6464,6 +6493,7 @@ sub main { $cxn = Cxn->new( dsn_string => shift @ARGV, NAME_lc => 0, + parent => $o->get('daemonize'), DSNParser => $dp, OptionParser => $o, ); @@ -6643,6 +6673,15 @@ sub main { $daemon->make_PID_file(); } + # If we daemonized, the parent has already exited and we're the child. + # We shared a copy of every Cxn with the parent, and the parent's copies + # were destroyed but the dbhs were not disconnected because the parent + # attrib was true. Now, as the child, set it false so the dbhs will be + # disconnected when our Cxn copies are destroyed. If we didn't daemonize, + # then we're not really a parent (since we have no children), so set it + # false to auto-disconnect the dbhs when our Cxns are destroyed. + $cxn->{parent} = 0 if $cxn; + # ######################################################################## # Do the version-check # ######################################################################## diff --git a/bin/pt-online-schema-change b/bin/pt-online-schema-change index 353ed2b9..598cffd2 100755 --- a/bin/pt-online-schema-change +++ b/bin/pt-online-schema-change @@ -4018,23 +4018,24 @@ sub new { } my $self = { - dsn => $dsn, - dbh => $args{dbh}, - dsn_name => $dp->as_string($dsn, [qw(h P S)]), - hostname => '', - set => $args{set}, - NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, - dbh_set => 0, - OptionParser => $o, - DSNParser => $dp, + dsn => $dsn, + dbh => $args{dbh}, + dsn_name => $dp->as_string($dsn, [qw(h P S)]), + hostname => '', + set => $args{set}, + NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, + dbh_set => 0, + OptionParser => $o, + DSNParser => $dp, is_cluster_node => undef, + parent => $args{parent}, }; return bless $self, $class; } sub connect { - my ( $self ) = @_; + my ( $self, %opts ) = @_; my $dsn = $self->{dsn}; my $dp = $self->{DSNParser}; my $o = $self->{OptionParser}; @@ -4045,11 +4046,18 @@ sub connect { $dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: "); $self->{asked_for_pass} = 1; } - $dbh = $dp->get_dbh($dp->get_cxn_params($dsn), { AutoCommit => 1 }); + $dbh = $dp->get_dbh( + $dp->get_cxn_params($dsn), + { + AutoCommit => 1, + %opts, + }, + ); } - PTDEBUG && _d($dbh, 'Connected dbh to', $self->{name}); - return $self->set_dbh($dbh); + $dbh = $self->set_dbh($dbh); + PTDEBUG && _d($dbh, 'Connected dbh to', $self->{hostname},$self->{dsn_name}); + return $dbh; } sub set_dbh { @@ -4072,6 +4080,11 @@ sub set_dbh { $self->{hostname} = $hostname; } + if ( $self->{parent} ) { + PTDEBUG && _d($dbh, 'Setting InactiveDestroy=1 in parent'); + $dbh->{InactiveDestroy} = 1; + } + if ( my $set = $self->{set}) { $set->($dbh); } @@ -4081,6 +4094,13 @@ sub set_dbh { return $dbh; } +sub lost_connection { + my ($self, $e) = @_; + return 0 unless $e; + return $e =~ m/MySQL server has gone away/ + || $e =~ m/Lost connection to MySQL server/; +} + sub dbh { my ($self) = @_; return $self->{dbh}; @@ -4099,12 +4119,21 @@ sub name { sub DESTROY { my ($self) = @_; - if ( $self->{dbh} - && blessed($self->{dbh}) - && $self->{dbh}->can("disconnect") ) { - PTDEBUG && _d('Disconnecting dbh', $self->{dbh}, $self->{name}); + + PTDEBUG && _d('Destroying cxn'); + + if ( $self->{parent} ) { + PTDEBUG && _d($self->{dbh}, 'Not disconnecting dbh in parent'); + } + elsif ( $self->{dbh} + && blessed($self->{dbh}) + && $self->{dbh}->can("disconnect") ) + { + PTDEBUG && _d($self->{dbh}, 'Disconnecting dbh on', $self->{hostname}, + $self->{dsn_name}); $self->{dbh}->disconnect(); } + return; } diff --git a/bin/pt-table-checksum b/bin/pt-table-checksum index e52a4df0..927563bb 100755 --- a/bin/pt-table-checksum +++ b/bin/pt-table-checksum @@ -3376,23 +3376,24 @@ sub new { } my $self = { - dsn => $dsn, - dbh => $args{dbh}, - dsn_name => $dp->as_string($dsn, [qw(h P S)]), - hostname => '', - set => $args{set}, - NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, - dbh_set => 0, - OptionParser => $o, - DSNParser => $dp, + dsn => $dsn, + dbh => $args{dbh}, + dsn_name => $dp->as_string($dsn, [qw(h P S)]), + hostname => '', + set => $args{set}, + NAME_lc => defined($args{NAME_lc}) ? $args{NAME_lc} : 1, + dbh_set => 0, + OptionParser => $o, + DSNParser => $dp, is_cluster_node => undef, + parent => $args{parent}, }; return bless $self, $class; } sub connect { - my ( $self ) = @_; + my ( $self, %opts ) = @_; my $dsn = $self->{dsn}; my $dp = $self->{DSNParser}; my $o = $self->{OptionParser}; @@ -3403,11 +3404,18 @@ sub connect { $dsn->{p} = OptionParser::prompt_noecho("Enter MySQL password: "); $self->{asked_for_pass} = 1; } - $dbh = $dp->get_dbh($dp->get_cxn_params($dsn), { AutoCommit => 1 }); + $dbh = $dp->get_dbh( + $dp->get_cxn_params($dsn), + { + AutoCommit => 1, + %opts, + }, + ); } - PTDEBUG && _d($dbh, 'Connected dbh to', $self->{name}); - return $self->set_dbh($dbh); + $dbh = $self->set_dbh($dbh); + PTDEBUG && _d($dbh, 'Connected dbh to', $self->{hostname},$self->{dsn_name}); + return $dbh; } sub set_dbh { @@ -3430,6 +3438,11 @@ sub set_dbh { $self->{hostname} = $hostname; } + if ( $self->{parent} ) { + PTDEBUG && _d($dbh, 'Setting InactiveDestroy=1 in parent'); + $dbh->{InactiveDestroy} = 1; + } + if ( my $set = $self->{set}) { $set->($dbh); } @@ -3439,6 +3452,13 @@ sub set_dbh { return $dbh; } +sub lost_connection { + my ($self, $e) = @_; + return 0 unless $e; + return $e =~ m/MySQL server has gone away/ + || $e =~ m/Lost connection to MySQL server/; +} + sub dbh { my ($self) = @_; return $self->{dbh}; @@ -3457,12 +3477,21 @@ sub name { sub DESTROY { my ($self) = @_; - if ( $self->{dbh} - && blessed($self->{dbh}) - && $self->{dbh}->can("disconnect") ) { - PTDEBUG && _d('Disconnecting dbh', $self->{dbh}, $self->{name}); + + PTDEBUG && _d('Destroying cxn'); + + if ( $self->{parent} ) { + PTDEBUG && _d($self->{dbh}, 'Not disconnecting dbh in parent'); + } + elsif ( $self->{dbh} + && blessed($self->{dbh}) + && $self->{dbh}->can("disconnect") ) + { + PTDEBUG && _d($self->{dbh}, 'Disconnecting dbh on', $self->{hostname}, + $self->{dsn_name}); $self->{dbh}->disconnect(); } + return; }