From e40d0e2444e6c6db2e3e1c9b3d22445c7a924a0c Mon Sep 17 00:00:00 2001 From: Digimer Date: Thu, 26 Aug 2021 23:26:03 -0400 Subject: [PATCH] Fixed a bug where if a database is pingable but the pgsql database is down, and it's the first database tested (or local), then the DB handle used to read / quote fails. Signed-off-by: Digimer --- Anvil/Tools/Database.pm | 128 ++++++++++++++++++----------------- Anvil/Tools/Server.pm | 2 - tools/anvil-provision-server | 2 +- 3 files changed, 66 insertions(+), 66 deletions(-) diff --git a/Anvil/Tools/Database.pm b/Anvil/Tools/Database.pm index a6177d09..ae227823 100644 --- a/Anvil/Tools/Database.pm +++ b/Anvil/Tools/Database.pm @@ -1347,67 +1347,6 @@ sub connect } } - # Before we try to connect, see if this is a local database and, if so, make sure it's setup. - my $is_local = $anvil->Network->is_local({debug => $debug, host => $host}); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { is_local => $is_local }}); - if ($is_local) - { - $anvil->data->{sys}{database}{read_uuid} = $uuid; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "sys::database::read_uuid" => $anvil->data->{sys}{database}{read_uuid} }}); - - # If requested, and if running with root access, set it up (or update it) if needed. - # This method just returns if nothing is needed. - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - check_if_configured => $check_if_configured, - real_uid => $<, - effective_uid => $>, - }}); - if (($check_if_configured) && ($< == 0) && ($> == 0)) - { - $anvil->Database->configure_pgsql({debug => $debug, uuid => $uuid}); - } - } - elsif (not $anvil->data->{sys}{database}{read_uuid}) - { - $anvil->data->{sys}{database}{read_uuid} = $uuid; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "sys::database::read_uuid" => $anvil->data->{sys}{database}{read_uuid} }}); - } - - # If this isn't a local database, read the target's Anvil! version (if available) and make - # sure it matches ours. If it doesn't, skip this database. - if (not $is_local) - { - my ($local_anvil_version, $local_schema_version) = $anvil->_anvil_version({debug => $debug}); - my ($remote_anvil_version, $remote_schema_version) = $anvil->Get->anvil_version({ - debug => $debug, - target => $host, - password => $password, - }); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { - 's1:host' => $host, - 's2:local_anvil_version' => $local_anvil_version, - 's3:remote_anvil_version' => $remote_anvil_version, - 's4:local_schema_version' => $local_schema_version, - 's5:remote_schema_version' => $remote_schema_version, - }}); - # TODO: Periodically, we fail to get the remote version. For now, we proceed if - # everything else is OK. Might be better to pause a re-try... To be determined. - if (($remote_schema_version) && ($remote_schema_version ne $local_schema_version)) - { - # Version doesn't match, - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0145", variables => { - host => $host, - local_version => $local_schema_version, - target_version => $remote_schema_version, - }}); - - # Delete the information about this database. We'll try again on nexy - # ->connect(). - delete $anvil->data->{database}{$uuid}; - next; - } - } - # Connect! my $dbh = ""; ### NOTE: The Database->write() method, when passed an array, will automatically disable @@ -1484,11 +1423,12 @@ sub connect }; } $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "alert", key => $message_key, variables => $variables }); + + next; } elsif ($dbh =~ /^DBI::db=HASH/) { # Woot! - $anvil->data->{sys}{database}{connections}++; push @{$successful_connections}, $uuid; $anvil->data->{cache}{database_handle}{$uuid} = $dbh; @@ -1607,6 +1547,67 @@ sub connect "sys::database::timestamp" => $anvil->data->{sys}{database}{timestamp}, }}); } + + # Before we try to connect, see if this is a local database and, if so, make sure it's setup. + my $is_local = $anvil->Network->is_local({debug => $debug, host => $host}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { is_local => $is_local }}); + if ($is_local) + { + $anvil->data->{sys}{database}{read_uuid} = $uuid; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "sys::database::read_uuid" => $anvil->data->{sys}{database}{read_uuid} }}); + + # If requested, and if running with root access, set it up (or update it) if needed. + # This method just returns if nothing is needed. + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + check_if_configured => $check_if_configured, + real_uid => $<, + effective_uid => $>, + }}); + if (($check_if_configured) && ($< == 0) && ($> == 0)) + { + $anvil->Database->configure_pgsql({debug => $debug, uuid => $uuid}); + } + } + elsif (not $anvil->data->{sys}{database}{read_uuid}) + { + $anvil->data->{sys}{database}{read_uuid} = $uuid; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "sys::database::read_uuid" => $anvil->data->{sys}{database}{read_uuid} }}); + } + + # If this isn't a local database, read the target's Anvil! version (if available) and make + # sure it matches ours. If it doesn't, skip this database. + if (not $is_local) + { + my ($local_anvil_version, $local_schema_version) = $anvil->_anvil_version({debug => $debug}); + my ($remote_anvil_version, $remote_schema_version) = $anvil->Get->anvil_version({ + debug => $debug, + target => $host, + password => $password, + }); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + 's1:host' => $host, + 's2:local_anvil_version' => $local_anvil_version, + 's3:remote_anvil_version' => $remote_anvil_version, + 's4:local_schema_version' => $local_schema_version, + 's5:remote_schema_version' => $remote_schema_version, + }}); + # TODO: Periodically, we fail to get the remote version. For now, we proceed if + # everything else is OK. Might be better to pause a re-try... To be determined. + if (($remote_schema_version) && ($remote_schema_version ne $local_schema_version)) + { + # Version doesn't match, + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0145", variables => { + host => $host, + local_version => $local_schema_version, + target_version => $remote_schema_version, + }}); + + # Delete the information about this database. We'll try again on nexy + # ->connect(). + delete $anvil->data->{database}{$uuid}; + next; + } + } } my $total = tv_interval ($start_time, [gettimeofday]); @@ -14991,7 +14992,7 @@ sub resync_databases # Now read in the data from the different databases. foreach my $uuid (sort {$a cmp $b} keys %{$anvil->data->{cache}{database_handle}}) { - # ... + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { uuid => $uuid }}); $anvil->data->{db_resync}{$uuid}{public}{sql} = []; $anvil->data->{db_resync}{$uuid}{history}{sql} = []; @@ -15313,6 +15314,7 @@ sub resync_databases # Do the INSERTs now and then release the memory. foreach my $uuid (sort {$a cmp $b} keys %{$anvil->data->{cache}{database_handle}}) { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { uuid => $uuid }}); # Merge the queries for both schemas into one array, with public schema # queries being first, then delete the arrays holding them to free memory # before we start the resync. diff --git a/Anvil/Tools/Server.pm b/Anvil/Tools/Server.pm index c50fd4b6..3bf56862 100644 --- a/Anvil/Tools/Server.pm +++ b/Anvil/Tools/Server.pm @@ -1304,8 +1304,6 @@ sub parse_definition } $anvil->data->{server}{$target}{$server}{$source}{parsed} = $server_xml; - #print Dumper $server_xml; - #die; # Get the DRBD data that this server will almost certainly be using. $anvil->DRBD->get_devices({debug => $debug}); diff --git a/tools/anvil-provision-server b/tools/anvil-provision-server index d7866471..efbbccb0 100755 --- a/tools/anvil-provision-server +++ b/tools/anvil-provision-server @@ -1124,7 +1124,7 @@ sub check_drbd_minor_and_port resource_name => $anvil->data->{job}{server_name}, }); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { - 'job::drbd_minor' => $anvil->data->{job}{drbd_minor}, + 'job::drbd_minor' => $anvil->data->{job}{drbd_minor}, 'job::drbd_tcp_port' => $anvil->data->{job}{drbd_tcp_port}, }}); }