1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-12-21 23:47:33 +02:00
Files
pgbackrest/lib/BackRest/ArchiveInfo.pm
David Steele a59284a4cc v0.80: DBI Support, Stability, and Convenience Features
* Fixed an issue that caused the formatted timestamp for both the oldest and newest backups to be reported as the current time by the info command.  Only text output was affected -- json output reported the correct epoch values.  Reported by Michael Renner.

* Fixed protocol issue that was preventing ssh errors (especially on connection) from being logged.

* Now using Perl DBI and DBD::Pg for connections to PostgreSQL rather than psql.  The cmd-psql and cmd-psql-option settings have been removed and replaced with db-port and db-socket-path.

* Add stop-auto option to allow failed backups to automatically be stopped when a new backup starts.

* Add db-timeout option to limit the amount of time pgBackRest will wait for pg_start_backup() and pg_stop_backup() to return.

* Remove pg_control file at the beginning of the restore and copy it back at the very end.  This prevents the possibility that a partial restore can be started by PostgreSQL.

* The repository is now created and updated with consistent directory and file modes.  By default umask is set to 0000 but this can be disabled with the neutral-umask setting.

* Added checks to be sure the db-path setting is consistent with db-port by comparing the data_directory as reported by the cluster against the db-path setting and the version as reported by the cluster against the value read from pg_control.  The db-socket-path setting is checked to be sure it is an absolute path.

* Experimental support for PostgreSQL 9.5 alpha1.  This may break when the control version or WAL magic changes in future versions but will be updated in each pgBackRest release to keep pace.  All regression tests pass except for --target-resume tests (this functionality has changed in 9.5) and there is no testing yet for .partial WAL segments.

* Major refactoring of the protocol layer to support future development.

* Added vagrant test configurations for Ubuntu 14.04 and CentOS 7.

* Split most of README.md out into USERGUIDE.md and CHANGELOG.md because it was becoming unwieldy.  Changed most references to "database" in the user guide to "database cluster" for clarity.
2015-08-09 11:20:43 -04:00

159 lines
6.5 KiB
Perl

####################################################################################################################################
# ARCHIVE INFO MODULE
####################################################################################################################################
package BackRest::ArchiveInfo;
use parent 'BackRest::Ini';
use strict;
use warnings FATAL => qw(all);
use Carp qw(confess);
use Exporter qw(import);
use File::Basename qw(dirname basename);
use File::stat;
use lib dirname($0);
use BackRest::BackupInfo;
use BackRest::Config;
use BackRest::Exception;
use BackRest::File;
use BackRest::Ini;
use BackRest::Manifest;
use BackRest::Utility;
####################################################################################################################################
# Operation constants
####################################################################################################################################
use constant OP_ARCHIVE_INFO => 'ArchiveInfo';
use constant OP_ARCHIVE_INFO_NEW => OP_ARCHIVE_INFO . "->new";
####################################################################################################################################
# File/path constants
####################################################################################################################################
use constant ARCHIVE_INFO_FILE => 'archive.info';
our @EXPORT = qw(ARCHIVE_INFO_FILE);
####################################################################################################################################
# Backup info Constants
####################################################################################################################################
use constant INFO_ARCHIVE_SECTION_DB => INFO_BACKUP_SECTION_DB;
push @EXPORT, qw(INFO_ARCHIVE_SECTION_DB);
use constant INFO_ARCHIVE_SECTION_DB_HISTORY => INFO_BACKUP_SECTION_DB_HISTORY;
push @EXPORT, qw(INFO_ARCHIVE_SECTION_DB);
use constant INFO_ARCHIVE_KEY_DB_VERSION => MANIFEST_KEY_DB_VERSION;
push @EXPORT, qw(INFO_ARCHIVE_KEY_DB_VERSION);
use constant INFO_ARCHIVE_KEY_DB_ID => INFO_BACKUP_KEY_HISTORY_ID;
push @EXPORT, qw(INFO_ARCHIVE_KEY_DB_ID);
use constant INFO_ARCHIVE_KEY_DB_SYSTEM_ID => MANIFEST_KEY_SYSTEM_ID;
push @EXPORT, qw(INFO_ARCHIVE_KEY_DB_SYSTEM_ID);
####################################################################################################################################
# CONSTRUCTOR
####################################################################################################################################
sub new
{
my $class = shift; # Class name
my $strArchiveClusterPath = shift; # Backup cluster path
my $bRequired = shift; # Is archive info required?
logDebug(OP_ARCHIVE_INFO_NEW, DEBUG_CALL, undef, {archiveClusterPath => \$strArchiveClusterPath});
# Build the archive info path/file name
my $strArchiveInfoFile = "${strArchiveClusterPath}/" . ARCHIVE_INFO_FILE;
my $bExists = -e $strArchiveInfoFile ? true : false;
if (!$bExists && defined($bRequired) && $bRequired)
{
confess &log(ERROR, ARCHIVE_INFO_FILE . " does not exist but is required to get WAL segments\n" .
"HINT: Is archive_command configured in postgresql.conf?\n" .
"HINT: Use --no-archive-check to disable archive checks during backup if you have an alternate archiving" .
" scheme.", ERROR_FILE_MISSING);
}
# Init object and store variables
my $self = $class->SUPER::new($strArchiveInfoFile, $bExists);
$self->{bExists} = $bExists;
$self->{strArchiveClusterPath} = $strArchiveClusterPath;
return $self;
}
####################################################################################################################################
# check
#
# Check archive info and make it is compatible.
####################################################################################################################################
sub check
{
my $self = shift;
my $strDbVersion = shift;
my $ullDbSysId = shift;
my $bSave = false;
if ($self->test(INFO_ARCHIVE_SECTION_DB))
{
my $strError = undef;
if (!$self->test(INFO_ARCHIVE_SECTION_DB, INFO_ARCHIVE_KEY_DB_VERSION, undef, $strDbVersion))
{
$strError = "WAL segment version ${strDbVersion} does not match archive version " .
$self->get(INFO_ARCHIVE_SECTION_DB, INFO_ARCHIVE_KEY_DB_VERSION);
}
if (!$self->test(INFO_ARCHIVE_SECTION_DB, INFO_ARCHIVE_KEY_DB_SYSTEM_ID, undef, $ullDbSysId))
{
$strError = "WAL segment system-id ${ullDbSysId} does not match archive system-id " .
$self->get(INFO_ARCHIVE_SECTION_DB, INFO_ARCHIVE_KEY_DB_SYSTEM_ID);
}
if (defined($strError))
{
confess &log(ERROR, "${strError}\nHINT: are you archiving to the correct stanza?", ERROR_ARCHIVE_MISMATCH);
}
}
# Else create the info file from the current WAL segment
else
{
my $iDbId = 1;
# Fill db section
$self->setNumeric(INFO_ARCHIVE_SECTION_DB, INFO_ARCHIVE_KEY_DB_SYSTEM_ID, undef, $ullDbSysId);
$self->set(INFO_ARCHIVE_SECTION_DB, INFO_ARCHIVE_KEY_DB_VERSION, undef, $strDbVersion);
$self->setNumeric(INFO_ARCHIVE_SECTION_DB, INFO_ARCHIVE_KEY_DB_ID, undef, $iDbId);
# Fill db history
$self->setNumeric(INFO_ARCHIVE_SECTION_DB_HISTORY, $iDbId, INFO_ARCHIVE_KEY_DB_ID, $ullDbSysId);
$self->set(INFO_ARCHIVE_SECTION_DB_HISTORY, $iDbId, INFO_ARCHIVE_KEY_DB_VERSION, $strDbVersion);
$bSave = true;
}
# Save if changes have been made
if ($bSave)
{
$self->save();
}
return $self->archiveId();
}
####################################################################################################################################
# archiveId
#
# Get the archive id.
####################################################################################################################################
sub archiveId
{
my $self = shift;
return $self->get(INFO_ARCHIVE_SECTION_DB, INFO_ARCHIVE_KEY_DB_VERSION) . "-" .
$self->get(INFO_ARCHIVE_SECTION_DB, INFO_ARCHIVE_KEY_DB_ID);
}
1;