diff --git a/Anvil/Tools/Database.pm b/Anvil/Tools/Database.pm index e160977a..16406532 100644 --- a/Anvil/Tools/Database.pm +++ b/Anvil/Tools/Database.pm @@ -16224,10 +16224,59 @@ sub resync_databases }}); } + ### TODO: This can be removed later. + # Look through the bridges, bonds, and network interfaces tables. Look for records in the + # history schema that don't exist in the public schema and purge them. + if ($schema eq "history") + { + 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 }}); + + my $query = "SELECT DISTINCT ".$uuid_column." FROM history.".$table.";"; + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0124", variables => { query => $query }}); + + my $results = $anvil->Database->query({debug => $debug, uuid => $uuid, query => $query, source => $THIS_FILE, line => __LINE__}); + my $count = @{$results}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + results => $results, + count => $count, + }}); + foreach my $row (@{$results}) + { + my $column_uuid = $row->[0]; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { column_uuid => $column_uuid }}); + + my $query = "SELECT COUNT(*) FROM ".$table." WHERE ".$uuid_column." = '".$column_uuid."';"; + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0124", variables => { query => $query }}); + + my $count = $anvil->Database->query({debug => $debug, uuid => $uuid, query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0]; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { count => $count }}); + + if (not $count) + { + # Purge it from everywhere. + my $queries = []; + push @{$queries}, "DELETE FROM history.".$table." WHERE ".$uuid_column." = '".$column_uuid."';"; + push @{$queries}, "DELETE FROM ".$table." WHERE ".$uuid_column." = '".$column_uuid."';"; + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "err", key => "error_0365", variables => { + table => $table, + uuid_column => $uuid_column, + column_uuid => $column_uuid, + }}); + # Delete across all DBs. + $anvil->Database->write({debug => $debug, query => $queries, source => $THIS_FILE, line => __LINE__}); + } + } + } + } + # 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 }}); + + # This will store queries. $anvil->data->{db_resync}{$uuid}{public}{sql} = []; $anvil->data->{db_resync}{$uuid}{history}{sql} = []; @@ -16266,7 +16315,7 @@ sub resync_databases { $query .= " ORDER BY utc_modified_date DESC;"; } - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0074", variables => { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0074", variables => { uuid => $anvil->Database->get_host_from_uuid({short => 1, host_uuid => $uuid}), query => $query, }}); @@ -16345,7 +16394,7 @@ sub resync_databases if (($last_record) && ($schema eq "history") && ($last_record eq "${modified_date}::${row_uuid}")) { # Duplicate! - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "error_0363", variables => { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "err", key => "error_0363", variables => { table => $table, key => $last_record, query => $query, @@ -16354,7 +16403,7 @@ sub resync_databases # Delete this entry. my $query = "DELETE FROM history.".$table." WHERE history_id = ".$history_id.";"; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); $anvil->Database->write({debug => $debug, uuid => $uuid, query => $query, source => $THIS_FILE, line => __LINE__}); next; @@ -18066,7 +18115,6 @@ ORDER BY } } - # Are being asked to trigger a resync? foreach my $uuid (keys %{$anvil->data->{cache}{database_handle}}) { @@ -18154,6 +18202,20 @@ ORDER BY last if $anvil->data->{sys}{database}{resync_needed}; } + # Force resync if requested by command line switch. + $anvil->data->{switches}{'resync-db'} = "" if not defined $anvil->data->{switches}{'resync-db'}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "switches::resync-db" => $anvil->data->{switches}{'resync-db'}, + }}); + if ($anvil->data->{switches}{'resync-db'}) + { + $anvil->data->{sys}{database}{resync_needed} = 1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "sys::database::resync_needed" => $anvil->data->{sys}{database}{resync_needed}, + }}); + return(0); + } + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "sys::database::resync_needed" => $anvil->data->{sys}{database}{resync_needed} }}); return(0); } diff --git a/share/words.xml b/share/words.xml index 73e7b71c..1ce8432e 100644 --- a/share/words.xml +++ b/share/words.xml @@ -510,6 +510,7 @@ The output, if any, was; ' to specify the alert level of the test message.]]> There are two or more entries on the host: [#!variable!host!#] in the history table: [#!variable!table!#]! The duplicate modidied_date and column UUID are: [#!variable!key!#] (time is UTC), and the query that exposed the dupplicate was: [#!variable!query!#]. This is likely caused by two database writes where the 'modified_date' wasn't updated between writes. [ Error ] - There was a problem purging records. The details of the problem should be in the logs. + The table: [#!variable!table!#] has an entry in the history schema that doesn't have a corresponding record in the public schema. This is likely a resync artifact of a deleted record. Purging the record: [#!variable!uuid_column!#:#!variable!column_uuid!#] from all databases. @@ -2125,6 +2126,7 @@ The file: [#!variable!file!#] needs to be updated. The difference is: I was asked to update the timestamp, but the returned timestamp matches the last one. Will loop until a new timestamp is returned. The timestamp has been updated from: [#!variable!old_time!#] to: [#!variable!new_time!#]. read_state() was called but both the 'state_name' and 'state_uuid' parameters were not passed or both were empty.]]> + Forcing the dailing resync and checking to clear records in the history schema no longer in public schema. The host name: [#!variable!target!#] does not resolve to an IP address. diff --git a/tools/striker-purge-target b/tools/striker-purge-target index db2d0a05..2ff73cdf 100755 --- a/tools/striker-purge-target +++ b/tools/striker-purge-target @@ -280,7 +280,66 @@ WHERE push @{$queries}, $query; } } - + + # If deleting an Anvil!, we need to clear any Anvil! references from file_locations and storage groups. + if (($table eq "anvils") && ($anvil->data->{purge}{anvil_uuid})) + { + # + my $query = "DELETE FROM history.file_locations WHERE file_location_anvil_uuid = ".$anvil->Database->quote($anvil->data->{purge}{anvil_uuid}).";"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); + push @{$queries}, $query; + + $query = "DELETE FROM file_locations WHERE file_location_anvil_uuid = ".$anvil->Database->quote($anvil->data->{purge}{anvil_uuid}).";"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); + push @{$queries}, $query; + + # Storage groups + $query = " +SELECT + storage_group_member_uuid +FROM + storage_group_members +WHERE + storage_group_member_storage_group_uuid = + ( + SELECT + storage_group_uuid + FROM + storage_groups + WHERE + storage_group_anvil_uuid = ".$anvil->Database->quote($anvil->data->{purge}{anvil_uuid})." + ) +;"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); + my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__}); + my $count = @{$results}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + results => $results, + count => $count, + }}); + foreach my $row (@{$results}) + { + my $storage_group_member_uuid = $row->[0]; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { storage_group_member_uuid => $storage_group_member_uuid }}); + + my $query = "DELETE FROM history.storage_group_members WHERE storage_group_member_uuid = ".$anvil->Database->quote($storage_group_member_uuid).";"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); + push @{$queries}, $query; + + $query = "DELETE FROM storage_group_members WHERE storage_group_member_uuid = ".$anvil->Database->quote($storage_group_member_uuid).";"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); + push @{$queries}, $query; + } + + $query = "DELETE FROM history.storage_groups WHERE storage_group_anvil_uuid = ".$anvil->Database->quote($anvil->data->{purge}{anvil_uuid}).";"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); + push @{$queries}, $query; + + $query = "DELETE FROM storage_groups WHERE storage_group_anvil_uuid = ".$anvil->Database->quote($anvil->data->{purge}{anvil_uuid}).";"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); + push @{$queries}, $query; + } + # Just delete the record normally. if ($anvil->data->{sys}{database}{history_table}{$table}) { @@ -295,6 +354,12 @@ WHERE } # Commit. + print "===================\n"; + foreach my $query (@{$queries}) + { + print $query."\n"; + } + print "===================\n"; my $problem = $anvil->Database->write({query => $queries, source => $THIS_FILE, line => __LINE__}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }}); if ($problem)