Fixed bugs related to automatic database startup and conditional backup loading.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 3 years ago
parent 4e9882812d
commit e60a1b46b3
  1. 145
      Anvil/Tools/Database.pm
  2. 2
      anvil.conf
  3. 4
      share/words.xml
  4. 12
      tools/anvil-daemon
  5. 2
      tools/anvil-manage-firewall
  6. 2
      tools/anvil-parse-fence-agents
  7. 10
      tools/striker-manage-install-target

@ -332,7 +332,7 @@ sub backup_database
}
my $start_time = time;
my $dump_file = $anvil->data->{path}{directories}{pgsql}."/".$anvil->data->{sys}{database}{name}."_db_dump.".$anvil->Get->host_uuid().".out";
my $dump_file = $anvil->data->{path}{directories}{pgsql}."/".$anvil->data->{sys}{database}{name}."_db_dump.".$anvil->Get->host_uuid().".sql";
$dump_file =~ s/\/\//\//g;
my $dump_call = $anvil->data->{path}{exe}{su}." - postgres -c \"".$anvil->data->{path}{exe}{pg_dump}." ".$anvil->data->{sys}{database}{name}." > ".$dump_file."\"";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
@ -1714,42 +1714,44 @@ sub connect
my $db_name = $anvil->data->{sys}{database}{name};
my $dump_files = [];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { directory => $directory }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { directory => $directory }});
local(*DIRECTORY);
opendir(DIRECTORY, $directory);
while(my $file = readdir(DIRECTORY))
{
next if $file eq ".";
next if $file eq "..";
my $db_dump_uuid = "";
my $full_path = $directory."/".$file;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
my $db_dump_uuid = "";
my $full_path = $directory."/".$file;
$full_path =~ s/\/\//\//g;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
file => $file,
full_path => $full_path,
}});
if ($file =~ /\Q${db_name}_db_dump\.(.*).sql/)
if ($file =~ /\Q$db_name\E_db_dump\.(.*).sql/)
{
$db_dump_uuid = $1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { directory => $directory }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { directory => $directory }});
# Is this one of our own dumps?
if ($db_dump_uuid eq $local_host_uuid)
{
# How recent is it?
$anvil->Storage->get_file_stats({debug => $debug, file => $full_path});
$anvil->Storage->get_file_stats({debug => $debug, file_path => $full_path});
my $mtime = $anvil->data->{file_stat}{$full_path}{modified_time};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { mtime => $mtime }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mtime => $mtime }});
if ($mtime > $backup_age)
{
$backup_age = $mtime;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { backup_age => $backup_age }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { backup_age => $backup_age }});
}
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0653", variables => { full_path => $full_path }});
next;
}
# Record this dump file for later purging.
push @{$dump_files}, $full_path;
# Is this a database we're configured to use?
@ -1763,67 +1765,77 @@ sub connect
}});
next;
}
# Still here? This is a candidate for loading. What's the mtime on this file?
$anvil->Storage->get_file_stats({debug => $debug, file_path => $full_path});
my $mtime = $anvil->data->{file_stat}{$full_path}{modified_time};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { directory => $directory }});
if ($mtime > $youngest_dump)
{
# This is the youngest, so far.
$youngest_dump = $mtime;
$use_dump = $full_path;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
youngest_dump => $youngest_dump,
full_path => $full_path,
}});
}
}
else
{
# Not a dump file, ignore it.
next;
}
# What's the mtime on this file?
$anvil->Storage->get_file_stats({debug => $debug, file => $full_path});
my $mtime = $anvil->data->{file_stat}{$full_path}{modified_time};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { directory => $directory }});
if ($mtime > $youngest_dump)
{
# This is the youngest, so far.
$youngest_dump = $mtime;
$use_dump = $full_path;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
youngest_dump => $youngest_dump,
full_path => $full_path,
}});
}
}
closedir(DIRECTORY);
# Did I find a dump to load that's newer than my most recent backup?
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
use_dump => $use_dump,
youngest_dump => $youngest_dump,
backup_age => $backup_age,
}});
if (($use_dump) && ($youngest_dump > $backup_age))
{
# Yup! This will start the database, if needed.
my $file_size = $anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{file_stat}{$use_dump}{size}});
my $file_size_bytes = $anvil->Convert->add_commas({number => $anvil->data->{file_stat}{$use_dump}{size}});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0656", variables => {
file => $use_dump,
size => $file_size,
size_bytes => $file_size_bytes,
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { use_dump => $use_dump }});
if ($use_dump)
{
# Is one of our dumps newer? If so, don't load.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
youngest_dump => $youngest_dump,
backup_age => $backup_age,
}});
my $problem = $anvil->Database->load_database({
debug => $debug,
backup => 1,
load_file => $use_dump,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { problem => $problem }});
if ($problem)
if ($backup_age > $youngest_dump)
{
# Failed, delete the file we tried to load.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "err", key => "error_0355", variables => { file => $use_dump }});
unlink $use_dump;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0661"});
}
else
{
# Success! Delete all backups we found so we don't reload
# them in the future.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0657"});
foreach my $full_path (@{$dump_files})
# Yup! This will start the database, if needed.
my $file_size = $anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{file_stat}{$use_dump}{size}});
my $file_size_bytes = $anvil->Convert->add_commas({number => $anvil->data->{file_stat}{$use_dump}{size}});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0656", variables => {
file => $use_dump,
size => $file_size,
size_bytes => $file_size_bytes,
}});
my $problem = $anvil->Database->load_database({
debug => 2,
backup => 0,
load_file => $use_dump,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }});
if ($problem)
{
# Failed, delete the file we tried to load.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, priority => "err", key => "error_0355", variables => { file => $use_dump }});
unlink $use_dump;
}
else
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0589", variables => { file => $full_path }});
unlink $full_path;
# Success! Delete all backups we found from other hosts so we don't
# reload them in the future.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0657"});
foreach my $full_path (@{$dump_files})
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0589", variables => { file => $full_path }});
unlink $full_path;
}
}
}
}
@ -1839,14 +1851,15 @@ sub connect
{
# Started the daemon.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0059"});
# Recall this method.
if (not $retry)
{
$anvil->Database->connect({debug => $debug, retry => 1});
}
}
}
# Reconnect
if (not $retry)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0662"});
$anvil->Database->connect({debug => $debug, retry => 1});
}
}
my $total = tv_interval ($start_time, [gettimeofday]);
@ -14025,8 +14038,8 @@ sub load_database
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->load_database()" }});
my $backup = $parameter->{backup} ? $parameter->{backup} : 1;
my $load_file = $parameter->{load_file} ? $parameter->{load_file} : 0;
my $backup = defined $parameter->{backup} ? $parameter->{backup} : 1;
my $load_file = defined $parameter->{load_file} ? $parameter->{load_file} : 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
backup => $backup,
load_file => $load_file,
@ -14182,7 +14195,7 @@ sub load_database
}
# Finally, load the database.
my $load_call = $anvil->data->{path}{exe}{su}." - postgres -c \"".$anvil->data->{path}{exe}{pgsql}." < ".$load_file."\"";
my $load_call = $anvil->data->{path}{exe}{su}." - postgres -c \"".$anvil->data->{path}{exe}{psql}." ".$anvil->data->{sys}{database}{name}." < ".$load_file."\"";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { load_call => $load_call }});
$output = "";
$return_code = "";

@ -116,7 +116,7 @@ sys::database::log_transactions = 0
# lot of log traffic. If you want to silence these log alerts, you can set the value below to be higher than
# your current active log level (default is '1', so set to '2' or '3' to silence).
# NOTE: It's important to only use this temporarily.
sys::database::failed_connection_log_level = 1
#sys::database::failed_connection_log_level = 2
# This controls what log facility to use by default.
# NOTE: This will always be 'authpriv' when a log entry is marked as secure.

@ -2019,7 +2019,7 @@ The file: [#!variable!file!#] needs to be updated. The difference is:
<key name="log_0650">[ Note ] - We're a Striker and we did not connect to a peer's database. Will check now if we can load a recent backup, then start postgres locally (with or without a load).</key>
<key name="log_0651">Evaluating the dump file: [#!variable!full_path!#].</key>
<key name="log_0652">The database host UUID: [#!variable!host_uuid!#] is not configured here, ignoring: [#!variable!full_path!#].</key>
<key name="log_0653">We created the database dump file: [#!variable!full_path!#], ignoring it.</key>
<key name="log_0653">We created the database dump file: [#!variable!full_path!#], will compare it's modidified time to other dumps we may find.</key>
<key name="log_0654">The database was dumped to: [#!variable!file!#] in: [#!variable!took!#] second(s). The size of the dump file is: [#!variable!size!#] (#!variable!size_bytes) bytes).</key>
<key name="log_0655">The database was loaded successfull from the file: [#!variable!file!#] in: [#!variable!took!#] second(s)!</key>
<key name="log_0656">No databases were available, so we will become primary after loading: [#!variable!file!#], which is: [#!variable!size!#] (#!variable!size_bytes!# bytes). Please be patient, this could take a moment.</key>
@ -2027,6 +2027,8 @@ The file: [#!variable!file!#] needs to be updated. The difference is:
<key name="log_0658">Sync'ed the file: [#!variable!file!#] to the peer Striker: [#!variable!host_name!#]. The sync took: [#!variable!took!#] seconds, and the file was: [#!variable!size!#] (#!variable!size_bytes!# bytes).</key>
<key name="log_0659">We're going to shut down our database. Creating a backup first.</key>
<key name="log_0660">Stopped the postgresql daemon as a peer is currently primary.</key>
<key name="log_0661">Our most recent database dump is newer than any from our peers. As such, we'll just start the database without a load.</key>
<key name="log_0662">Retrying to connect to the database.</key>
<!-- Messages for users (less technical than log entries), though sometimes used for logs, too. -->
<key name="message_0001">The host name: [#!variable!target!#] does not resolve to an IP address.</key>

@ -378,26 +378,26 @@ sub check_network
# The network sometimes doesn't come up, but we don't want to try recovering it too soon. As such,
# we'll start watching the network after the uptime is 2 minutes.
my $uptime = $anvil->Get->uptime;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { uptime => $uptime }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { uptime => $uptime }});
if ($uptime > 120)
{
# Check that bonds are up. Degraded bonds will be left alone.
if (not $anvil->data->{sys}{network}{initial_checks})
{
my $running = $anvil->System->check_daemon({daemon => "NetworkManager"});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { running => $running }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { running => $running }});
if (not $running)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "message_0250", variables => { daemon => "NetworkManager" }});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "message_0250", variables => { daemon => "NetworkManager" }});
my $return_code = $anvil->System->start_daemon({daemon => "NetworkManager"});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { return_code => $return_code }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { return_code => $return_code }});
}
#$anvil->Network->check_network({heal => "all"});
$anvil->data->{sys}{network}{initial_checks} = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
"sys::network::initial_checks" => $anvil->data->{sys}{network}{initial_checks},
}});
}
@ -1503,7 +1503,7 @@ sub update_state_file
#my $shell_call = $anvil->data->{path}{exe}{'anvil-update-states'}.$anvil->Log->switches;
my $shell_call = $anvil->data->{path}{exe}{'anvil-update-states'};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { shell_call => $shell_call }});
my ($states_output, $return_code) = $anvil->System->call({debug => 3, shell_call => $shell_call, source => $THIS_FILE, line => __LINE__});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {

@ -48,7 +48,7 @@ if (not $anvil->data->{sys}{manage}{firewall})
# Do nothing.
$anvil->nice_exit({exit_code => 0});
}
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, secure => 0, key => "log_0115", variables => { program => $THIS_FILE }});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 3, secure => 0, key => "log_0115", variables => { program => $THIS_FILE }});
# Read switches
$anvil->data->{switches}{'y'} = "";

@ -27,7 +27,7 @@ my $anvil = Anvil::Tools->new();
$anvil->data->{switches}{refresh} = 0;
$anvil->Get->switches;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0115", variables => { program => $THIS_FILE }});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, secure => 0, key => "log_0115", variables => { program => $THIS_FILE }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
"switches::refresh" => $anvil->data->{switches}{refresh},
}});

@ -76,7 +76,7 @@ $anvil->data->{switches}{'no-refresh'} = 0;
$anvil->data->{switches}{refresh} = 0;
$anvil->data->{switches}{status} = "";
$anvil->Get->switches();
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0115", variables => { program => $THIS_FILE }});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, secure => 0, key => "log_0115", variables => { program => $THIS_FILE }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
'switches::check' => $anvil->data->{switches}{check},
'switches::disable' => $anvil->data->{switches}{disable},
@ -584,7 +584,7 @@ sub setup_boot_environment
}
### PXE UEFI 'grub.cfg' file.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "host_os::os_type" => $anvil->data->{host_os}{os_type} }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "host_os::os_type" => $anvil->data->{host_os}{os_type} }});
my $say_os = "#!string!brand_0010!#";
if ($anvil->data->{host_os}{os_type} eq "centos8")
{
@ -594,7 +594,7 @@ sub setup_boot_environment
{
$say_os = "#!string!brand_0012!#";
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_os => $say_os }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { say_os => $say_os }});
my $uefi_grub_body = $anvil->Template->get({file => "pxe.txt", show_name => 0, name => "tftp_grub", variables => {
base_url => $base_url,
@ -2735,7 +2735,7 @@ sub load_packages
my ($os_type, $os_arch) = $anvil->Get->os_type();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
os_type => $os_type,
os_arch => $os_arch,
}});
@ -2772,7 +2772,7 @@ sub load_packages
my $rhel8_test_source = $anvil->data->{path}{directories}{html}."/rhel8";
my $centos8_test_source = $anvil->data->{path}{directories}{html}."/centos8";
my $centos_stream8_test_source = $anvil->data->{path}{directories}{html}."/centos-stream8";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
rhel8_test_source => $rhel8_test_source,
centos8_test_source => $centos8_test_source,
centos_stream8_test_source => $centos_stream8_test_source,

Loading…
Cancel
Save