diff --git a/lib/pgBackRest/Db.pm b/lib/pgBackRest/Db.pm deleted file mode 100644 index 05e9ac81c..000000000 --- a/lib/pgBackRest/Db.pm +++ /dev/null @@ -1,703 +0,0 @@ -#################################################################################################################################### -# DB MODULE -#################################################################################################################################### -package pgBackRest::Db; - -use strict; -use warnings FATAL => qw(all); -use Carp qw(confess); -use English '-no_match_vars'; - -use Exporter qw(import); - our @EXPORT = qw(); -use Fcntl qw(O_RDONLY); -use File::Basename qw(dirname); -use JSON::PP; - -use pgBackRest::DbVersion; -use pgBackRest::Common::Exception; -use pgBackRest::Common::Log; -use pgBackRest::Common::String; -use pgBackRest::Common::Wait; -use pgBackRest::Config::Config; -use pgBackRest::Manifest; -use pgBackRest::Protocol::Storage::Helper; -use pgBackRest::Version; - -#################################################################################################################################### -# Backup advisory lock -#################################################################################################################################### -use constant DB_BACKUP_ADVISORY_LOCK => '12340078987004321'; - push @EXPORT, qw(DB_BACKUP_ADVISORY_LOCK); - -#################################################################################################################################### -# Map the control and catalog versions to PostgreSQL version. -# -# The control version can be found in src/include/catalog/pg_control.h and may not change with every version of PostgreSQL but is -# still checked to detect custom builds which change the structure. The catalog version can be found in -# src/include/catalog/catversion.h and should change with every release. -#################################################################################################################################### -my $oPgControlVersionHash = -{ - # iControlVersion => {iCatalogVersion => strDbVersion} - 833 => {200711281 => PG_VERSION_83}, - 843 => {200904091 => PG_VERSION_84}, - 903 => - { - 201008051 => PG_VERSION_90, - 201105231 => PG_VERSION_91, - }, - 922 => {201204301 => PG_VERSION_92}, - 937 => {201306121 => PG_VERSION_93}, - 942 => - { - 201409291 => PG_VERSION_94, - 201510051 => PG_VERSION_95, - }, - 960 => - { - 201608131 => PG_VERSION_96, - }, - 1002 => - { - 201707211 => PG_VERSION_10, - }, - 1100 => - { - 201809051 => PG_VERSION_11, - }, - 1201 => - { - 201909212 => PG_VERSION_12, - }, -}; - -#################################################################################################################################### -# CONSTRUCTOR -#################################################################################################################################### -sub new -{ - my $class = shift; # Class name - - # Create the class hash - my $self = {}; - bless $self, $class; - - # Assign function parameters, defaults, and log debug info - ( - my $strOperation, - $self->{iRemoteIdx}, - ) = - logDebugParam - ( - __PACKAGE__ . '->new', \@_, - {name => 'iRemoteIdx', required => false}, - ); - - if (defined($self->{iRemoteIdx})) - { - $self->{strDbPath} = cfgOption(cfgOptionIdFromIndex(CFGOPT_PG_PATH, $self->{iRemoteIdx})); - } - - # Return from function and log return values if any - return logDebugReturn - ( - $strOperation, - {name => 'self', value => $self} - ); -} - -#################################################################################################################################### -# DESTRUCTOR -#################################################################################################################################### -sub DESTROY -{ - my $self = shift; - - # Assign function parameters, defaults, and log debug info - my ($strOperation) = logDebugParam(__PACKAGE__ . '->DESTROY'); - - if (defined($self->{oDb})) - { - $self->{oDb}->close(); - undef($self->{oDb}); - } - - # Return from function and log return values if any - return logDebugReturn($strOperation); -} - -#################################################################################################################################### -# connect -#################################################################################################################################### -sub connect -{ - my $self = shift; - - # Assign function parameters, defaults, and log debug info - my - ( - $strOperation, - $bWarnOnError, - ) = - logDebugParam - ( - __PACKAGE__ . '::connect', \@_, - {name => 'bWarnOnError', default => false}, - ); - - # Only connect if not already connected - my $bResult = true; - - if (!defined($self->{oDb})) - { - $self->{oDb} = new pgBackRest::LibC::PgClient( - cfgOption(cfgOptionIdFromIndex(CFGOPT_PG_SOCKET_PATH, $self->{iRemoteIdx}), false), - cfgOption(cfgOptionIdFromIndex(CFGOPT_PG_PORT, $self->{iRemoteIdx})), 'postgres', - cfgOption(CFGOPT_DB_TIMEOUT) * 1000); - - if ($bWarnOnError) - { - eval - { - $self->{oDb}->open(); - return true; - } - or do - { - &log(WARN, exceptionMessage($EVAL_ERROR)); - $bResult = false; - - undef($self->{oDb}); - } - } - else - { - $self->{oDb}->open(); - } - - if (defined($self->{oDb})) - { - my ($fDbVersion) = $self->versionGet(); - - if ($fDbVersion >= PG_VERSION_APPLICATION_NAME) - { - # Set application name for monitoring and debugging - $self->{oDb}->query("set application_name = '" . PROJECT_NAME . ' [' . cfgCommandName(cfgCommandGet()) . "]'"); - - # Clear search path to prevent possible function overrides - $self->{oDb}->query("set search_path = 'pg_catalog'"); - } - } - } - - # Return from function and log return values if any - return logDebugReturn - ( - $strOperation, - {name => 'bResult', value => $bResult} - ); -} - -#################################################################################################################################### -# executeSql -#################################################################################################################################### -sub executeSql -{ - my $self = shift; - - # Assign function parameters, defaults, and log debug info - my - ( - $strOperation, - $strSql, - $bIgnoreError, - $bResult, - ) = - logDebugParam - ( - __PACKAGE__ . '::executeSql', \@_, - {name => 'strSql'}, - {name => 'bIgnoreError', default => false}, - {name => 'bResult', default => true}, - ); - - # Get the user-defined command for psql - my @stryResult; - - $self->connect(); - my $strResult = $self->{oDb}->query($strSql); - - if (defined($strResult)) - { - @stryResult = @{JSON::PP->new()->allow_nonref()->decode($strResult)}; - } - - # Return from function and log return values if any - return logDebugReturn - ( - $strOperation, - {name => 'stryResult', value => \@stryResult, ref => true} - ); -} - -#################################################################################################################################### -# executeSqlRow -#################################################################################################################################### -sub executeSqlRow -{ - my $self = shift; - - # Assign function parameters, defaults, and log debug info - my - ( - $strOperation, - $strSql - ) = - logDebugParam - ( - __PACKAGE__ . '->executeSqlRow', \@_, - {name => 'strSql'} - ); - - # Return from function and log return values if any - return logDebugReturn - ( - $strOperation, - {name => 'stryResult', value => @{$self->executeSql($strSql)}[0]} - ); -} - -#################################################################################################################################### -# executeSqlOne -#################################################################################################################################### -sub executeSqlOne -{ - my $self = shift; - - # Assign function parameters, defaults, and log debug info - my - ( - $strOperation, - $strSql - ) = - logDebugParam - ( - __PACKAGE__ . '->executeSqlOne', \@_, - {name => 'strSql'} - ); - - # Return from function and log return values if any - return logDebugReturn - ( - $strOperation, - {name => 'strResult', value => @{@{$self->executeSql($strSql)}[0]}[0]} - ); -} - -#################################################################################################################################### -# info -#################################################################################################################################### -sub info -{ - my $self = shift; - - # Assign function parameters, defaults, and log debug info - my - ( - $strOperation, - $strDbPath - ) = - logDebugParam - ( - __PACKAGE__ . '->info', \@_, - {name => 'strDbPath', default => $self->{strDbPath}} - ); - - # Get info if it is not cached - #------------------------------------------------------------------------------------------------------------------------------- - if (!defined($self->{info}{$strDbPath})) - { - # Open the control file and read system id and versions - #----------------------------------------------------------------------------------------------------------------------- - my $strControlFile = "${strDbPath}/" . DB_FILE_PGCONTROL; - my $hFile; - my $tBlock; - - sysopen($hFile, $strControlFile, O_RDONLY) - or confess &log(ERROR, "unable to open ${strControlFile}", ERROR_FILE_OPEN); - - # Read system identifier - sysread($hFile, $tBlock, 8) == 8 - or confess &log(ERROR, "unable to read database system identifier"); - - $self->{info}{$strDbPath}{ullDbSysId} = unpack('Q', $tBlock); - - # Read control version - sysread($hFile, $tBlock, 4) == 4 - or confess &log(ERROR, "unable to read control version"); - - $self->{info}{$strDbPath}{iDbControlVersion} = unpack('L', $tBlock); - - # Read catalog version - sysread($hFile, $tBlock, 4) == 4 - or confess &log(ERROR, "unable to read catalog version"); - - $self->{info}{$strDbPath}{iDbCatalogVersion} = unpack('L', $tBlock); - - # Close the control file - close($hFile); - - # Get PostgreSQL version - $self->{info}{$strDbPath}{strDbVersion} = - $oPgControlVersionHash->{$self->{info}{$strDbPath}{iDbControlVersion}} - {$self->{info}{$strDbPath}{iDbCatalogVersion}}; - - if (!defined($self->{info}{$strDbPath}{strDbVersion})) - { - confess &log( - ERROR, - 'unexpected control version = ' . $self->{info}{$strDbPath}{iDbControlVersion} . - ' and catalog version = ' . $self->{info}{$strDbPath}{iDbCatalogVersion} . "\n" . - 'HINT: is this version of PostgreSQL supported?', - ERROR_VERSION_NOT_SUPPORTED); - } - } - - # Return from function and log return values if any - return logDebugReturn - ( - $strOperation, - {name => 'strDbVersion', value => $self->{info}{$strDbPath}{strDbVersion}}, - {name => 'iDbControlVersion', value => $self->{info}{$strDbPath}{iDbControlVersion}}, - {name => 'iDbCatalogVersion', value => $self->{info}{$strDbPath}{iDbCatalogVersion}}, - {name => 'ullDbSysId', value => $self->{info}{$strDbPath}{ullDbSysId}} - ); -} - -#################################################################################################################################### -# versionGet -#################################################################################################################################### -sub versionGet -{ - my $self = shift; - - # Assign function parameters, defaults, and log debug info - my ($strOperation) = logDebugParam(__PACKAGE__ . '->versionGet'); - - # Get data from the cache if possible - if (defined($self->{strDbVersion}) && defined($self->{strDbPath})) - { - return $self->{strDbVersion}, $self->{strDbPath}; - } - - # Get version and pg-path from - my ($strVersionNum, $strDbPath) = - $self->executeSqlRow( - "select (select setting from pg_settings where name = 'server_version_num'), " . - " (select setting from pg_settings where name = 'data_directory')"); - - # Get first part of the major version - for 10 and above there will only be one part - $self->{strDbVersion} = substr($strVersionNum, 0, length($strVersionNum) - 4); - - # Now retrieve the second part of the major version for versions less than 10 - if ($self->{strDbVersion} < PG_VERSION_10) - { - $self->{strDbVersion} .= qw{.} . int(substr($strVersionNum, 1, 2)); - } - - # Check that the version is supported - my @stryVersionSupport = versionSupport(); - - if ($self->{strDbVersion} < $stryVersionSupport[0]) - { - confess &log(ERROR, 'unsupported Postgres version' . $self->{strDbVersion}, ERROR_VERSION_NOT_SUPPORTED); - } - - # Return from function and log return values if any - return logDebugReturn - ( - $strOperation, - {name => 'strDbVersion', value => $self->{strDbVersion}}, - {name => 'strDbPath', value => $strDbPath} - ); -} - -#################################################################################################################################### -# configValidate -# -# Validate the database configuration and archiving. -#################################################################################################################################### -sub configValidate -{ - my $self = shift; - - # Assign function parameters, defaults, and log debug info - my - ( - $strOperation, - ) = - logDebugParam - ( - __PACKAGE__ . '->configValidate', \@_, - ); - - # Get the version from the control file - my ($strDbVersion) = $self->info(); - - # Get version and db path from the database - my ($fCompareDbVersion, $strCompareDbPath) = $self->versionGet(); - - # Error if the version from the control file and the configured pg-path do not match the values obtained from the database - if (!($strDbVersion == $fCompareDbVersion && $self->{strDbPath} eq $strCompareDbPath)) - { - confess &log(ERROR, - "version '${fCompareDbVersion}' and path '${strCompareDbPath}' queried from cluster do not match version" . - " '${strDbVersion}' and " . cfgOptionName(CFGOPT_PG_PATH) . " '$self->{strDbPath}' read from" . - " '$self->{strDbPath}/" . DB_FILE_PGCONTROL . "'\n" . - "HINT: the " . cfgOptionName(CFGOPT_PG_PATH) . " and " . cfgOptionName(CFGOPT_PG_PORT) . - " settings likely reference different clusters.", - ERROR_DB_MISMATCH); - } - - # If cluster is not a standby and archive checking is enabled, then perform various validations - if (!$self->isStandby() && cfgOptionValid(CFGOPT_ARCHIVE_CHECK) && cfgOption(CFGOPT_ARCHIVE_CHECK)) - { - my $strArchiveMode = $self->executeSqlOne('show archive_mode'); - - # Error if archive_mode = off since pg_start_backup () will fail - if ($strArchiveMode eq 'off') - { - confess &log(ERROR, 'archive_mode must be enabled', ERROR_ARCHIVE_DISABLED); - } - - # Error if archive_mode = always (support has not been added yet) - if ($strArchiveMode eq 'always') - { - confess &log(ERROR, "archive_mode=always not supported", ERROR_FEATURE_NOT_SUPPORTED); - } - - # Check if archive_command is set - my $strArchiveCommand = $self->executeSqlOne('show archive_command'); - - if (index($strArchiveCommand, PROJECT_EXE) == -1) - { - confess &log(ERROR, - 'archive_command ' . (defined($strArchiveCommand) ? "'${strArchiveCommand}'" : '[null]') . ' must contain \'' . - PROJECT_EXE . '\'', ERROR_ARCHIVE_COMMAND_INVALID); - } - } - - return logDebugReturn - ( - $strOperation - ); -} - -#################################################################################################################################### -# walId -# -# Returns 'wal' or 'xlog' depending on the version of PostgreSQL. -#################################################################################################################################### -sub walId -{ - my $self = shift; - - return $self->{strDbVersion} >= PG_VERSION_10 ? 'wal' : 'xlog'; -} - -#################################################################################################################################### -# isStandby -# -# Determines if a database is a standby by testing if it is in recovery mode. -#################################################################################################################################### -sub isStandby -{ - my $self = shift; - - # Assign function parameters, defaults, and log debug info - my ($strOperation) = logDebugParam(__PACKAGE__ . '->isStandby'); - - if (!defined($self->{bStandby})) - { - my ($strDbVersion) = $self->versionGet(); - - if ($strDbVersion <= PG_VERSION_90) - { - $self->{bStandby} = false; - } - else - { - $self->{bStandby} = $self->executeSqlOne('select pg_is_in_recovery()') ? true : false; - } - } - - # Return from function and log return values if any - return logDebugReturn - ( - $strOperation, - {name => 'bStandby', value => $self->{bStandby}} - ); -} - -#################################################################################################################################### -# dbObjectGet -# -# Gets the database objects(s) and indexes. The databases required for the backup type must be online. A connection to the available -# databases will be established to determine which is the master and which, if any, is the standby. If there is a master and a -# standby to which a connection can be established, it returns both, else just the master. -#################################################################################################################################### -sub dbObjectGet -{ - # Assign function parameters, defaults, and log debug info - my ( - $strOperation, - $bMasterOnly, - ) = - logDebugParam - ( - __PACKAGE__ . '::dbObjectGet', \@_, - {name => 'bMasterOnly', optional => true, default => false}, - ); - - my $iStandbyIdx = undef; - my $iMasterRemoteIdx = 1; - my $oDbMaster = undef; - my $oDbStandby = undef; - - # Only iterate databases if online and more than one is defined. It might be better to check the version of each database but - # this is simple and works. - if (!$bMasterOnly && cfgOptionTest(CFGOPT_ONLINE) && cfgOption(CFGOPT_ONLINE) && multipleDb()) - { - for (my $iRemoteIdx = 1; $iRemoteIdx <= cfgOptionIndexTotal(CFGOPT_PG_HOST); $iRemoteIdx++) - { - # Make sure a db is defined for this index - if (cfgOptionTest(cfgOptionIdFromIndex(CFGOPT_PG_PATH, $iRemoteIdx)) || - cfgOptionTest(cfgOptionIdFromIndex(CFGOPT_PG_HOST, $iRemoteIdx))) - { - # Create the db object - my $oDb; - - logWarnOnErrorEnable(); - eval - { - $oDb = new pgBackRest::Db($iRemoteIdx); - return true; - } - or do {}; - - logWarnOnErrorDisable(); - my $bAssigned = false; - - if (defined($oDb)) - { - # If able to connect then test if the database is a master or a standby. It's OK if some databases cannot be - # reached as long as the databases required for the backup type are present. - if ($oDb->connect(true)) - { - # If this db is a standby - if ($oDb->isStandby()) - { - # If standby backup is requested then use the first standby found - if (cfgOption(CFGOPT_BACKUP_STANDBY) && !defined($oDbStandby)) - { - $oDbStandby = $oDb; - $iStandbyIdx = $iRemoteIdx; - $bAssigned = true; - } - } - # Else this db is a master - else - { - # Error if more than one master is found - if (defined($oDbMaster)) - { - confess &log(ERROR, 'more than one master database found'); - } - - $oDbMaster = $oDb; - $iMasterRemoteIdx = $iRemoteIdx; - $bAssigned = true; - } - } - } - } - } - - # Make sure a standby database is defined when backup from standby option is set - if (cfgOption(CFGOPT_BACKUP_STANDBY) && !defined($oDbStandby)) - { - # Throw an error that is distinct from connecting to the master for testing purposes - confess &log(ERROR, 'unable to find standby database - cannot proceed', ERROR_HOST_CONNECT); - } - - # A master database is always required - if (!defined($oDbMaster)) - { - # Throw an error that is distinct from connecting to a standy for testing purposes - confess &log(ERROR, 'unable to find master database - cannot proceed', ERROR_DB_CONNECT); - } - } - - # If master db is not already defined then set to default - if (!defined($oDbMaster)) - { - $oDbMaster = new pgBackRest::Db($iMasterRemoteIdx); - } - - # Return from function and log return values if any - return logDebugReturn - ( - $strOperation, - {name => 'oDbMaster', value => $oDbMaster}, - {name => 'iDbMasterIdx', value => $iMasterRemoteIdx}, - {name => 'oDbStandby', value => $oDbStandby}, - {name => 'iDbStandbyIdx', value => $iStandbyIdx}, - ); -} - -push @EXPORT, qw(dbObjectGet); - -#################################################################################################################################### -# dbMasterGet -# -# Usually only the master database is required so this function makes getting it simple. If in offline mode (which is true for a -# lot of archive operations) then the database returned is simply the first configured. -#################################################################################################################################### -sub dbMasterGet -{ - # Assign function parameters, defaults, and log debug info - my ($strOperation) = logDebugParam(__PACKAGE__ . '::dbMasterGet'); - - my ($oDbMaster) = dbObjectGet({bMasterOnly => true}); - - # Return from function and log return values if any - return logDebugReturn - ( - $strOperation, - {name => 'oDbMaster', value => $oDbMaster, trace => true}, - ); -} - -push @EXPORT, qw(dbMasterGet); - -#################################################################################################################################### -# multipleDb -# -# Helper function to determine if there is more than one database defined. -#################################################################################################################################### -sub multipleDb -{ - for (my $iDbPathIdx = 2; $iDbPathIdx <= cfgOptionIndexTotal(CFGOPT_PG_PATH); $iDbPathIdx++) - { - # If an index exists above 1 then return true - if (cfgOptionTest(cfgOptionIdFromIndex(CFGOPT_PG_PATH, $iDbPathIdx))) - { - return true; - } - } - - return false; -} - -1; diff --git a/libc/LibC.xs b/libc/LibC.xs index 197762347..f2ad85456 100644 --- a/libc/LibC.xs +++ b/libc/LibC.xs @@ -67,7 +67,6 @@ XSH includes These includes define data structures that are required for the C to Perl interface but are not part of the regular C source. ***********************************************************************************************************************************/ #include "xs/config/configTest.xsh" -#include "xs/postgres/client.xsh" #include "xs/storage/storage.xsh" #include "xs/storage/storageRead.xsh" #include "xs/storage/storageWrite.xsh" @@ -94,7 +93,6 @@ OUTPUT: INCLUDE: xs/config/config.xs INCLUDE: xs/config/configTest.xs INCLUDE: xs/config/define.xs -INCLUDE: xs/postgres/client.xs INCLUDE: xs/storage/storage.xs INCLUDE: xs/storage/storageRead.xs INCLUDE: xs/storage/storageWrite.xs diff --git a/libc/Makefile.PL b/libc/Makefile.PL index e9ce5b760..fae5f175c 100644 --- a/libc/Makefile.PL +++ b/libc/Makefile.PL @@ -98,7 +98,6 @@ my @stryCFile = 'protocol/parallel.c', 'protocol/parallelJob.c', 'protocol/server.c', - 'postgres/client.c', 'storage/posix/read.c', 'storage/posix/storage.c', 'storage/posix/write.c', diff --git a/libc/typemap b/libc/typemap index 5c1754df0..14e50c447 100644 --- a/libc/typemap +++ b/libc/typemap @@ -1,4 +1,3 @@ -pgBackRest::LibC::PgClient T_PTROBJ pgBackRest::LibC::Storage T_PTROBJ pgBackRest::LibC::StorageRead T_PTROBJ pgBackRest::LibC::StorageWrite T_PTROBJ diff --git a/libc/xs/postgres/client.xs b/libc/xs/postgres/client.xs deleted file mode 100644 index b6dbc6c71..000000000 --- a/libc/xs/postgres/client.xs +++ /dev/null @@ -1,91 +0,0 @@ -# ---------------------------------------------------------------------------------------------------------------------------------- -# PostgreSQL Query Client -# ---------------------------------------------------------------------------------------------------------------------------------- - -MODULE = pgBackRest::LibC PACKAGE = pgBackRest::LibC::PgClient - -#################################################################################################################################### -pgBackRest::LibC::PgClient -new(class, host, port, database, queryTimeout) -PREINIT: - MEM_CONTEXT_XS_TEMP_BEGIN() - { -INPUT: - const String *class = STR_NEW_SV($arg); - const String *host = STR_NEW_SV($arg); - U32 port - const String *database = STR_NEW_SV($arg); - UV queryTimeout -CODE: - CHECK(strEqZ(class, PACKAGE_NAME_LIBC "::PgClient")); - - MEM_CONTEXT_PRIOR_BEGIN() - { - RETVAL = pgClientNew(host, port, database, NULL, queryTimeout); - } - MEM_CONTEXT_PRIOR_END(); -OUTPUT: - RETVAL -CLEANUP: - } - MEM_CONTEXT_XS_TEMP_END(); - -#################################################################################################################################### -void -open(self) -PREINIT: - MEM_CONTEXT_XS_TEMP_BEGIN() - { -INPUT: - pgBackRest::LibC::PgClient self -CODE: - pgClientOpen(self); -CLEANUP: - } - MEM_CONTEXT_XS_TEMP_END(); - -#################################################################################################################################### -const char * -query(self, query) -PREINIT: - MEM_CONTEXT_XS_TEMP_BEGIN() - { -INPUT: - pgBackRest::LibC::PgClient self - const String *query = STR_NEW_SV($arg); -CODE: - VariantList *result = pgClientQuery(self, query); - RETVAL = result ? strPtr(jsonFromVar(varNewVarLst(result))) : NULL; -OUTPUT: - RETVAL -CLEANUP: - } - MEM_CONTEXT_XS_TEMP_END(); - -#################################################################################################################################### -void -close(self) -PREINIT: - MEM_CONTEXT_XS_TEMP_BEGIN() - { -INPUT: - pgBackRest::LibC::PgClient self -CODE: - pgClientClose(self); -CLEANUP: - } - MEM_CONTEXT_XS_TEMP_END(); - -#################################################################################################################################### -void -DESTROY(self) -PREINIT: - MEM_CONTEXT_XS_TEMP_BEGIN() - { -INPUT: - pgBackRest::LibC::PgClient self -CODE: - pgClientFree(self); -CLEANUP: - } - MEM_CONTEXT_XS_TEMP_END(); diff --git a/libc/xs/postgres/client.xsh b/libc/xs/postgres/client.xsh deleted file mode 100644 index c6f0ac834..000000000 --- a/libc/xs/postgres/client.xsh +++ /dev/null @@ -1,6 +0,0 @@ -/*********************************************************************************************************************************** -PostgreSQL Query Client Header -***********************************************************************************************************************************/ -#include "postgres/client.h" - -typedef PgClient *pgBackRest__LibC__PgClient; diff --git a/test/lib/pgBackRestTest/Env/ExpireEnvTest.pm b/test/lib/pgBackRestTest/Env/ExpireEnvTest.pm index ce7399dcc..8378d06bf 100644 --- a/test/lib/pgBackRestTest/Env/ExpireEnvTest.pm +++ b/test/lib/pgBackRestTest/Env/ExpireEnvTest.pm @@ -11,15 +11,16 @@ use strict; use warnings FATAL => qw(all); use Carp qw(confess); +use Fcntl qw(O_RDONLY); use File::Basename qw(basename); use pgBackRest::Archive::Info; use pgBackRest::Backup::Common; use pgBackRest::Backup::Info; +use pgBackRest::Common::Exception; use pgBackRest::Common::Ini; use pgBackRest::Common::Log; use pgBackRest::Config::Config; -use pgBackRest::Db; use pgBackRest::DbVersion; use pgBackRest::Manifest; use pgBackRest::Protocol::Storage::Helper; @@ -72,6 +73,116 @@ sub new ); } +#################################################################################################################################### +# get into from pg_control +#################################################################################################################################### +my $oPgControlVersionHash = +{ + # iControlVersion => {iCatalogVersion => strDbVersion} + 833 => {200711281 => PG_VERSION_83}, + 843 => {200904091 => PG_VERSION_84}, + 903 => + { + 201008051 => PG_VERSION_90, + 201105231 => PG_VERSION_91, + }, + 922 => {201204301 => PG_VERSION_92}, + 937 => {201306121 => PG_VERSION_93}, + 942 => + { + 201409291 => PG_VERSION_94, + 201510051 => PG_VERSION_95, + }, + 960 => + { + 201608131 => PG_VERSION_96, + }, + 1002 => + { + 201707211 => PG_VERSION_10, + }, + 1100 => + { + 201809051 => PG_VERSION_11, + }, + 1201 => + { + 201909212 => PG_VERSION_12, + }, +}; + +sub info +{ + my $self = shift; + + # Assign function parameters, defaults, and log debug info + my + ( + $strOperation, + $strDbPath + ) = + logDebugParam + ( + __PACKAGE__ . '->info', \@_, + {name => 'strDbPath', default => cfgOption(CFGOPT_PG_PATH)} + ); + + # Open the control file and read system id and versions + #----------------------------------------------------------------------------------------------------------------------- + my $strControlFile = "${strDbPath}/" . DB_FILE_PGCONTROL; + my $hFile; + my $tBlock; + + sysopen($hFile, $strControlFile, O_RDONLY) + or confess &log(ERROR, "unable to open ${strControlFile}", ERROR_FILE_OPEN); + + # Read system identifier + sysread($hFile, $tBlock, 8) == 8 + or confess &log(ERROR, "unable to read database system identifier"); + + $self->{info}{$strDbPath}{ullDbSysId} = unpack('Q', $tBlock); + + # Read control version + sysread($hFile, $tBlock, 4) == 4 + or confess &log(ERROR, "unable to read control version"); + + $self->{info}{$strDbPath}{iDbControlVersion} = unpack('L', $tBlock); + + # Read catalog version + sysread($hFile, $tBlock, 4) == 4 + or confess &log(ERROR, "unable to read catalog version"); + + $self->{info}{$strDbPath}{iDbCatalogVersion} = unpack('L', $tBlock); + + # Close the control file + close($hFile); + + # Get PostgreSQL version + $self->{info}{$strDbPath}{strDbVersion} = + $oPgControlVersionHash->{$self->{info}{$strDbPath}{iDbControlVersion}} + {$self->{info}{$strDbPath}{iDbCatalogVersion}}; + + if (!defined($self->{info}{$strDbPath}{strDbVersion})) + { + confess &log( + ERROR, + 'unexpected control version = ' . $self->{info}{$strDbPath}{iDbControlVersion} . + ' and catalog version = ' . $self->{info}{$strDbPath}{iDbCatalogVersion} . "\n" . + 'HINT: is this version of PostgreSQL supported?', + ERROR_VERSION_NOT_SUPPORTED); + } + + # Return from function and log return values if any + return logDebugReturn + ( + $strOperation, + {name => 'strDbVersion', value => $self->{info}{$strDbPath}{strDbVersion}}, + {name => 'iDbControlVersion', value => $self->{info}{$strDbPath}{iDbControlVersion}}, + {name => 'iDbCatalogVersion', value => $self->{info}{$strDbPath}{iDbCatalogVersion}}, + {name => 'ullDbSysId', value => $self->{info}{$strDbPath}{ullDbSysId}} + ); +} + #################################################################################################################################### # stanzaSet - set the local stanza object #################################################################################################################################### @@ -124,15 +235,13 @@ sub stanzaSet {strCipherPassSub => $bEncrypted ? ENCRYPTION_KEY_MANIFEST : undef}); } - my ($oDb) = dbObjectGet(); if (cfgOption(CFGOPT_ONLINE)) { - # If the pg-path in pgbackrest.conf does not match the pg_control then this will error alert the user to fix pgbackrest.conf - $oDb->configValidate(); + confess &log(ERROR, "this function may not be used for online tests"); } # Get the database info for the stanza - (my $strVersion, $$oStanza{iControlVersion}, $$oStanza{iCatalogVersion}, $$oStanza{ullDbSysId}) = $oDb->info(); + (my $strVersion, $$oStanza{iControlVersion}, $$oStanza{iCatalogVersion}, $$oStanza{ullDbSysId}) = $self->info(); $$oStanza{strDbVersion} = $strDbVersion; if ($bStanzaUpgrade) diff --git a/test/lib/pgBackRestTest/Env/Host/HostBackupTest.pm b/test/lib/pgBackRestTest/Env/Host/HostBackupTest.pm index 8757415fb..de13062ba 100644 --- a/test/lib/pgBackRestTest/Env/Host/HostBackupTest.pm +++ b/test/lib/pgBackRestTest/Env/Host/HostBackupTest.pm @@ -1105,8 +1105,8 @@ sub configCreate if (defined($oHostDb2)) { - # Add an invalid replica to simulate more than one replica. A warning should be thrown by dbObjectGet when a stanza is - # created and a valid replica should be chosen. + # Add an invalid replica to simulate more than one replica. A warning should be thrown when a stanza is created and a + # valid replica should be chosen. my $iInvalidReplica = 2; $oParamHash{$strStanza}{cfgOptionName(cfgOptionIdFromIndex(CFGOPT_PG_HOST, $iInvalidReplica))} = BOGUS; $oParamHash{$strStanza}{cfgOptionName(cfgOptionIdFromIndex(CFGOPT_PG_HOST_USER, $iInvalidReplica))} = diff --git a/test/lib/pgBackRestTest/Module/Real/RealAllTest.pm b/test/lib/pgBackRestTest/Module/Real/RealAllTest.pm index f807621e9..405c7637c 100644 --- a/test/lib/pgBackRestTest/Module/Real/RealAllTest.pm +++ b/test/lib/pgBackRestTest/Module/Real/RealAllTest.pm @@ -15,7 +15,6 @@ use File::Basename qw(dirname); use pgBackRest::Archive::Info; use pgBackRest::Backup::Info; -use pgBackRest::Db; use pgBackRest::DbVersion; use pgBackRest::Common::Exception; use pgBackRest::Common::Ini; @@ -40,6 +39,11 @@ use pgBackRestTest::Env::HostEnvTest; use pgBackRestTest::Common::Storage; use pgBackRestTest::Common::StoragePosix; +#################################################################################################################################### +# Backup advisory lock +#################################################################################################################################### +use constant DB_BACKUP_ADVISORY_LOCK => '12340078987004321'; + #################################################################################################################################### # run ####################################################################################################################################