From cb2bef59b2598093951547bf6751048d3e33a1fa Mon Sep 17 00:00:00 2001 From: jbjohnso Date: Fri, 16 Oct 2009 18:53:28 +0000 Subject: [PATCH] -When clearing DB handles, also clear the DB handle list -Correctly map the database handle per 'realautocommit' (was causing xCAT to be unable to survive even one database disconnect). -Fix problem where mapping from database handles to dependent objects was not being updated when the database handles changed (was causing xCAT to be unable to survive more than one database disconnect). -Put in more comments so that people may understand the unusable db handle recovery code git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@4401 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- perl-xCAT/xCAT/Table.pm | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/perl-xCAT/xCAT/Table.pm b/perl-xCAT/xCAT/Table.pm index 6f0ad87f0..6942f1748 100644 --- a/perl-xCAT/xCAT/Table.pm +++ b/perl-xCAT/xCAT/Table.pm @@ -129,6 +129,13 @@ sub init_dbworker { $_->{InactiveDestroy} = 1; undef $_; } + $::XCAT_DBHS={}; + $dbobjsforhandle={};#TODO: It's not said explicitly, but this means an + #existing TABLE object is useless if going into db worker. Table objects + #must be recreated after the transition. Only xcatd should have to + #worry about it. This may warrant being done better, making a Table + #object meaningfully survive in much the same way it survives a DB handle + #migration in handle_dbc_request $dbworkerpid = fork; @@ -229,16 +236,25 @@ sub handle_dbc_request { my @args = @{$request->{args}}; my $autocommit = $request->{autocommit}; my $dbindex; - foreach $dbindex (keys %{$::XCAT_DBHS}) { - unless ($::XCAT_DBHS->{$dbindex}) { next; } + foreach $dbindex (keys %{$::XCAT_DBHS}) { #Go through the current open DB handles + unless ($::XCAT_DBHS->{$dbindex}) { next; } #If we have a stale dbindex entry skip it (should no longer happen with additions to init_dbworker unless ($::XCAT_DBHS->{$dbindex} and $::XCAT_DBHS->{$dbindex}->ping) { - my @afflictedobjs = @{$dbobjsforhandle->{$::XCAT_DBHS->{$dbindex}}}; - my $oldhandle = $::XCAT_DBHS->{$dbindex}; - $::XCAT_DBHS->{$dbindex} = $::XCAT_DBHS->{$dbindex}->clone(); - foreach (@afflictedobjs) { + #We have a database that we were unable to reach, migrate database + #handles out from under table objects + my @afflictedobjs = (); #Get the list of objects whose database handle needs to be replaced + if (defined $dbobjsforhandle->{$::XCAT_DBHS->{$dbindex}}) { + @afflictedobjs = @{$dbobjsforhandle->{$::XCAT_DBHS->{$dbindex}}}; + } else { + die "DB HANDLE TRACKING CODE HAS A BUG"; + } + my $oldhandle = $::XCAT_DBHS->{$dbindex}; #store old handle off + $::XCAT_DBHS->{$dbindex} = $::XCAT_DBHS->{$dbindex}->clone(); #replace broken db handle with nice, new, working one + $dbobjsforhandle->{$::XCAT_DBHS->{$dbindex}} = $dbobjsforhandle->{$oldhandle}; #Move the map of depenednt objects to the new handle + foreach (@afflictedobjs) { #migrate afflicted objects to the new DB handle $$_->{dbh} = $::XCAT_DBHS->{$dbindex}; } - $oldhandle->disconnect(); + delete $dbobjsforhandle->{$oldhandle}; #remove the entry for the stale handle + $oldhandle->disconnect(); #free resources associated with dead handle } } if ($functionname eq 'new') { @@ -583,7 +599,7 @@ sub new #This for now is ok, as either we aren't in DB worker mode, in which case this structure would be short lived... #or we are in db worker mode, in which case Table objects live indefinitely #TODO: be able to reap these objects sanely, just in case - push @{$dbobjsforhandle->{$::XCAT_DBHS->{$self->{connstring},$self->{dbuser},$self->{dbpass},$self->{autocommit}}}},\$self; + push @{$dbobjsforhandle->{$::XCAT_DBHS->{$self->{connstring},$self->{dbuser},$self->{dbpass},$self->{realautocommit}}}},\$self; #DBI->connect($self->{connstring}, $self->{dbuser}, $self->{dbpass}, {AutoCommit => $autocommit}); if ($xcatcfg =~ /^SQLite:/) {