- 11 Beta 4 support.
+ 11 Beta 4 support, including configurable WAL segment size.
diff --git a/lib/pgBackRest/Archive/Common.pm b/lib/pgBackRest/Archive/Common.pm
index b6e118d6a..fe6de439b 100644
--- a/lib/pgBackRest/Archive/Common.pm
+++ b/lib/pgBackRest/Archive/Common.pm
@@ -125,6 +125,7 @@ sub lsnFileRange
$strLsnStart,
$strLsnStop,
$strDbVersion,
+ $iWalSegmentSize,
) =
logDebugParam
(
@@ -132,6 +133,7 @@ sub lsnFileRange
{name => 'strLsnStart'},
{name => 'strLsnStop'},
{name => '$strDbVersion'},
+ {name => '$iWalSegmentSize'},
);
# Working variables
@@ -142,11 +144,11 @@ sub lsnFileRange
# Iterate through all archive logs between start and stop
my @stryArchiveSplit = split('/', $strLsnStart);
my $iStartMajor = hex($stryArchiveSplit[0]);
- my $iStartMinor = hex(substr(sprintf("%08s", $stryArchiveSplit[1]), 0, 2));
+ my $iStartMinor = int(hex($stryArchiveSplit[1]) / $iWalSegmentSize);
@stryArchiveSplit = split('/', $strLsnStop);
my $iStopMajor = hex($stryArchiveSplit[0]);
- my $iStopMinor = hex(substr(sprintf("%08s", $stryArchiveSplit[1]), 0, 2));
+ my $iStopMinor = int(hex($stryArchiveSplit[1]) / $iWalSegmentSize);
$stryArchive[$iArchiveIdx] = uc(sprintf("%08x%08x", $iStartMajor, $iStartMinor));
$iArchiveIdx += 1;
@@ -155,7 +157,7 @@ sub lsnFileRange
{
$iStartMinor += 1;
- if ($bSkipFF && $iStartMinor == 255 || !$bSkipFF && $iStartMinor == 256)
+ if ($bSkipFF && $iStartMinor == 255 || !$bSkipFF && $iStartMinor > int(0xFFFFFFFF / $iWalSegmentSize))
{
$iStartMajor += 1;
$iStartMinor = 0;
diff --git a/lib/pgBackRest/Backup/Backup.pm b/lib/pgBackRest/Backup/Backup.pm
index 331395a83..72384032d 100644
--- a/lib/pgBackRest/Backup/Backup.pm
+++ b/lib/pgBackRest/Backup/Backup.pm
@@ -723,6 +723,7 @@ sub process
# Start backup (unless --no-online is set)
my $strArchiveStart = undef;
my $strLsnStart = undef;
+ my $iWalSegmentSize = undef;
my $hTablespaceMap = undef;
my $hDatabaseMap = undef;
@@ -757,7 +758,7 @@ sub process
else
{
# Start the backup
- ($strArchiveStart, $strLsnStart) =
+ ($strArchiveStart, $strLsnStart, $iWalSegmentSize) =
$oDbMaster->backupStart(
BACKREST_NAME . ' backup started at ' . timestampFormat(undef, $lTimestampStart), cfgOption(CFGOPT_START_FAST));
@@ -929,7 +930,7 @@ sub process
my $oArchiveInfo = new pgBackRest::Archive::Info(storageRepo()->pathGet(STORAGE_REPO_ARCHIVE), true);
my $strArchiveId = $oArchiveInfo->archiveId();
- my @stryArchive = lsnFileRange($strLsnStart, $strLsnStop, $strDbVersion);
+ my @stryArchive = lsnFileRange($strLsnStart, $strLsnStop, $strDbVersion, $iWalSegmentSize);
foreach my $strArchive (@stryArchive)
{
diff --git a/lib/pgBackRest/Db.pm b/lib/pgBackRest/Db.pm
index 118258ebd..b8145d839 100644
--- a/lib/pgBackRest/Db.pm
+++ b/lib/pgBackRest/Db.pm
@@ -680,8 +680,13 @@ sub backupStart
"exclusive pg_start_backup() with label \"${strLabel}\": backup begins after " .
($bStartFast ? "the requested immediate checkpoint" : "the next regular checkpoint") . " completes");
- my ($strTimestampDbStart, $strArchiveStart, $strLsnStart) = $self->executeSqlRow(
- "select to_char(current_timestamp, 'YYYY-MM-DD HH24:MI:SS.US TZ'), pg_" . $self->walId() . "file_name(lsn), lsn::text" .
+ my ($strTimestampDbStart, $strArchiveStart, $strLsnStart, $iWalSegmentSize) = $self->executeSqlRow(
+ "select to_char(current_timestamp, 'YYYY-MM-DD HH24:MI:SS.US TZ'), pg_" . $self->walId() . "file_name(lsn), lsn::text," .
+ ($self->{strDbVersion} < PG_VERSION_84 ? PG_WAL_SIZE :
+ " (select setting::int8 from pg_settings where name = 'wal_segment_size')" .
+ # In Pre-11 versions the wal_segment_sise was expressed in terms of blocks rather than total size
+ ($self->{strDbVersion} < PG_VERSION_11 ?
+ " * (select setting::int8 from pg_settings where name = 'wal_block_size')" : '')) .
" from pg_start_backup('${strLabel}'" .
($bStartFast ? ', true' : $self->{strDbVersion} >= PG_VERSION_84 ? ', false' : '') .
($self->{strDbVersion} >= PG_VERSION_96 ? ', false' : '') . ') as lsn');
@@ -692,6 +697,7 @@ sub backupStart
$strOperation,
{name => 'strArchiveStart', value => $strArchiveStart},
{name => 'strLsnStart', value => $strLsnStart},
+ {name => 'iWalSegmentSize', value => $iWalSegmentSize},
{name => 'strTimestampDbStart', value => $strTimestampDbStart}
);
}
diff --git a/src/Makefile b/src/Makefile
index 45eed2c6d..29a2bae10 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -110,7 +110,18 @@ SRCS = \
info/infoPg.c \
perl/config.c \
perl/exec.c \
- postgres/info.c \
+ postgres/interface.c \
+ postgres/interface/v083.c \
+ postgres/interface/v084.c \
+ postgres/interface/v090.c \
+ postgres/interface/v091.c \
+ postgres/interface/v092.c \
+ postgres/interface/v093.c \
+ postgres/interface/v094.c \
+ postgres/interface/v095.c \
+ postgres/interface/v096.c \
+ postgres/interface/v100.c \
+ postgres/interface/v110.c \
postgres/pageChecksum.c \
storage/driver/posix/storage.c \
storage/driver/posix/common.c \
@@ -144,10 +155,10 @@ install: pgbackrest
command/archive/common.o: command/archive/common.c command/archive/common.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h postgres/version.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h
$(CC) $(CFLAGS) -c command/archive/common.c -o command/archive/common.o
-command/archive/get/file.o: command/archive/get/file.c command/archive/common.h command/archive/get/file.h command/control/control.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h compress/gzip.h compress/gzipDecompress.h config/config.auto.h config/config.h config/define.auto.h config/define.h info/infoArchive.h info/infoPg.h postgres/info.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h
+command/archive/get/file.o: command/archive/get/file.c command/archive/common.h command/archive/get/file.h command/control/control.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h compress/gzip.h compress/gzipDecompress.h config/config.auto.h config/config.h config/define.auto.h config/define.h info/infoArchive.h info/infoPg.h postgres/interface.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h
$(CC) $(CFLAGS) -c command/archive/get/file.c -o command/archive/get/file.o
-command/archive/get/get.o: command/archive/get/get.c command/archive/common.h command/archive/get/file.h command/command.h common/assert.h common/debug.h common/error.auto.h common/error.h common/fork.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/load.h perl/exec.h postgres/info.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h
+command/archive/get/get.o: command/archive/get/get.c command/archive/common.h command/archive/get/file.h command/command.h common/assert.h common/debug.h common/error.auto.h common/error.h common/fork.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/load.h perl/exec.h postgres/interface.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h
$(CC) $(CFLAGS) -c command/archive/get/get.c -o command/archive/get/get.o
command/archive/push/push.o: command/archive/push/push.c command/archive/common.h command/command.h common/debug.h common/error.auto.h common/error.h common/fork.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/load.h perl/exec.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h
@@ -300,10 +311,10 @@ info/info.o: info/info.c common/debug.h common/error.auto.h common/error.h commo
info/infoArchive.o: info/infoArchive.c common/debug.h common/error.auto.h common/error.h common/ini.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h info/infoArchive.h info/infoPg.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h
$(CC) $(CFLAGS) -c info/infoArchive.c -o info/infoArchive.o
-info/infoPg.o: info/infoPg.c common/assert.h common/debug.h common/error.auto.h common/error.h common/ini.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/json.h common/type/keyValue.h common/type/list.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h crypto/hash.h info/info.h info/infoPg.h postgres/info.h postgres/version.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h
+info/infoPg.o: info/infoPg.c common/assert.h common/debug.h common/error.auto.h common/error.h common/ini.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/json.h common/type/keyValue.h common/type/list.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h crypto/hash.h info/info.h info/infoPg.h postgres/interface.h postgres/version.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h
$(CC) $(CFLAGS) -c info/infoPg.c -o info/infoPg.o
-main.o: main.c command/archive/get/get.h command/archive/push/push.h command/command.h command/help/help.h common/debug.h common/error.auto.h common/error.h common/exit.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/load.h perl/exec.h version.h
+main.o: main.c command/archive/get/get.h command/archive/push/push.h command/command.h command/help/help.h common/debug.h common/error.auto.h common/error.h common/exit.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/load.h perl/exec.h postgres/interface.h version.h
$(CC) $(CFLAGS) -c main.c -o main.o
perl/config.o: perl/config.c common/debug.h common/error.auto.h common/error.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h
@@ -312,10 +323,43 @@ perl/config.o: perl/config.c common/debug.h common/error.auto.h common/error.h c
perl/exec.o: perl/exec.c ../libc/LibC.h common/debug.h common/encode.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/load.h config/parse.h crypto/cipher.h crypto/cipherBlock.h crypto/hash.h crypto/random.h perl/config.h perl/embed.auto.c perl/exec.h perl/libc.auto.c postgres/pageChecksum.h storage/driver/posix/fileRead.h storage/driver/posix/fileWrite.h storage/driver/posix/storage.h storage/fileRead.h storage/fileWrite.h storage/info.h storage/storage.h storage/storage.intern.h version.h ../libc/xs/common/encode.xsh ../libc/xs/crypto/cipherBlock.xsh ../libc/xs/crypto/hash.xsh
$(CC) $(CFLAGS) -c perl/exec.c -o perl/exec.o
-postgres/info.o: postgres/info.c common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h postgres/info.h postgres/type.h postgres/version.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h
- $(CC) $(CFLAGS) -c postgres/info.c -o postgres/info.o
+postgres/interface.o: postgres/interface.c common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h postgres/interface.h postgres/interface/v083.h postgres/interface/v084.h postgres/interface/v090.h postgres/interface/v091.h postgres/interface/v092.h postgres/interface/v093.h postgres/interface/v094.h postgres/interface/v095.h postgres/interface/v096.h postgres/interface/v100.h postgres/interface/v110.h postgres/version.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h
+ $(CC) $(CFLAGS) -c postgres/interface.c -o postgres/interface.o
-postgres/pageChecksum.o: postgres/pageChecksum.c common/assert.h common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/stackTrace.h common/type/convert.h postgres/pageChecksum.h postgres/type.h
+postgres/interface/v083.o: postgres/interface/v083.c common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h postgres/interface.h postgres/interface/v083.auto.c postgres/interface/v083.h
+ $(CC) $(CFLAGS) -c postgres/interface/v083.c -o postgres/interface/v083.o
+
+postgres/interface/v084.o: postgres/interface/v084.c common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h postgres/interface.h postgres/interface/v084.auto.c postgres/interface/v084.h
+ $(CC) $(CFLAGS) -c postgres/interface/v084.c -o postgres/interface/v084.o
+
+postgres/interface/v090.o: postgres/interface/v090.c common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h postgres/interface.h postgres/interface/v090.auto.c postgres/interface/v090.h
+ $(CC) $(CFLAGS) -c postgres/interface/v090.c -o postgres/interface/v090.o
+
+postgres/interface/v091.o: postgres/interface/v091.c common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h postgres/interface.h postgres/interface/v091.auto.c postgres/interface/v091.h
+ $(CC) $(CFLAGS) -c postgres/interface/v091.c -o postgres/interface/v091.o
+
+postgres/interface/v092.o: postgres/interface/v092.c common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h postgres/interface.h postgres/interface/v092.auto.c postgres/interface/v092.h
+ $(CC) $(CFLAGS) -c postgres/interface/v092.c -o postgres/interface/v092.o
+
+postgres/interface/v093.o: postgres/interface/v093.c common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h postgres/interface.h postgres/interface/v093.auto.c postgres/interface/v093.h
+ $(CC) $(CFLAGS) -c postgres/interface/v093.c -o postgres/interface/v093.o
+
+postgres/interface/v094.o: postgres/interface/v094.c common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h postgres/interface.h postgres/interface/v094.auto.c postgres/interface/v094.h
+ $(CC) $(CFLAGS) -c postgres/interface/v094.c -o postgres/interface/v094.o
+
+postgres/interface/v095.o: postgres/interface/v095.c common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h postgres/interface.h postgres/interface/v095.auto.c postgres/interface/v095.h
+ $(CC) $(CFLAGS) -c postgres/interface/v095.c -o postgres/interface/v095.o
+
+postgres/interface/v096.o: postgres/interface/v096.c common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h postgres/interface.h postgres/interface/v096.auto.c postgres/interface/v096.h
+ $(CC) $(CFLAGS) -c postgres/interface/v096.c -o postgres/interface/v096.o
+
+postgres/interface/v100.o: postgres/interface/v100.c common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h postgres/interface.h postgres/interface/v100.auto.c postgres/interface/v100.h
+ $(CC) $(CFLAGS) -c postgres/interface/v100.c -o postgres/interface/v100.o
+
+postgres/interface/v110.o: postgres/interface/v110.c common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h postgres/interface.h postgres/interface/v110.auto.c postgres/interface/v110.h
+ $(CC) $(CFLAGS) -c postgres/interface/v110.c -o postgres/interface/v110.o
+
+postgres/pageChecksum.o: postgres/pageChecksum.c common/assert.h common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/stackTrace.h common/type/convert.h postgres/pageChecksum.h
$(CC) $(CFLAGS) -funroll-loops -ftree-vectorize -c postgres/pageChecksum.c -o postgres/pageChecksum.o
storage/driver/posix/common.o: storage/driver/posix/common.c common/assert.h common/debug.h common/error.auto.h common/error.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h storage/driver/posix/common.h
diff --git a/src/command/archive/common.h b/src/command/archive/common.h
index 8aab50eba..fbb48935c 100644
--- a/src/command/archive/common.h
+++ b/src/command/archive/common.h
@@ -35,12 +35,9 @@ WAL segment constants
// Match on a WAL segment with partial allowed
#define WAL_SEGMENT_PARTIAL_REGEXP WAL_SEGMENT_PREFIX_REGEXP "(\\.partial){0,1}$"
-// Defines the size of standard WAL segment name -- this should never changed
+// Defines the size of standard WAL segment name -- hopefully this won't change
#define WAL_SEGMENT_NAME_SIZE ((unsigned int)24)
-// Default size of a WAL segment
-#define WAL_SEGMENT_DEFAULT_SIZE ((size_t)(16 * 1024 * 1024))
-
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
diff --git a/src/command/archive/get/file.c b/src/command/archive/get/file.c
index 1f903adb9..8474759ce 100644
--- a/src/command/archive/get/file.c
+++ b/src/command/archive/get/file.c
@@ -11,7 +11,7 @@ Archive Get File
#include "compress/gzipDecompress.h"
#include "config/config.h"
#include "info/infoArchive.h"
-#include "postgres/info.h"
+#include "postgres/interface.h"
#include "storage/helper.h"
#include "storage/helper.h"
@@ -32,7 +32,7 @@ archiveGetCheck(const String *archiveFile)
MEM_CONTEXT_TEMP_BEGIN()
{
// Get pg control info
- PgControlInfo controlInfo = pgControlInfo(cfgOptionStr(cfgOptPgPath));
+ PgControl controlInfo = pgControlFromFile(cfgOptionStr(cfgOptPgPath));
// Attempt to load the archive info file
InfoArchive *info = infoArchiveNew(storageRepo(), strNew(STORAGE_REPO_ARCHIVE "/" INFO_ARCHIVE_FILE), false);
diff --git a/src/command/archive/get/get.c b/src/command/archive/get/get.c
index 1d902ce48..de55e7bf6 100644
--- a/src/command/archive/get/get.c
+++ b/src/command/archive/get/get.c
@@ -17,7 +17,7 @@ Archive Get Command
#include "config/config.h"
#include "config/load.h"
#include "perl/exec.h"
-#include "postgres/info.h"
+#include "postgres/interface.h"
#include "storage/helper.h"
#include "storage/helper.h"
@@ -220,11 +220,8 @@ cmdArchiveGet(void)
if (lockAcquire( // {uncoverable - almost impossible to make this lock fail}
cfgOptionStr(cfgOptLockPath), cfgOptionStr(cfgOptStanza), cfgLockType(), 0, false))
{
- // Get the version of PostgreSQL
- unsigned int pgVersion = pgControlInfo(cfgOptionStr(cfgOptPgPath)).version;
-
- // Determine WAL segment size -- for now this is the default but for PG11 it will be configurable
- unsigned int walSegmentSize = WAL_SEGMENT_DEFAULT_SIZE;
+ // Get control info
+ PgControl pgControl = pgControlFromFile(cfgOptionStr(cfgOptPgPath));
// Create the queue
storagePathCreateNP(storageSpoolWrite(), strNew(STORAGE_SPOOL_ARCHIVE_IN));
@@ -233,8 +230,8 @@ cmdArchiveGet(void)
// will return the list of WAL needed to fill the queue and this will be passed to the async process.
cfgCommandParamSet(
queueNeed(
- walSegment, found, (size_t)cfgOptionInt64(cfgOptArchiveGetQueueMax), walSegmentSize,
- pgVersion));
+ walSegment, found, (size_t)cfgOptionInt64(cfgOptArchiveGetQueueMax), pgControl.walSegmentSize,
+ pgControl.version));
// The async process should not output on the console at all
cfgOptionSet(cfgOptLogLevelConsole, cfgSourceParam, varNewStrZ("off"));
diff --git a/src/info/infoPg.c b/src/info/infoPg.c
index 5b18f04c7..e5f4e1151 100644
--- a/src/info/infoPg.c
+++ b/src/info/infoPg.c
@@ -16,7 +16,7 @@ PostgreSQL Info Handler
#include "common/type/list.h"
#include "info/info.h"
#include "info/infoPg.h"
-#include "postgres/info.h"
+#include "postgres/interface.h"
#include "postgres/version.h"
#include "storage/helper.h"
diff --git a/src/main.c b/src/main.c
index a3560844d..a976100a5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -13,6 +13,7 @@ Main
#include "common/exit.h"
#include "config/config.h"
#include "config/load.h"
+#include "postgres/interface.h"
#include "perl/exec.h"
#include "version.h"
@@ -76,6 +77,13 @@ main(int argListSize, const char *argList[])
// -------------------------------------------------------------------------------------------------------------------------
else if (cfgCommand() == cfgCmdBackup)
{
+#ifdef DEBUG
+ // Check pg_control during testing so errors are more obvious. Otherwise errors only happen in archive-get/archive-push
+ // and end up in the PostgreSQL log which is not output in CI. This can be removed once backup is written in C.
+ if (cfgOptionBool(cfgOptOnline) && !cfgOptionBool(cfgOptBackupStandby) && !cfgOptionTest(cfgOptPgHost))
+ pgControlFromFile(cfgOptionStr(cfgOptPgPath));
+#endif
+
// Run backup
perlExec();
diff --git a/src/perl/embed.auto.c b/src/perl/embed.auto.c
index f131c01cc..e97907eee 100644
--- a/src/perl/embed.auto.c
+++ b/src/perl/embed.auto.c
@@ -162,6 +162,7 @@ static const EmbeddedModule embeddedModule[] =
"$strLsnStart,\n"
"$strLsnStop,\n"
"$strDbVersion,\n"
+ "$iWalSegmentSize,\n"
") =\n"
"logDebugParam\n"
"(\n"
@@ -169,6 +170,7 @@ static const EmbeddedModule embeddedModule[] =
"{name => 'strLsnStart'},\n"
"{name => 'strLsnStop'},\n"
"{name => '$strDbVersion'},\n"
+ "{name => '$iWalSegmentSize'},\n"
");\n"
"\n\n"
"my @stryArchive;\n"
@@ -177,11 +179,11 @@ static const EmbeddedModule embeddedModule[] =
"\n\n"
"my @stryArchiveSplit = split('/', $strLsnStart);\n"
"my $iStartMajor = hex($stryArchiveSplit[0]);\n"
- "my $iStartMinor = hex(substr(sprintf(\"%08s\", $stryArchiveSplit[1]), 0, 2));\n"
+ "my $iStartMinor = int(hex($stryArchiveSplit[1]) / $iWalSegmentSize);\n"
"\n"
"@stryArchiveSplit = split('/', $strLsnStop);\n"
"my $iStopMajor = hex($stryArchiveSplit[0]);\n"
- "my $iStopMinor = hex(substr(sprintf(\"%08s\", $stryArchiveSplit[1]), 0, 2));\n"
+ "my $iStopMinor = int(hex($stryArchiveSplit[1]) / $iWalSegmentSize);\n"
"\n"
"$stryArchive[$iArchiveIdx] = uc(sprintf(\"%08x%08x\", $iStartMajor, $iStartMinor));\n"
"$iArchiveIdx += 1;\n"
@@ -190,7 +192,7 @@ static const EmbeddedModule embeddedModule[] =
"{\n"
"$iStartMinor += 1;\n"
"\n"
- "if ($bSkipFF && $iStartMinor == 255 || !$bSkipFF && $iStartMinor == 256)\n"
+ "if ($bSkipFF && $iStartMinor == 255 || !$bSkipFF && $iStartMinor > int(0xFFFFFFFF / $iWalSegmentSize))\n"
"{\n"
"$iStartMajor += 1;\n"
"$iStartMinor = 0;\n"
@@ -2604,6 +2606,7 @@ static const EmbeddedModule embeddedModule[] =
"\n\n"
"my $strArchiveStart = undef;\n"
"my $strLsnStart = undef;\n"
+ "my $iWalSegmentSize = undef;\n"
"my $hTablespaceMap = undef;\n"
"my $hDatabaseMap = undef;\n"
"\n\n"
@@ -2634,7 +2637,7 @@ static const EmbeddedModule embeddedModule[] =
"else\n"
"{\n"
"\n"
- "($strArchiveStart, $strLsnStart) =\n"
+ "($strArchiveStart, $strLsnStart, $iWalSegmentSize) =\n"
"$oDbMaster->backupStart(\n"
"BACKREST_NAME . ' backup started at ' . timestampFormat(undef, $lTimestampStart), cfgOption(CFGOPT_START_FAST));\n"
"\n\n"
@@ -2777,7 +2780,7 @@ static const EmbeddedModule embeddedModule[] =
"\n"
"my $oArchiveInfo = new pgBackRest::Archive::Info(storageRepo()->pathGet(STORAGE_REPO_ARCHIVE), true);\n"
"my $strArchiveId = $oArchiveInfo->archiveId();\n"
- "my @stryArchive = lsnFileRange($strLsnStart, $strLsnStop, $strDbVersion);\n"
+ "my @stryArchive = lsnFileRange($strLsnStart, $strLsnStop, $strDbVersion, $iWalSegmentSize);\n"
"\n"
"foreach my $strArchive (@stryArchive)\n"
"{\n"
@@ -9333,8 +9336,13 @@ static const EmbeddedModule embeddedModule[] =
"\"exclusive pg_start_backup() with label \\\"${strLabel}\\\": backup begins after \" .\n"
"($bStartFast ? \"the requested immediate checkpoint\" : \"the next regular checkpoint\") . \" completes\");\n"
"\n"
- "my ($strTimestampDbStart, $strArchiveStart, $strLsnStart) = $self->executeSqlRow(\n"
- "\"select to_char(current_timestamp, 'YYYY-MM-DD HH24:MI:SS.US TZ'), pg_\" . $self->walId() . \"file_name(lsn), lsn::text\" .\n"
+ "my ($strTimestampDbStart, $strArchiveStart, $strLsnStart, $iWalSegmentSize) = $self->executeSqlRow(\n"
+ "\"select to_char(current_timestamp, 'YYYY-MM-DD HH24:MI:SS.US TZ'), pg_\" . $self->walId() . \"file_name(lsn), lsn::text,\" .\n"
+ "($self->{strDbVersion} < PG_VERSION_84 ? PG_WAL_SIZE :\n"
+ "\" (select setting::int8 from pg_settings where name = 'wal_segment_size')\" .\n"
+ "\n"
+ "($self->{strDbVersion} < PG_VERSION_11 ?\n"
+ "\" * (select setting::int8 from pg_settings where name = 'wal_block_size')\" : '')) .\n"
"\" from pg_start_backup('${strLabel}'\" .\n"
"($bStartFast ? ', true' : $self->{strDbVersion} >= PG_VERSION_84 ? ', false' : '') .\n"
"($self->{strDbVersion} >= PG_VERSION_96 ? ', false' : '') . ') as lsn');\n"
@@ -9344,6 +9352,7 @@ static const EmbeddedModule embeddedModule[] =
"$strOperation,\n"
"{name => 'strArchiveStart', value => $strArchiveStart},\n"
"{name => 'strLsnStart', value => $strLsnStart},\n"
+ "{name => 'iWalSegmentSize', value => $iWalSegmentSize},\n"
"{name => 'strTimestampDbStart', value => $strTimestampDbStart}\n"
");\n"
"}\n"
diff --git a/src/postgres/info.c b/src/postgres/info.c
deleted file mode 100644
index e0e289018..000000000
--- a/src/postgres/info.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/***********************************************************************************************************************************
-PostgreSQL Info
-***********************************************************************************************************************************/
-#include "common/debug.h"
-#include "common/log.h"
-#include "common/memContext.h"
-#include "common/type/convert.h"
-#include "common/regExp.h"
-#include "postgres/info.h"
-#include "postgres/type.h"
-#include "postgres/version.h"
-#include "storage/helper.h"
-
-/***********************************************************************************************************************************
-Set control data size. The control file is actually 8192 bytes but only the first 512 bytes are used to prevent torn pages even on
-really old storage with 512-byte sectors.
-***********************************************************************************************************************************/
-#define PG_CONTROL_DATA_SIZE 512
-
-/***********************************************************************************************************************************
-Map control/catalog version to PostgreSQL version
-***********************************************************************************************************************************/
-static unsigned int
-pgVersionMap(uint32_t controlVersion, uint32_t catalogVersion)
-{
- FUNCTION_TEST_BEGIN();
- FUNCTION_TEST_PARAM(UINT32, controlVersion);
- FUNCTION_TEST_PARAM(UINT32, catalogVersion);
- FUNCTION_TEST_END();
-
- unsigned int result = 0;
-
- if (controlVersion == 1100 && catalogVersion == 201809051)
- result = PG_VERSION_11;
- else if (controlVersion == 1002 && catalogVersion == 201707211)
- result = PG_VERSION_10;
- else if (controlVersion == 960 && catalogVersion == 201608131)
- result = PG_VERSION_96;
- else if (controlVersion == 942 && catalogVersion == 201510051)
- result = PG_VERSION_95;
- else if (controlVersion == 942 && catalogVersion == 201409291)
- result = PG_VERSION_94;
- else if (controlVersion == 937 && catalogVersion == 201306121)
- result = PG_VERSION_93;
- else if (controlVersion == 922 && catalogVersion == 201204301)
- result = PG_VERSION_92;
- else if (controlVersion == 903 && catalogVersion == 201105231)
- result = PG_VERSION_91;
- else if (controlVersion == 903 && catalogVersion == 201008051)
- result = PG_VERSION_90;
- else if (controlVersion == 843 && catalogVersion == 200904091)
- result = PG_VERSION_84;
- else if (controlVersion == 833 && catalogVersion == 200711281)
- result = PG_VERSION_83;
- else
- {
- THROW_FMT(
- VersionNotSupportedError,
- "unexpected control version = %u and catalog version = %u\n"
- "HINT: is this version of PostgreSQL supported?",
- controlVersion, catalogVersion);
- }
-
- FUNCTION_TEST_RESULT(UINT, result);
-}
-
-/***********************************************************************************************************************************
-Convert version string to version number
-***********************************************************************************************************************************/
-unsigned int
-pgVersionFromStr(const String *version)
-{
- FUNCTION_DEBUG_BEGIN(logLevelTrace);
- FUNCTION_DEBUG_PARAM(STRING, version);
-
- FUNCTION_DEBUG_ASSERT(version != NULL);
- FUNCTION_DEBUG_END();
-
- unsigned int result = 0;
-
- MEM_CONTEXT_TEMP_BEGIN()
- {
- // If format is not number.number (9.4) or number only (10) then error
- if (!regExpMatchOne(strNew("^[0-9]+[.]*[0-9]+$"), version))
- THROW_FMT(AssertError, "version %s format is invalid", strPtr(version));
-
- // If there is a dot set the major and minor versions, else just the major
- int idxStart = strChr(version, '.');
- unsigned int major;
- unsigned int minor = 0;
-
- if (idxStart != -1)
- {
- major = cvtZToUInt(strPtr(strSubN(version, 0, (size_t)idxStart)));
- minor = cvtZToUInt(strPtr(strSub(version, (size_t)idxStart + 1)));
- }
- else
- major = cvtZToUInt(strPtr(version));
-
- // No check to see if valid/supported PG version is on purpose
- result = major * 10000 + minor * 100;
- }
- MEM_CONTEXT_TEMP_END();
-
- FUNCTION_DEBUG_RESULT(UINT, result);
-}
-
-/***********************************************************************************************************************************
-Convert version number to string
-***********************************************************************************************************************************/
-String *
-pgVersionToStr(unsigned int version)
-{
- FUNCTION_DEBUG_BEGIN(logLevelTrace);
- FUNCTION_DEBUG_PARAM(UINT, version);
- FUNCTION_DEBUG_END();
-
- String *result = version >= PG_VERSION_10 ?
- strNewFmt("%u", version / 10000) : strNewFmt("%u.%u", version / 10000, version % 10000 / 100);
-
- FUNCTION_DEBUG_RESULT(STRING, result);
-}
-
-/***********************************************************************************************************************************
-Get info from pg_control
-***********************************************************************************************************************************/
-PgControlInfo
-pgControlInfo(const String *pgPath)
-{
- FUNCTION_DEBUG_BEGIN(logLevelDebug);
- FUNCTION_DEBUG_PARAM(STRING, pgPath);
-
- FUNCTION_TEST_ASSERT(pgPath != NULL);
- FUNCTION_DEBUG_END();
-
- PgControlInfo result = {0};
-
- MEM_CONTEXT_TEMP_BEGIN()
- {
- // Read control file
- PgControlFile *control = (PgControlFile *)bufPtr(
- storageGetP(
- storageNewReadNP(storageLocal(), strNewFmt("%s/" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL, strPtr(pgPath))),
- .exactSize = PG_CONTROL_DATA_SIZE));
-
- // Get PostgreSQL version
- result.systemId = control->systemId;
- result.controlVersion = control->controlVersion;
- result.catalogVersion = control->catalogVersion;
- result.version = pgVersionMap(result.controlVersion, result.catalogVersion);
- }
- MEM_CONTEXT_TEMP_END();
-
- FUNCTION_DEBUG_RESULT(PG_CONTROL_INFO, result);
-}
diff --git a/src/postgres/interface.c b/src/postgres/interface.c
new file mode 100644
index 000000000..3a6d9ffc6
--- /dev/null
+++ b/src/postgres/interface.c
@@ -0,0 +1,365 @@
+/***********************************************************************************************************************************
+PostgreSQL Interface
+***********************************************************************************************************************************/
+#include