1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-04-17 11:46:39 +02:00

Remove support for PostgreSQL 8.3/8.4.

There is no evidence that users need 8.3/8.4 anymore but it does cost us in terms of development and testing, especially now that we have a number of new backup/restore features planned.

It seems to make sense to remove this support now. If there are users who need to use/migrate from these versions they can use an older version of pgBackRest.
This commit is contained in:
David Steele 2022-01-06 15:34:04 -05:00 committed by GitHub
parent ef62ef2379
commit bb4b30ddd3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 288 additions and 988 deletions

View File

@ -86,9 +86,9 @@ pgBackRest repositories can be located in S3, Azure, and GCS compatible object s
pgBackRest can encrypt the repository to secure backups wherever they are stored.
### Compatibility with PostgreSQL >= 8.3
### Compatibility with PostgreSQL >= 9.0
pgBackRest includes support for versions down to 8.3, since older versions of PostgreSQL are still regularly utilized.
pgBackRest includes support for versions down to 9.0, since older versions of PostgreSQL are still regularly utilized.
## Getting Started

View File

@ -144,9 +144,9 @@
</section>
<section id="postgres-compatibility">
<title>Compatibility with <postgres/> >= 8.3</title>
<title>Compatibility with <postgres/> >= 9.0</title>
<p><backrest/> includes support for versions down to 8.3, since older versions of PostgreSQL are still regularly utilized.</p>
<p><backrest/> includes support for versions down to 9.0, since older versions of PostgreSQL are still regularly utilized.</p>
</section>
</section>

View File

@ -15,6 +15,22 @@
<release-list>
<release date="XXXX-XX-XX" version="2.38dev" title="UNDER DEVELOPMENT">
<release-core-list>
<release-improvement-list>
<release-item>
<github-pull-request id="1611"/>
<release-item-contributor-list>
<release-item-contributor id="david.steele"/>
<release-item-reviewer id="reid.thompson"/>
<release-item-reviewer id="stefan.fercot"/>
</release-item-contributor-list>
<p>Remove support for <proper>PostgreSQL</proper> <id>8.3</id>/<id>8.4</id>.</p>
</release-item>
</release-improvement-list>
</release-core-list>
<release-doc-list>
<release-improvement-list>
<release-item>

View File

@ -1174,8 +1174,6 @@
<text>
<p>Forces a checkpoint (by passing <id>y</id> to the <id>fast</id> parameter of <code>pg_start_backup()</code>) so the backup begins immediately. Otherwise the backup will start after the next regular checkpoint.</p>
<p>This feature only works in <postgres/> &gt;= <id>8.4</id>.</p>
</text>
<example>y</example>

View File

@ -242,13 +242,6 @@ backupInit(const InfoBackup *infoBackup)
cfgOptionSet(cfgOptStopAuto, cfgSourceParam, BOOL_FALSE_VAR);
}
// Only allow start-fast option for PostgreSQL >= 8.4
if (cfgOptionBool(cfgOptStartFast) && result->version < PG_VERSION_84)
{
LOG_WARN(CFGOPT_START_FAST " option is only available in " PG_NAME " >= " PG_VERSION_84_STR);
cfgOptionSet(cfgOptStartFast, cfgSourceParam, BOOL_FALSE_VAR);
}
// If checksum page is not explicitly set then automatically enable it when checksums are available
if (!cfgOptionTest(cfgOptChecksumPage))
{

View File

@ -1060,12 +1060,8 @@ restoreCleanBuild(Manifest *manifest)
const String *tablespaceId = pgTablespaceId(
manifestData(manifest)->pgVersion, manifestData(manifest)->pgCatalogVersion);
// Only PostgreSQL >= 9.0 has tablespace indentifiers
if (tablespaceId != NULL)
{
cleanData->targetName = strNewFmt("%s/%s", strZ(cleanData->targetName), strZ(tablespaceId));
cleanData->targetPath = strNewFmt("%s/%s", strZ(cleanData->targetPath), strZ(tablespaceId));
}
cleanData->targetName = strNewFmt("%s/%s", strZ(cleanData->targetName), strZ(tablespaceId));
cleanData->targetPath = strNewFmt("%s/%s", strZ(cleanData->targetPath), strZ(tablespaceId));
}
strLstSort(cleanData->fileIgnore, sortOrderAsc);
@ -1304,17 +1300,10 @@ restoreSelectiveExpression(Manifest *manifest)
RegExp *baseRegExp = regExpNew(STRDEF("^" MANIFEST_TARGET_PGDATA "/" PG_PATH_BASE "/[0-9]+/" PG_FILE_PGVERSION));
// Generate tablespace expression
RegExp *tablespaceRegExp = NULL;
const String *tablespaceId = pgTablespaceId(
manifestData(manifest)->pgVersion, manifestData(manifest)->pgCatalogVersion);
if (tablespaceId == NULL)
tablespaceRegExp = regExpNew(STRDEF("^" MANIFEST_TARGET_PGTBLSPC "/[0-9]+/[0-9]+/" PG_FILE_PGVERSION));
else
{
tablespaceRegExp = regExpNew(
RegExp *tablespaceRegExp = regExpNew(
strNewFmt("^" MANIFEST_TARGET_PGTBLSPC "/[0-9]+/%s/[0-9]+/" PG_FILE_PGVERSION, strZ(tablespaceId)));
}
// Generate a list of databases in base or in a tablespace and get all standard system databases, even in cases where
// users have recreated them
@ -1458,12 +1447,7 @@ restoreSelectiveExpression(Manifest *manifest)
const ManifestTarget *target = manifestTarget(manifest, targetIdx);
if (target->tablespaceId != 0)
{
if (tablespaceId == NULL)
strCatFmt(expression, "|(^%s/%s/)", strZ(target->name), strZ(db));
else
strCatFmt(expression, "|(^%s/%s/%s/)", strZ(target->name), strZ(tablespaceId), strZ(db));
}
strCatFmt(expression, "|(^%s/%s/%s/)", strZ(target->name), strZ(tablespaceId), strZ(db));
}
}
}

View File

@ -291,8 +291,7 @@ dbOpen(Db *this)
MEM_CONTEXT_END();
// Set application name to help identify the backup session
if (dbPgVersion(this) >= PG_VERSION_APPLICATION_NAME)
dbExec(this, strNewFmt("set application_name = '%s'", strZ(this->applicationName)));
dbExec(this, strNewFmt("set application_name = '%s'", strZ(this->applicationName)));
// There is no need to have parallelism enabled in a backup session. In particular, 9.6 marks pg_stop_backup() as
// parallel-safe but an error will be thrown if pg_stop_backup() is run in a worker.
@ -334,7 +333,7 @@ dbBackupStartQuery(unsigned int pgVersion, bool startFast)
strCatFmt(result, ", " TRUE_Z);
}
// Else start backup at the next scheduled checkpoint
else if (pgVersion >= PG_VERSION_84)
else
strCatFmt(result, ", " FALSE_Z);
// Use non-exclusive backup mode when available
@ -729,27 +728,21 @@ dbPing(Db *const this, const bool force)
if (force || timeNow - this->pingTimeLast > DB_PING_SEC)
{
// Make sure recovery state has not changed for versions that support recovery
if (dbPgVersion(this) >= PG_VERSION_90)
// Make sure recovery state has not changed
if (dbIsInRecovery(this) != dbIsStandby(this))
{
if (dbIsInRecovery(this) != dbIsStandby(this))
// If this is the standby then it must have been promoted
if (dbIsStandby(this))
{
// If this is the standby then it must have been promoted
if (dbIsStandby(this))
{
THROW(
DbMismatchError,
"standby is no longer in recovery\n"
"HINT: was the standby promoted during the backup?");
}
// Else if a primary then something has gone seriously wrong
else
THROW(AssertError, "primary has switched to recovery");
THROW(
DbMismatchError,
"standby is no longer in recovery\n"
"HINT: was the standby promoted during the backup?");
}
// Else if a primary then something has gone seriously wrong
else
THROW(AssertError, "primary has switched to recovery");
}
// Else just make sure the cluster is still running
else
dbTimeMSec(this);
this->pingTimeLast = timeNow;
}

View File

@ -700,7 +700,7 @@ manifestBuildCallback(void *data, const StorageInfo *info)
}
// Skip pg_notify/* since these files cannot be reused on recovery
if (strEqZ(info->name, PG_PATH_PGNOTIFY) && pgVersion >= PG_VERSION_90)
if (strEqZ(info->name, PG_PATH_PGNOTIFY))
{
FUNCTION_TEST_RETURN_VOID();
return;
@ -729,7 +729,7 @@ manifestBuildCallback(void *data, const StorageInfo *info)
// Skip temporary statistics in pg_stat_tmp even when stats_temp_directory is set because PGSS_TEXT_FILE is always
// created there
if (strEqZ(info->name, PG_PATH_PGSTATTMP) && pgVersion >= PG_VERSION_84)
if (strEqZ(info->name, PG_PATH_PGSTATTMP))
{
FUNCTION_TEST_RETURN_VOID();
return;
@ -755,9 +755,7 @@ manifestBuildCallback(void *data, const StorageInfo *info)
ManifestBuildData buildDataSub = buildData;
buildDataSub.manifestParentName = manifestName;
buildDataSub.pgPath = strNewFmt("%s/%s", strZ(buildData.pgPath), strZ(info->name));
if (buildData.dbPathExp != NULL)
buildDataSub.dbPath = regExpMatch(buildData.dbPathExp, manifestName);
buildDataSub.dbPath = regExpMatch(buildData.dbPathExp, manifestName);
storageInfoListP(
buildDataSub.storagePg, buildDataSub.pgPath, manifestBuildCallback, &buildDataSub, .sortOrder = sortOrderAsc);
@ -781,7 +779,7 @@ manifestBuildCallback(void *data, const StorageInfo *info)
// the creating process id as the extension can exist so skip that as well. This seems to be a bug in PostgreSQL since
// the temp file should be removed on startup. Use regExpMatchOne() here instead of preparing a regexp in advance since
// the likelihood of needing the regexp should be very small.
if ((pgVersion <= PG_VERSION_84 || buildData.dbPath) && strBeginsWithZ(info->name, PG_FILE_PGINTERNALINIT) &&
if (buildData.dbPath && strBeginsWithZ(info->name, PG_FILE_PGINTERNALINIT) &&
(strSize(info->name) == sizeof(PG_FILE_PGINTERNALINIT) - 1 ||
regExpMatchOne(STRDEF("\\.[0-9]+"), strSub(info->name, sizeof(PG_FILE_PGINTERNALINIT) - 1))))
{
@ -953,32 +951,27 @@ manifestBuildCallback(void *data, const StorageInfo *info)
manifestPathAdd(buildData.manifest, &path);
}
// If the tablespace id is present then the tablespace link destination path is not the path where data will be
// stored so we can just store it as a dummy path.
if (buildData.tablespaceId != NULL)
// The tablespace link destination path is not the path where data will be stored so we can just store it as a dummy
// path. This is because PostgreSQL creates a subpath with the version/catalog number so that multiple versions of
// PostgreSQL can share a tablespace, which makes upgrades easier.
const ManifestPath *pathTblSpc = manifestPathFind(
buildData.manifest, STRDEF(MANIFEST_TARGET_PGDATA "/" MANIFEST_TARGET_PGTBLSPC));
ManifestPath path =
{
const ManifestPath *pathTblSpc = manifestPathFind(
buildData.manifest, STRDEF(MANIFEST_TARGET_PGDATA "/" MANIFEST_TARGET_PGTBLSPC));
.name = manifestName,
.mode = pathTblSpc->mode,
.user = pathTblSpc->user,
.group = pathTblSpc->group,
};
ManifestPath path =
{
.name = manifestName,
.mode = pathTblSpc->mode,
.user = pathTblSpc->user,
.group = pathTblSpc->group,
};
manifestPathAdd(buildData.manifest, &path);
manifestPathAdd(buildData.manifest, &path);
// Update build structure to reflect the path added above and the tablespace id
buildData.manifestParentName = manifestName;
manifestName = strNewFmt("%s/%s", strZ(manifestName), strZ(buildData.tablespaceId));
buildData.pgPath = strNewFmt("%s/%s", strZ(buildData.pgPath), strZ(info->name));
linkName = buildData.tablespaceId;
}
// If no tablespace id then parent manifest name is the tablespace directory
else
buildData.manifestParentName = MANIFEST_TARGET_PGTBLSPC_STR;
// Update build structure to reflect the path added above and the tablespace id
buildData.manifestParentName = manifestName;
manifestName = strNewFmt("%s/%s", strZ(manifestName), strZ(buildData.tablespaceId));
buildData.pgPath = strNewFmt("%s/%s", strZ(buildData.pgPath), strZ(info->name));
linkName = buildData.tablespaceId;
}
// Add info about the linked file/path
@ -1092,19 +1085,15 @@ manifestNewBuild(
.pgPath = storagePathP(storagePg, NULL),
};
// We won't identify db paths for PostgreSQL < 9.0. This means that temp relations will not be excluded but it doesn't
// seem worth supporting this feature on such old versions of PostgreSQL.
// Build expressions to identify databases paths and temp relations
// ---------------------------------------------------------------------------------------------------------------------
if (pgVersion >= PG_VERSION_90)
{
ASSERT(buildData.tablespaceId != NULL);
ASSERT(buildData.tablespaceId != NULL);
// Expression to identify database paths
buildData.dbPathExp = regExpNew(strNewFmt("^" DB_PATH_EXP "$", strZ(buildData.tablespaceId)));
// Expression to identify database paths
buildData.dbPathExp = regExpNew(strNewFmt("^" DB_PATH_EXP "$", strZ(buildData.tablespaceId)));
// Expression to find temp relations
buildData.tempRelationExp = regExpNew(STRDEF("^t[0-9]+_" RELATION_EXP "$"));
}
// Expression to find temp relations
buildData.tempRelationExp = regExpNew(STRDEF("^t[0-9]+_" RELATION_EXP "$"));
// Build expression to identify files that can be copied from the standby when standby backup is supported
// ---------------------------------------------------------------------------------------------------------------------

View File

@ -198,26 +198,6 @@ static const PgInterface pgInterface[] =
.walIs = pgInterfaceWalIs090,
.wal = pgInterfaceWal090,
},
{
.version = PG_VERSION_84,
.controlIs = pgInterfaceControlIs084,
.control = pgInterfaceControl084,
.controlVersion = pgInterfaceControlVersion084,
.walIs = pgInterfaceWalIs084,
.wal = pgInterfaceWal084,
},
{
.version = PG_VERSION_83,
.controlIs = pgInterfaceControlIs083,
.control = pgInterfaceControl083,
.controlVersion = pgInterfaceControlVersion083,
.walIs = pgInterfaceWalIs083,
.wal = pgInterfaceWal083,
},
};
// Total PostgreSQL versions in pgInterface
@ -458,20 +438,17 @@ pgTablespaceId(unsigned int pgVersion, unsigned int pgCatalogVersion)
String *result = NULL;
if (pgVersion >= PG_VERSION_90)
MEM_CONTEXT_TEMP_BEGIN()
{
MEM_CONTEXT_TEMP_BEGIN()
{
String *pgVersionStr = pgVersionToStr(pgVersion);
String *pgVersionStr = pgVersionToStr(pgVersion);
MEM_CONTEXT_PRIOR_BEGIN()
{
result = strNewFmt("PG_%s_%u", strZ(pgVersionStr), pgCatalogVersion);
}
MEM_CONTEXT_PRIOR_END();
MEM_CONTEXT_PRIOR_BEGIN()
{
result = strNewFmt("PG_%s_%u", strZ(pgVersionStr), pgCatalogVersion);
}
MEM_CONTEXT_TEMP_END();
MEM_CONTEXT_PRIOR_END();
}
MEM_CONTEXT_TEMP_END();
FUNCTION_TEST_RETURN(result);
}

View File

@ -1,12 +0,0 @@
/***********************************************************************************************************************************
PostgreSQL 8.3 Interface
See postgres/interface/version.intern.h for documentation.
***********************************************************************************************************************************/
#include "build.auto.h"
#define PG_VERSION PG_VERSION_83
#include "postgres/interface/version.intern.h"
PG_INTERFACE(083);

View File

@ -1,12 +0,0 @@
/***********************************************************************************************************************************
PostgreSQL 8.4 Interface
See postgres/interface/version.intern.h for documentation.
***********************************************************************************************************************************/
#include "build.auto.h"
#define PG_VERSION PG_VERSION_84
#include "postgres/interface/version.intern.h"
PG_INTERFACE(084);

View File

@ -9,18 +9,6 @@ PostgreSQL Version Interface
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
bool pgInterfaceControlIs083(const unsigned char *controlFile);
PgControl pgInterfaceControl083(const unsigned char *controlFile);
uint32_t pgInterfaceControlVersion083(void);
bool pgInterfaceWalIs083(const unsigned char *walFile);
PgWal pgInterfaceWal083(const unsigned char *controlFile);
bool pgInterfaceControlIs084(const unsigned char *controlFile);
PgControl pgInterfaceControl084(const unsigned char *controlFile);
uint32_t pgInterfaceControlVersion084(void);
bool pgInterfaceWalIs084(const unsigned char *walFile);
PgWal pgInterfaceWal084(const unsigned char *controlFile);
bool pgInterfaceControlIs090(const unsigned char *controlFile);
PgControl pgInterfaceControl090(const unsigned char *controlFile);
uint32_t pgInterfaceControlVersion090(void);

View File

@ -22,7 +22,7 @@ Determine if the supplied pg_control is for this version of PostgreSQL
***********************************************************************************************************************************/
#if PG_VERSION > PG_VERSION_MAX
#elif PG_VERSION >= PG_VERSION_83
#elif PG_VERSION >= PG_VERSION_90
#ifdef CATALOG_VERSION_NO_MAX
@ -81,7 +81,7 @@ Read the version specific pg_control into a general data structure
}; \
}
#elif PG_VERSION >= PG_VERSION_83
#elif PG_VERSION >= PG_VERSION_90
#define PG_INTERFACE_CONTROL(version) \
PgControl \
@ -110,7 +110,7 @@ Get the control version
***********************************************************************************************************************************/
#if PG_VERSION > PG_VERSION_MAX
#elif PG_VERSION >= PG_VERSION_83
#elif PG_VERSION >= PG_VERSION_90
#define PG_INTERFACE_CONTROL_VERSION(version) \
uint32_t \
@ -126,7 +126,7 @@ Determine if the supplied WAL is for this version of PostgreSQL
***********************************************************************************************************************************/
#if PG_VERSION > PG_VERSION_MAX
#elif PG_VERSION >= PG_VERSION_83
#elif PG_VERSION >= PG_VERSION_90
#define PG_INTERFACE_WAL_IS(version) \
bool \
@ -144,7 +144,7 @@ Read the version specific WAL header into a general data structure
***********************************************************************************************************************************/
#if PG_VERSION > PG_VERSION_MAX
#elif PG_VERSION >= PG_VERSION_83
#elif PG_VERSION >= PG_VERSION_90
#define PG_INTERFACE_WAL(version) \
PgWal \

View File

@ -31,7 +31,7 @@ Types from src/include/c.h
// ---------------------------------------------------------------------------------------------------------------------------------
#if PG_VERSION > PG_VERSION_MAX
#elif PG_VERSION >= PG_VERSION_83
#elif PG_VERSION >= PG_VERSION_90
typedef int64_t int64;
@ -41,7 +41,7 @@ typedef int64_t int64;
// ---------------------------------------------------------------------------------------------------------------------------------
#if PG_VERSION > PG_VERSION_MAX
#elif PG_VERSION >= PG_VERSION_83
#elif PG_VERSION >= PG_VERSION_90
/* MultiXactId must be equivalent to TransactionId, to fit in t_xmax */
typedef TransactionId MultiXactId;
@ -52,7 +52,7 @@ typedef TransactionId MultiXactId;
// ---------------------------------------------------------------------------------------------------------------------------------
#if PG_VERSION > PG_VERSION_MAX
#elif PG_VERSION >= PG_VERSION_83
#elif PG_VERSION >= PG_VERSION_90
typedef uint32 MultiXactOffset;
@ -66,7 +66,7 @@ Types from src/include/pgtime.h
// ---------------------------------------------------------------------------------------------------------------------------------
#if PG_VERSION > PG_VERSION_MAX
#elif PG_VERSION >= PG_VERSION_84
#elif PG_VERSION >= PG_VERSION_90
/*
* The API of this library is generally similar to the corresponding
@ -85,7 +85,7 @@ Types from src/include/postgres_ext.h
// ---------------------------------------------------------------------------------------------------------------------------------
#if PG_VERSION > PG_VERSION_MAX
#elif PG_VERSION >= PG_VERSION_83
#elif PG_VERSION >= PG_VERSION_90
/*
* Object ID is a fundamental type in Postgres.
@ -106,7 +106,7 @@ Types from src/include/port/pg_crc32.h
typedef uint32 pg_crc32c;
#elif PG_VERSION >= PG_VERSION_83
#elif PG_VERSION >= PG_VERSION_90
typedef uint32 pg_crc32;
@ -128,7 +128,7 @@ Types from src/include/access/xlogdefs.h
*/
typedef uint64 XLogRecPtr;
#elif PG_VERSION >= PG_VERSION_83
#elif PG_VERSION >= PG_VERSION_90
/*
* Pointer to a location in the XLOG. These pointers are 64 bits wide,
@ -157,7 +157,7 @@ typedef struct XLogRecPtr
// ---------------------------------------------------------------------------------------------------------------------------------
#if PG_VERSION > PG_VERSION_MAX
#elif PG_VERSION >= PG_VERSION_83
#elif PG_VERSION >= PG_VERSION_90
/*
* TimeLineID (TLI) - identifies different database histories to prevent
@ -342,33 +342,6 @@ Types from src/include/catalog/catversion.h
/* yyyymmddN */
#define CATALOG_VERSION_NO 201008051
#elif PG_VERSION >= PG_VERSION_84
/*
* We could use anything we wanted for version numbers, but I recommend
* following the "YYYYMMDDN" style often used for DNS zone serial numbers.
* YYYYMMDD are the date of the change, and N is the number of the change
* on that day. (Hopefully we'll never commit ten independent sets of
* catalog changes on the same day...)
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200904091
#elif PG_VERSION >= PG_VERSION_83
/*
* We could use anything we wanted for version numbers, but I recommend
* following the "YYYYMMDDN" style often used for DNS zone serial numbers.
* YYYYMMDD are the date of the change, and N is the number of the change
* on that day. (Hopefully we'll never commit ten independent sets of
* catalog changes on the same day...)
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200711281
#endif
/***********************************************************************************************************************************
@ -446,16 +419,6 @@ Types from src/include/catalog/pg_control.h
/* Version identifier for this pg_control format */
#define PG_CONTROL_VERSION 903
#elif PG_VERSION >= PG_VERSION_84
/* Version identifier for this pg_control format */
#define PG_CONTROL_VERSION 843
#elif PG_VERSION >= PG_VERSION_83
/* Version identifier for this pg_control format */
#define PG_CONTROL_VERSION 833
#endif
// MOCK_AUTH_NONCE_LEN define
@ -723,44 +686,6 @@ typedef struct CheckPoint
TransactionId oldestActiveXid;
} CheckPoint;
#elif PG_VERSION >= PG_VERSION_84
/*
* Body of CheckPoint XLOG records. This is declared here because we keep
* a copy of the latest one in pg_control for possible disaster recovery.
*/
typedef struct CheckPoint
{
XLogRecPtr redo; /* next RecPtr available when we began to
* create CheckPoint (i.e. REDO start point) */
TimeLineID ThisTimeLineID; /* current TLI */
uint32 nextXidEpoch; /* higher-order bits of nextXid */
TransactionId nextXid; /* next free XID */
Oid nextOid; /* next free OID */
MultiXactId nextMulti; /* next free MultiXactId */
MultiXactOffset nextMultiOffset; /* next free MultiXact offset */
pg_time_t time; /* time stamp of checkpoint */
} CheckPoint;
#elif PG_VERSION >= PG_VERSION_83
/*
* Body of CheckPoint XLOG records. This is declared here because we keep
* a copy of the latest one in pg_control for possible disaster recovery.
*/
typedef struct CheckPoint
{
XLogRecPtr redo; /* next RecPtr available when we began to
* create CheckPoint (i.e. REDO start point) */
TimeLineID ThisTimeLineID; /* current TLI */
uint32 nextXidEpoch; /* higher-order bits of nextXid */
TransactionId nextXid; /* next free XID */
Oid nextOid; /* next free OID */
MultiXactId nextMulti; /* next free MultiXactId */
MultiXactOffset nextMultiOffset; /* next free MultiXact offset */
time_t time; /* time stamp of checkpoint */
} CheckPoint;
#endif
// DBState enum
@ -784,7 +709,7 @@ typedef enum DBState
DB_IN_PRODUCTION
} DBState;
#elif PG_VERSION >= PG_VERSION_83
#elif PG_VERSION >= PG_VERSION_90
/* System status indicator */
typedef enum DBState
@ -799,18 +724,6 @@ typedef enum DBState
#endif
// LOCALE_NAME_BUFLEN define
// ---------------------------------------------------------------------------------------------------------------------------------
#if PG_VERSION > PG_VERSION_MAX
#elif PG_VERSION >= PG_VERSION_84
#elif PG_VERSION >= PG_VERSION_83
#define LOCALE_NAME_BUFLEN 128
#endif
// ControlFileData type
// ---------------------------------------------------------------------------------------------------------------------------------
#if PG_VERSION > PG_VERSION_MAX
@ -2033,183 +1946,6 @@ typedef struct ControlFileData
pg_crc32 crc;
} ControlFileData;
#elif PG_VERSION >= PG_VERSION_84
/*
* Contents of pg_control.
*
* NOTE: try to keep this under 512 bytes so that it will fit on one physical
* sector of typical disk drives. This reduces the odds of corruption due to
* power failure midway through a write.
*/
typedef struct ControlFileData
{
/*
* Unique system identifier --- to ensure we match up xlog files with the
* installation that produced them.
*/
uint64 system_identifier;
/*
* Version identifier information. Keep these fields at the same offset,
* especially pg_control_version; they won't be real useful if they move
* around. (For historical reasons they must be 8 bytes into the file
* rather than immediately at the front.)
*
* pg_control_version identifies the format of pg_control itself.
* catalog_version_no identifies the format of the system catalogs.
*
* There are additional version identifiers in individual files; for
* example, WAL logs contain per-page magic numbers that can serve as
* version cues for the WAL log.
*/
uint32 pg_control_version; /* PG_CONTROL_VERSION */
uint32 catalog_version_no; /* see catversion.h */
/*
* System status data
*/
DBState state; /* see enum above */
pg_time_t time; /* time stamp of last pg_control update */
XLogRecPtr checkPoint; /* last check point record ptr */
XLogRecPtr prevCheckPoint; /* previous check point record ptr */
CheckPoint checkPointCopy; /* copy of last check point record */
XLogRecPtr minRecoveryPoint; /* must replay xlog to here */
/*
* This data is used to check for hardware-architecture compatibility of
* the database and the backend executable. We need not check endianness
* explicitly, since the pg_control version will surely look wrong to a
* machine of different endianness, but we do need to worry about MAXALIGN
* and floating-point format. (Note: storage layout nominally also
* depends on SHORTALIGN and INTALIGN, but in practice these are the same
* on all architectures of interest.)
*
* Testing just one double value is not a very bulletproof test for
* floating-point compatibility, but it will catch most cases.
*/
uint32 maxAlign; /* alignment requirement for tuples */
double floatFormat; /* constant 1234567.0 */
#define FLOATFORMAT_VALUE 1234567.0
/*
* This data is used to make sure that configuration of this database is
* compatible with the backend executable.
*/
uint32 blcksz; /* data block size for this DB */
uint32 relseg_size; /* blocks per segment of large relation */
uint32 xlog_blcksz; /* block size within WAL files */
uint32 xlog_seg_size; /* size of each WAL segment */
uint32 nameDataLen; /* catalog name field width */
uint32 indexMaxKeys; /* max number of columns in an index */
uint32 toast_max_chunk_size; /* chunk size in TOAST tables */
/* flag indicating internal format of timestamp, interval, time */
bool enableIntTimes; /* int64 storage enabled? */
/* flags indicating pass-by-value status of various types */
bool float4ByVal; /* float4 pass-by-value? */
bool float8ByVal; /* float8, int8, etc pass-by-value? */
/* CRC of all above ... MUST BE LAST! */
pg_crc32 crc;
} ControlFileData;
#elif PG_VERSION >= PG_VERSION_83
/*
* Contents of pg_control.
*
* NOTE: try to keep this under 512 bytes so that it will fit on one physical
* sector of typical disk drives. This reduces the odds of corruption due to
* power failure midway through a write. Currently it fits comfortably,
* but we could probably reduce LOCALE_NAME_BUFLEN if things get tight.
*/
typedef struct ControlFileData
{
/*
* Unique system identifier --- to ensure we match up xlog files with the
* installation that produced them.
*/
uint64 system_identifier;
/*
* Version identifier information. Keep these fields at the same offset,
* especially pg_control_version; they won't be real useful if they move
* around. (For historical reasons they must be 8 bytes into the file
* rather than immediately at the front.)
*
* pg_control_version identifies the format of pg_control itself.
* catalog_version_no identifies the format of the system catalogs.
*
* There are additional version identifiers in individual files; for
* example, WAL logs contain per-page magic numbers that can serve as
* version cues for the WAL log.
*/
uint32 pg_control_version; /* PG_CONTROL_VERSION */
uint32 catalog_version_no; /* see catversion.h */
/*
* System status data
*/
DBState state; /* see enum above */
time_t time; /* time stamp of last pg_control update */
XLogRecPtr checkPoint; /* last check point record ptr */
XLogRecPtr prevCheckPoint; /* previous check point record ptr */
CheckPoint checkPointCopy; /* copy of last check point record */
XLogRecPtr minRecoveryPoint; /* must replay xlog to here */
/*
* This data is used to check for hardware-architecture compatibility of
* the database and the backend executable. We need not check endianness
* explicitly, since the pg_control version will surely look wrong to a
* machine of different endianness, but we do need to worry about MAXALIGN
* and floating-point format. (Note: storage layout nominally also
* depends on SHORTALIGN and INTALIGN, but in practice these are the same
* on all architectures of interest.)
*
* Testing just one double value is not a very bulletproof test for
* floating-point compatibility, but it will catch most cases.
*/
uint32 maxAlign; /* alignment requirement for tuples */
double floatFormat; /* constant 1234567.0 */
#define FLOATFORMAT_VALUE 1234567.0
/*
* This data is used to make sure that configuration of this database is
* compatible with the backend executable.
*/
uint32 blcksz; /* data block size for this DB */
uint32 relseg_size; /* blocks per segment of large relation */
uint32 xlog_blcksz; /* block size within WAL files */
uint32 xlog_seg_size; /* size of each WAL segment */
uint32 nameDataLen; /* catalog name field width */
uint32 indexMaxKeys; /* max number of columns in an index */
uint32 toast_max_chunk_size; /* chunk size in TOAST tables */
/* flag indicating internal format of timestamp, interval, time */
uint32 enableIntTimes; /* int64 storage enabled? */
/* active locales */
uint32 localeBuflen;
char lc_collate[LOCALE_NAME_BUFLEN];
char lc_ctype[LOCALE_NAME_BUFLEN];
/* CRC of all above ... MUST BE LAST! */
pg_crc32 crc;
} ControlFileData;
#endif
/***********************************************************************************************************************************
@ -2268,14 +2004,6 @@ Types from src/include/access/xlog_internal.h
#define XLOG_PAGE_MAGIC 0xD064 /* can be used as WAL version indicator */
#elif PG_VERSION >= PG_VERSION_84
#define XLOG_PAGE_MAGIC 0xD063 /* can be used as WAL version indicator */
#elif PG_VERSION >= PG_VERSION_83
#define XLOG_PAGE_MAGIC 0xD062 /* can be used as WAL version indicator */
#endif
// XLogPageHeaderData type
@ -2327,7 +2055,7 @@ typedef struct XLogPageHeaderData
uint32 xlp_rem_len; /* total len of remaining data for record */
} XLogPageHeaderData;
#elif PG_VERSION >= PG_VERSION_83
#elif PG_VERSION >= PG_VERSION_90
/*
* Each page of XLOG file has a header like this:
@ -2346,7 +2074,7 @@ typedef struct XLogPageHeaderData
// ---------------------------------------------------------------------------------------------------------------------------------
#if PG_VERSION > PG_VERSION_MAX
#elif PG_VERSION >= PG_VERSION_83
#elif PG_VERSION >= PG_VERSION_90
/*
* When the XLP_LONG_HEADER flag is set, we store additional fields in the
@ -2367,7 +2095,7 @@ typedef struct XLogLongPageHeaderData
// ---------------------------------------------------------------------------------------------------------------------------------
#if PG_VERSION > PG_VERSION_MAX
#elif PG_VERSION >= PG_VERSION_83
#elif PG_VERSION >= PG_VERSION_90
/* This flag indicates a "long" page header */
#define XLP_LONG_HEADER 0x0002

View File

@ -12,8 +12,6 @@ PostgreSQL name
/***********************************************************************************************************************************
PostgreSQL version constants
***********************************************************************************************************************************/
#define PG_VERSION_83 80300
#define PG_VERSION_84 80400
#define PG_VERSION_90 90000
#define PG_VERSION_91 90100
#define PG_VERSION_92 90200
@ -32,9 +30,6 @@ PostgreSQL version constants
/***********************************************************************************************************************************
Version where various PostgreSQL capabilities were introduced
***********************************************************************************************************************************/
// application_name can be set to show the application name in pg_stat_activity
#define PG_VERSION_APPLICATION_NAME PG_VERSION_90
// pg_is_in_recovery() supported
#define PG_VERSION_HOT_STANDBY PG_VERSION_91
@ -65,8 +60,6 @@ Version where various PostgreSQL capabilities were introduced
/***********************************************************************************************************************************
PostgreSQL version string constants for use in error messages
***********************************************************************************************************************************/
#define PG_VERSION_83_STR "8.3"
#define PG_VERSION_84_STR "8.4"
#define PG_VERSION_90_STR "9.0"
#define PG_VERSION_91_STR "9.1"
#define PG_VERSION_92_STR "9.2"

View File

@ -1427,14 +1427,6 @@ src/postgres/interface/static.vendor.h:
class: core/vendor
type: c/h
src/postgres/interface/v083.c:
class: core
type: c
src/postgres/interface/v084.c:
class: core
type: c
src/postgres/interface/v090.c:
class: core
type: c
@ -2047,14 +2039,6 @@ test/src/common/harnessPostgres.h:
class: test/harness
type: c/h
test/src/common/harnessPostgres/harness083.c:
class: test/harness
type: c
test/src/common/harnessPostgres/harness084.c:
class: test/harness
type: c
test/src/common/harnessPostgres/harness090.c:
class: test/harness
type: c

View File

@ -396,8 +396,6 @@ unit:
- command/command
- postgres/interface
- postgres/interface/page
- postgres/interface/v083
- postgres/interface/v084
- postgres/interface/v090
- postgres/interface/v091
- postgres/interface/v092

View File

@ -15,10 +15,6 @@ use pgBackRestDoc::Common::Log;
####################################################################################################################################
# PostgreSQL version numbers
####################################################################################################################################
use constant PG_VERSION_83 => '8.3';
push @EXPORT, qw(PG_VERSION_83);
use constant PG_VERSION_84 => '8.4';
push @EXPORT, qw(PG_VERSION_84);
use constant PG_VERSION_90 => '9.0';
push @EXPORT, qw(PG_VERSION_90);
use constant PG_VERSION_91 => '9.1';
@ -44,8 +40,6 @@ use constant PG_VERSION_13 => '13';
use constant PG_VERSION_14 => '14';
push @EXPORT, qw(PG_VERSION_14);
use constant PG_VERSION_APPLICATION_NAME => PG_VERSION_90;
push @EXPORT, qw(PG_VERSION_APPLICATION_NAME);
use constant PG_VERSION_HOT_STANDBY => PG_VERSION_91;
push @EXPORT, qw(PG_VERSION_HOT_STANDBY);
use constant PG_VERSION_BACKUP_STANDBY => PG_VERSION_92;
@ -61,9 +55,8 @@ sub versionSupport
# Assign function parameters, defaults, and log debug info
my ($strOperation) = logDebugParam(__PACKAGE__ . '->versionSupport');
my @strySupportVersion = (PG_VERSION_83, PG_VERSION_84, PG_VERSION_90, PG_VERSION_91, PG_VERSION_92, PG_VERSION_93,
PG_VERSION_94, PG_VERSION_95, PG_VERSION_96, PG_VERSION_10, PG_VERSION_11, PG_VERSION_12,
PG_VERSION_13, PG_VERSION_14);
my @strySupportVersion = (PG_VERSION_90, PG_VERSION_91, PG_VERSION_92, PG_VERSION_93, PG_VERSION_94, PG_VERSION_95,
PG_VERSION_96, PG_VERSION_10, PG_VERSION_11, PG_VERSION_12, PG_VERSION_13, PG_VERSION_14);
# Return from function and log return values if any
return logDebugReturn

View File

@ -195,8 +195,6 @@ my $oyVm =
&VM_DB =>
[
PG_VERSION_83,
PG_VERSION_84,
PG_VERSION_90,
PG_VERSION_91,
PG_VERSION_92,
@ -204,8 +202,6 @@ my $oyVm =
&VM_DB_TEST =>
[
PG_VERSION_83,
PG_VERSION_84,
PG_VERSION_90,
],
},
@ -225,8 +221,6 @@ my $oyVm =
&VM_DB =>
[
PG_VERSION_83,
PG_VERSION_84,
PG_VERSION_90,
PG_VERSION_91,
PG_VERSION_92,

View File

@ -79,8 +79,6 @@ sub new
my $oPgControlVersionHash =
{
# iControlVersion => {iCatalogVersion => strDbVersion}
833 => {200711281 => PG_VERSION_83},
843 => {200904091 => PG_VERSION_84},
903 =>
{
201008051 => PG_VERSION_90,

View File

@ -99,8 +99,7 @@ sub dbFileCreate
# Get tablespace path if this is a tablespace
my $strPgPath;
if ($$oManifestRef{&MANIFEST_SECTION_BACKUP_DB}{&MANIFEST_KEY_DB_VERSION} >= PG_VERSION_90 &&
index($strTarget, DB_PATH_PGTBLSPC . '/') == 0)
if (index($strTarget, DB_PATH_PGTBLSPC . '/') == 0)
{
my $iCatalog = ${$oManifestRef}{&MANIFEST_SECTION_BACKUP_DB}{&MANIFEST_KEY_CATALOG};
@ -185,9 +184,8 @@ sub manifestDbPathGet
# Determine the manifest key
my $strDbPath = ${$oManifestRef}{&MANIFEST_SECTION_BACKUP_TARGET}{$strTarget}{&MANIFEST_SUBKEY_PATH};
# If target is a tablespace and pg version >= 9.0
if (defined(${$oManifestRef}{&MANIFEST_SECTION_BACKUP_TARGET}{$strTarget}{&MANIFEST_SUBKEY_TABLESPACE_ID}) &&
$$oManifestRef{&MANIFEST_SECTION_BACKUP_DB}{&MANIFEST_KEY_DB_VERSION} >= PG_VERSION_90)
# If target is a tablespace
if (defined(${$oManifestRef}{&MANIFEST_SECTION_BACKUP_TARGET}{$strTarget}{&MANIFEST_SUBKEY_TABLESPACE_ID}))
{
my $iCatalog = ${$oManifestRef}{&MANIFEST_SECTION_BACKUP_DB}{&MANIFEST_KEY_CATALOG};
@ -299,9 +297,8 @@ sub manifestKeyGet
# Determine the manifest key
my $strManifestKey = $strTarget;
# If target is a tablespace and pg version >= 9.0
if (defined(${$oManifestRef}{&MANIFEST_SECTION_BACKUP_TARGET}{$strTarget}{&MANIFEST_SUBKEY_TABLESPACE_ID}) &&
$$oManifestRef{&MANIFEST_SECTION_BACKUP_DB}{&MANIFEST_KEY_DB_VERSION} >= PG_VERSION_90)
# If target is a tablespace
if (defined(${$oManifestRef}{&MANIFEST_SECTION_BACKUP_TARGET}{$strTarget}{&MANIFEST_SUBKEY_TABLESPACE_ID}))
{
my $iCatalog = ${$oManifestRef}{&MANIFEST_SECTION_BACKUP_DB}{&MANIFEST_KEY_CATALOG};
@ -566,15 +563,11 @@ sub manifestTablespaceCreate
# Create the tablespace path if it does not exist
my $strTablespacePath = $strLinkPath;
my $strPathTarget = $strTarget;
my $iCatalog = ${$oManifestRef}{&MANIFEST_SECTION_BACKUP_DB}{&MANIFEST_KEY_CATALOG};
my $strTablespaceId = 'PG_' . ${$oManifestRef}{&MANIFEST_SECTION_BACKUP_DB}{&MANIFEST_KEY_DB_VERSION} . "_${iCatalog}";
if ($$oManifestRef{&MANIFEST_SECTION_BACKUP_DB}{&MANIFEST_KEY_DB_VERSION} >= PG_VERSION_90)
{
my $iCatalog = ${$oManifestRef}{&MANIFEST_SECTION_BACKUP_DB}{&MANIFEST_KEY_CATALOG};
my $strTablespaceId = 'PG_' . ${$oManifestRef}{&MANIFEST_SECTION_BACKUP_DB}{&MANIFEST_KEY_DB_VERSION} . "_${iCatalog}";
$strTablespacePath .= "/${strTablespaceId}";
$strPathTarget .= "/${strTablespaceId}";
}
$strTablespacePath .= "/${strTablespaceId}";
$strPathTarget .= "/${strTablespaceId}";
if (!-e $strTablespacePath)
{
@ -666,8 +659,7 @@ sub dbPathCreate
my $strFinalPath = ${$oManifestRef}{&MANIFEST_SECTION_BACKUP_TARGET}{$strTarget}{&MANIFEST_SUBKEY_PATH};
# Get tablespace path if this is a tablespace
if ($$oManifestRef{&MANIFEST_SECTION_BACKUP_DB}{&MANIFEST_KEY_DB_VERSION} >= PG_VERSION_90 &&
index($strTarget, DB_PATH_PGTBLSPC . '/') == 0)
if (index($strTarget, DB_PATH_PGTBLSPC . '/') == 0)
{
my $iCatalog = ${$oManifestRef}{&MANIFEST_SECTION_BACKUP_DB}{&MANIFEST_KEY_CATALOG};

View File

@ -429,10 +429,7 @@ sub clusterStart
$strCommand .= " -c archive_command=true";
}
if ($self->pgVersion() >= PG_VERSION_90)
{
$strCommand .= ' -c wal_level=hot_standby -c hot_standby=' . ($bHotStandby ? 'on' : 'off');
}
$strCommand .= ' -c wal_level=hot_standby -c hot_standby=' . ($bHotStandby ? 'on' : 'off');
# Force parallel mode on to make sure we are disabling it and there are no issues. This is important for testing that 9.6
# works since pg_stop_backup() is marked parallel safe and will error if run in a worker.

View File

@ -239,8 +239,6 @@ sub dbCatalogVersion
my $hCatalogVersion =
{
&PG_VERSION_83 => 200711281,
&PG_VERSION_84 => 200904091,
&PG_VERSION_90 => 201008051,
&PG_VERSION_91 => 201105231,
&PG_VERSION_92 => 201204301,
@ -284,8 +282,6 @@ sub dbControlVersion
my $hControlVersion =
{
&PG_VERSION_83 => 833,
&PG_VERSION_84 => 843,
&PG_VERSION_90 => 903,
&PG_VERSION_91 => 903,
&PG_VERSION_92 => 922,
@ -336,8 +332,6 @@ sub controlGenerateContent
{
32 =>
{
'8.3' => 96 - length($tControlContent),
'8.4' => 104 - length($tControlContent),
'9.0' => 140 - length($tControlContent),
'9.1' => 140 - length($tControlContent),
'9.2' => 156 - length($tControlContent),
@ -353,8 +347,6 @@ sub controlGenerateContent
64 =>
{
'8.3' => 112 - length($tControlContent),
'8.4' => 112 - length($tControlContent),
'9.0' => 152 - length($tControlContent),
'9.1' => 152 - length($tControlContent),
'9.2' => 168 - length($tControlContent),
@ -446,8 +438,6 @@ sub walGenerateContent
# Get WAL magic for the PG version
my $hWalMagic =
{
&PG_VERSION_83 => hex('0xD062'),
&PG_VERSION_84 => hex('0xD063'),
&PG_VERSION_90 => hex('0xD064'),
&PG_VERSION_91 => hex('0xD066'),
&PG_VERSION_92 => hex('0xD071'),

View File

@ -485,8 +485,7 @@ sub repoPathGet
my $strRepoFile = $strTarget;
if ($self->isTargetTablespace($strTarget) &&
($self->dbVersion() >= PG_VERSION_90))
if ($self->isTargetTablespace($strTarget))
{
$strRepoFile .= '/' . $self->tablespacePathGet();
}
@ -871,7 +870,7 @@ sub build
next if $strFile =~ ('^' . MANIFEST_PATH_PGDYNSHMEM . '\/') && $self->dbVersion() >= PG_VERSION_94;
# Skip pg_notify/* since these files cannot be reused on recovery
next if $strFile =~ ('^' . MANIFEST_PATH_PGNOTIFY . '\/') && $self->dbVersion() >= PG_VERSION_90;
next if $strFile =~ ('^' . MANIFEST_PATH_PGNOTIFY . '\/');
# Skip pg_replslot/* since these files are generally not useful after a restore
next if $strFile =~ ('^' . MANIFEST_PATH_PGREPLSLOT . '\/') && $self->dbVersion() >= PG_VERSION_94;
@ -884,7 +883,7 @@ sub build
# Skip temporary statistics in pg_stat_tmp even when stats_temp_directory is set because PGSS_TEXT_FILE is always created
# there.
next if $strFile =~ ('^' . MANIFEST_PATH_PGSTATTMP . '\/') && $self->dbVersion() >= PG_VERSION_84;
next if $strFile =~ ('^' . MANIFEST_PATH_PGSTATTMP . '\/');
# Skip pg_subtrans/* since these files are reset
next if $strFile =~ ('^' . MANIFEST_PATH_PGSUBTRANS . '\/');
@ -911,8 +910,8 @@ sub build
next;
}
# If version is greater than 9.0, check for files to exclude
if ($self->dbVersion() >= PG_VERSION_90 && $hManifest->{$strName}{type} eq 'f')
# Check for files to exclude
if ($hManifest->{$strName}{type} eq 'f')
{
# Get the directory name from the manifest; it will be used later to search for existence in the keys
my $strDir = dirname($strName);
@ -1078,12 +1077,7 @@ sub build
if ($bTablespace)
{
# Only versions >= 9.0 have the special top-level tablespace path. Below 9.0 the database files are stored
# directly in the path referenced by the symlink.
if ($self->dbVersion() >= PG_VERSION_90)
{
$strFilter = $self->tablespacePathGet();
}
$strFilter = $self->tablespacePathGet();
$self->set(MANIFEST_SECTION_TARGET_PATH, MANIFEST_TARGET_PGTBLSPC, undef,
$self->get(MANIFEST_SECTION_TARGET_PATH, MANIFEST_TARGET_PGDATA));

View File

@ -52,8 +52,6 @@ sub run
foreach my $rhRun
(
{pg => PG_VERSION_83, repoDest => HOST_DB_PRIMARY, tls => 0, storage => POSIX, encrypt => 0, compress => NONE, repo => 2},
{pg => PG_VERSION_84, repoDest => HOST_BACKUP, tls => 1, storage => AZURE, encrypt => 1, compress => GZ, repo => 1},
{pg => PG_VERSION_90, repoDest => HOST_DB_PRIMARY, tls => 0, storage => GCS, encrypt => 1, compress => BZ2, repo => 2},
{pg => PG_VERSION_91, repoDest => HOST_DB_STANDBY, tls => 1, storage => GCS, encrypt => 0, compress => GZ, repo => 1},
{pg => PG_VERSION_92, repoDest => HOST_DB_STANDBY, tls => 0, storage => POSIX, encrypt => 1, compress => NONE, repo => 1},
@ -572,34 +570,22 @@ sub run
# The tablespace path should exist and have files in it
my $strTablespacePath = $oHostDbPrimary->tablespacePath(1);
# Version <= 8.4 always places a PG_VERSION file in the tablespace
if ($oHostDbPrimary->pgVersion() <= PG_VERSION_84)
{
if (!storageTest()->exists("${strTablespacePath}/" . DB_FILE_PGVERSION))
{
confess &log(ASSERT, "unable to find '" . DB_FILE_PGVERSION . "' in tablespace path '${strTablespacePath}'");
}
}
# Version >= 9.0 creates a special path using the version and catalog number
else
{
# Backup info will have the catalog number
my $oBackupInfo = new pgBackRestDoc::Common::Ini(
storageRepo(), $oHostBackup->repoBackupPath(FILE_BACKUP_INFO),
{bLoad => false, strContent => ${storageRepo()->get($oHostBackup->repoBackupPath(FILE_BACKUP_INFO))}});
# Backup info will have the catalog number
my $oBackupInfo = new pgBackRestDoc::Common::Ini(
storageRepo(), $oHostBackup->repoBackupPath(FILE_BACKUP_INFO),
{bLoad => false, strContent => ${storageRepo()->get($oHostBackup->repoBackupPath(FILE_BACKUP_INFO))}});
# Construct the special path
$strTablespacePath .=
'/PG_' . $oHostDbPrimary->pgVersion() . qw{_} . $oBackupInfo->get(INFO_BACKUP_SECTION_DB, INFO_BACKUP_KEY_CATALOG);
# Construct the special path
$strTablespacePath .=
'/PG_' . $oHostDbPrimary->pgVersion() . qw{_} . $oBackupInfo->get(INFO_BACKUP_SECTION_DB, INFO_BACKUP_KEY_CATALOG);
# Check that path exists
if (!storageTest()->pathExists($strTablespacePath))
{
confess &log(ASSERT, "unable to find tablespace path '${strTablespacePath}'");
}
# Check that path exists
if (!storageTest()->pathExists($strTablespacePath))
{
confess &log(ASSERT, "unable to find tablespace path '${strTablespacePath}'");
}
# Make sure there are some files in the tablespace path (exclude PG_VERSION if <= 8.4 since that was tested above)
# Make sure there are some files in the tablespace path
if (grep(!/^PG\_VERSION$/i, storageTest()->list($strTablespacePath)) == 0)
{
confess &log(ASSERT, "no files found in tablespace path '${strTablespacePath}'");
@ -614,15 +600,7 @@ sub run
$oHostDbPrimary->sqlExecute('drop database test2', {bAutoCommit => true});
# The test table lives in ts1 so it needs to be moved or dropped
if ($oHostDbPrimary->pgVersion() >= PG_VERSION_90)
{
$oHostDbPrimary->sqlExecute('alter table test set tablespace pg_default');
}
# Drop for older versions
else
{
$oHostDbPrimary->sqlExecute('drop table test');
}
$oHostDbPrimary->sqlExecute('alter table test set tablespace pg_default');
# And drop the tablespace
$oHostDbPrimary->sqlExecute('drop database test3', {bAutoCommit => true});
@ -753,25 +731,19 @@ sub run
# Restore (restore type = default, timeline = created by type = xid, inclusive recovery)
#---------------------------------------------------------------------------------------------------------------------------
if ($oHostDbPrimary->pgVersion() >= PG_VERSION_84)
{
&log(INFO, ' testing recovery type = ' . CFGOPTVAL_RESTORE_TYPE_DEFAULT);
&log(INFO, ' testing recovery type = ' . CFGOPTVAL_RESTORE_TYPE_DEFAULT);
$oHostDbPrimary->clusterStop();
$oHostDbPrimary->clusterStop();
# The timeline to use for this test is subject to change based on tests being added or removed above. The best thing
# would be to automatically grab the timeline after the restore, but since this test has been stable for a long time
# it does not seem worth the effort to automate.
$oHostDbPrimary->restore(
undef, $strIncrBackup,
{bDelta => true,
strType => $oHostDbPrimary->pgVersion() >= PG_VERSION_90 ?
CFGOPTVAL_RESTORE_TYPE_STANDBY : CFGOPTVAL_RESTORE_TYPE_DEFAULT,
strTargetTimeline => 4, iRepo => $iRepoTotal});
# The timeline to use for this test is subject to change based on tests being added or removed above. The best thing
# would be to automatically grab the timeline after the restore, but since this test has been stable for a long time
# it does not seem worth the effort to automate.
$oHostDbPrimary->restore(
undef, $strIncrBackup,
{bDelta => true, strType => CFGOPTVAL_RESTORE_TYPE_STANDBY, strTargetTimeline => 4, iRepo => $iRepoTotal});
$oHostDbPrimary->clusterStart({bHotStandby => true});
$oHostDbPrimary->sqlSelectOneTest('select message from test', $strTimelineMessage, {iTimeout => 120});
}
$oHostDbPrimary->clusterStart({bHotStandby => true});
$oHostDbPrimary->sqlSelectOneTest('select message from test', $strTimelineMessage, {iTimeout => 120});
# Stop clusters to catch any errors in the postgres log
#---------------------------------------------------------------------------------------------------------------------------

View File

@ -11,14 +11,6 @@ Harness for PostgreSQL Interface
/***********************************************************************************************************************************
Interface definition
***********************************************************************************************************************************/
uint32_t hrnPgInterfaceCatalogVersion083(void);
void hrnPgInterfaceControl083(PgControl pgControl, unsigned char *buffer);
void hrnPgInterfaceWal083(PgWal pgWal, unsigned char *buffer);
uint32_t hrnPgInterfaceCatalogVersion084(void);
void hrnPgInterfaceControl084(PgControl pgControl, unsigned char *buffer);
void hrnPgInterfaceWal084(PgWal pgWal, unsigned char *buffer);
uint32_t hrnPgInterfaceCatalogVersion090(void);
void hrnPgInterfaceControl090(PgControl pgControl, unsigned char *buffer);
void hrnPgInterfaceWal090(PgWal pgWal, unsigned char *buffer);
@ -167,20 +159,6 @@ static const HrnPgInterface hrnPgInterface[] =
.control = hrnPgInterfaceControl090,
.wal = hrnPgInterfaceWal090,
},
{
.version = PG_VERSION_84,
.catalogVersion = hrnPgInterfaceCatalogVersion084,
.control = hrnPgInterfaceControl084,
.wal = hrnPgInterfaceWal084,
},
{
.version = PG_VERSION_83,
.catalogVersion = hrnPgInterfaceCatalogVersion083,
.control = hrnPgInterfaceControl083,
.wal = hrnPgInterfaceWal083,
},
};
/***********************************************************************************************************************************

View File

@ -17,10 +17,6 @@ Control file size used to create pg_control
/***********************************************************************************************************************************
System id constants by version
***********************************************************************************************************************************/
#define HRN_PG_SYSTEMID_83 (10000000000000000000ULL + (uint64_t)PG_VERSION_83)
#define HRN_PG_SYSTEMID_83_Z "10000000000000080300"
#define HRN_PG_SYSTEMID_84 (10000000000000000000ULL + (uint64_t)PG_VERSION_84)
#define HRN_PG_SYSTEMID_84_Z "10000000000000080400"
#define HRN_PG_SYSTEMID_90 (10000000000000000000ULL + (uint64_t)PG_VERSION_90)
#define HRN_PG_SYSTEMID_90_Z "10000000000000090000"
#define HRN_PG_SYSTEMID_91 (10000000000000000000ULL + (uint64_t)PG_VERSION_91)

View File

@ -1,10 +0,0 @@
/***********************************************************************************************************************************
Harness for PostgreSQL Interface (see PG_VERSION for version)
***********************************************************************************************************************************/
#include "build.auto.h"
#define PG_VERSION PG_VERSION_83
#include "common/harnessPostgres/harnessVersion.intern.h"
HRN_PG_INTERFACE(083);

View File

@ -1,10 +0,0 @@
/***********************************************************************************************************************************
Harness for PostgreSQL Interface (see PG_VERSION for version)
***********************************************************************************************************************************/
#include "build.auto.h"
#define PG_VERSION PG_VERSION_84
#include "common/harnessPostgres/harnessVersion.intern.h"
HRN_PG_INTERFACE(084);

View File

@ -16,7 +16,7 @@ Get the catalog version
***********************************************************************************************************************************/
#if PG_VERSION > PG_VERSION_MAX
#elif PG_VERSION >= PG_VERSION_83
#elif PG_VERSION >= PG_VERSION_90
#define HRN_PG_INTERFACE_CATALOG_VERSION(version) \
uint32_t \
@ -56,7 +56,7 @@ Create a pg_control file
}; \
}
#elif PG_VERSION >= PG_VERSION_83
#elif PG_VERSION >= PG_VERSION_90
#define HRN_PG_INTERFACE_CONTROL_TEST(version) \
void \
@ -91,7 +91,7 @@ Create a WAL file
***********************************************************************************************************************************/
#if PG_VERSION > PG_VERSION_MAX
#elif PG_VERSION >= PG_VERSION_83
#elif PG_VERSION >= PG_VERSION_90
#define HRN_PG_INTERFACE_WAL_TEST(version) \
void \

View File

@ -232,28 +232,7 @@ Macros for defining groups of functions that implement various queries and comma
{.session = sessionParam, .function = HRNPQ_CLEAR}, \
{.session = sessionParam, .function = HRNPQ_GETRESULT, .resultNull = true}
#define HRNPQ_MACRO_START_BACKUP_83(sessionParam, lsnParam, walSegmentNameParam) \
{.session = sessionParam, \
.function = HRNPQ_SENDQUERY, \
.param = \
"[\"select lsn::text as lsn,\\n" \
" pg_catalog.pg_xlogfile_name(lsn)::text as wal_segment_name\\n" \
" from pg_catalog.pg_start_backup('pgBackRest backup started at ' || current_timestamp) as lsn\"]", \
.resultInt = 1}, \
{.session = sessionParam, .function = HRNPQ_CONSUMEINPUT}, \
{.session = sessionParam, .function = HRNPQ_ISBUSY}, \
{.session = sessionParam, .function = HRNPQ_GETRESULT}, \
{.session = sessionParam, .function = HRNPQ_RESULTSTATUS, .resultInt = PGRES_TUPLES_OK}, \
{.session = sessionParam, .function = HRNPQ_NTUPLES, .resultInt = 1}, \
{.session = sessionParam, .function = HRNPQ_NFIELDS, .resultInt = 2}, \
{.session = sessionParam, .function = HRNPQ_FTYPE, .param = "[0]", .resultInt = HRNPQ_TYPE_TEXT}, \
{.session = sessionParam, .function = HRNPQ_FTYPE, .param = "[1]", .resultInt = HRNPQ_TYPE_TEXT}, \
{.session = sessionParam, .function = HRNPQ_GETVALUE, .param = "[0,0]", .resultZ = lsnParam}, \
{.session = sessionParam, .function = HRNPQ_GETVALUE, .param = "[0,1]", .resultZ = walSegmentNameParam}, \
{.session = sessionParam, .function = HRNPQ_CLEAR}, \
{.session = sessionParam, .function = HRNPQ_GETRESULT, .resultNull = true}
#define HRNPQ_MACRO_START_BACKUP_84_95(sessionParam, startFastParam, lsnParam, walSegmentNameParam) \
#define HRNPQ_MACRO_START_BACKUP_LE_95(sessionParam, startFastParam, lsnParam, walSegmentNameParam) \
{.session = sessionParam, \
.function = HRNPQ_SENDQUERY, \
.param = strZ(strNewFmt( \
@ -542,7 +521,8 @@ Macros to simplify dbOpen() for specific database versions
HRNPQ_MACRO_OPEN(sessionParam, connectParam), \
HRNPQ_MACRO_SET_SEARCH_PATH(sessionParam), \
HRNPQ_MACRO_SET_CLIENT_ENCODING(sessionParam), \
HRNPQ_MACRO_VALIDATE_QUERY(sessionParam, pgVersion, pgPathParam, archiveMode, archiveCommand)
HRNPQ_MACRO_VALIDATE_QUERY(sessionParam, pgVersion, pgPathParam, archiveMode, archiveCommand), \
HRNPQ_MACRO_SET_APPLICATION_NAME(sessionParam)
#define HRNPQ_MACRO_OPEN_GE_92(sessionParam, connectParam, pgVersion, pgPathParam, standbyParam, archiveMode, archiveCommand) \
HRNPQ_MACRO_OPEN(sessionParam, connectParam), \

View File

@ -337,7 +337,7 @@ testBackupPqScript(unsigned int pgVersion, time_t backupTimeStart, TestBackupPqS
// Start backup
HRNPQ_MACRO_ADVISORY_LOCK(1, true),
HRNPQ_MACRO_IS_IN_BACKUP(1, false),
HRNPQ_MACRO_START_BACKUP_84_95(1, param.startFast, lsnStartStr, walSegmentStart),
HRNPQ_MACRO_START_BACKUP_LE_95(1, param.startFast, lsnStartStr, walSegmentStart),
HRNPQ_MACRO_DATABASE_LIST_1(1, "test1"),
HRNPQ_MACRO_TABLESPACE_LIST_0(1),
@ -372,7 +372,7 @@ testBackupPqScript(unsigned int pgVersion, time_t backupTimeStart, TestBackupPqS
HRNPQ_MACRO_ADVISORY_LOCK(1, true),
HRNPQ_MACRO_IS_IN_BACKUP(1, false),
HRNPQ_MACRO_CURRENT_WAL_LE_96(1, walSegmentPrior),
HRNPQ_MACRO_START_BACKUP_84_95(1, param.startFast, lsnStartStr, walSegmentStart),
HRNPQ_MACRO_START_BACKUP_LE_95(1, param.startFast, lsnStartStr, walSegmentStart),
HRNPQ_MACRO_DATABASE_LIST_1(1, "test1"),
HRNPQ_MACRO_TABLESPACE_LIST_0(1),
@ -1072,33 +1072,11 @@ testRun(void)
" " HRN_PG_SYSTEMID_11_Z "\n"
"HINT: is this the correct stanza?");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("reset start-fast when PostgreSQL < 8.4");
// Create pg_control
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_83);
argList = strLstNew();
hrnCfgArgRawZ(argList, cfgOptStanza, "test1");
hrnCfgArgRawZ(argList, cfgOptRepoPath, TEST_PATH "/repo");
hrnCfgArgRawZ(argList, cfgOptPgPath, TEST_PATH "/pg1");
hrnCfgArgRawZ(argList, cfgOptRepoRetentionFull, "1");
hrnCfgArgRawBool(argList, cfgOptOnline, false);
hrnCfgArgRawBool(argList, cfgOptStartFast, true);
HRN_CFG_LOAD(cfgCmdBackup, argList);
TEST_RESULT_VOID(
backupInit(infoBackupNew(PG_VERSION_83, HRN_PG_SYSTEMID_83, hrnPgCatalogVersion(PG_VERSION_83), NULL)),
"backup init");
TEST_RESULT_BOOL(cfgOptionBool(cfgOptStartFast), false, "check start-fast");
TEST_RESULT_LOG("P00 WARN: start-fast option is only available in PostgreSQL >= 8.4");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("reset stop-auto when PostgreSQL < 9.3");
// Create pg_control
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_84);
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_90);
argList = strLstNew();
hrnCfgArgRawZ(argList, cfgOptStanza, "test1");
@ -1110,7 +1088,7 @@ testRun(void)
HRN_CFG_LOAD(cfgCmdBackup, argList);
TEST_RESULT_VOID(
backupInit(infoBackupNew(PG_VERSION_84, HRN_PG_SYSTEMID_84, hrnPgCatalogVersion(PG_VERSION_84), NULL)),
backupInit(infoBackupNew(PG_VERSION_90, HRN_PG_SYSTEMID_90, hrnPgCatalogVersion(PG_VERSION_90), NULL)),
"backup init");
TEST_RESULT_BOOL(cfgOptionBool(cfgOptStopAuto), false, "check stop-auto");
@ -1489,7 +1467,7 @@ testRun(void)
HRN_CFG_LOAD(cfgCmdStanzaCreate, argList);
// Create pg_control
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_84);
HRN_PG_CONTROL_PUT(storagePgWrite(), PG_VERSION_90);
cmdStanzaCreate();
TEST_RESULT_LOG("P00 INFO: stanza-create for stanza 'test1' on repo1");
@ -1541,8 +1519,8 @@ testRun(void)
"P00 INFO: new backup label = [FULL-1]\n"
"P00 INFO: full backup size = 8KB, file total = 2",
TEST_64BIT() ?
(TEST_BIG_ENDIAN() ? "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" : "6c1435a9f3c24a020794f58945ada456cb1d3bbe") :
"d432aca683e0443e97cf0600ba3a5a9efd7586fd");
(TEST_BIG_ENDIAN() ? "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" : "b7ec43e4646f5d06c95881df0c572630a1221377") :
"f21ff9abdcd1ec2f600d4ee8e5792c9b61eb2e37");
// Make pg no longer appear to be running
HRN_STORAGE_REMOVE(storagePgWrite(), PG_FILE_POSTMTRPID, .errorOnMissing = true);

View File

@ -1267,7 +1267,8 @@ testRun(void)
OBJ_NEW_BEGIN(Manifest)
{
manifest = manifestNewInternal();
manifest->pub.data.pgVersion = PG_VERSION_84;
manifest->pub.data.pgVersion = PG_VERSION_90;
manifest->pub.data.pgCatalogVersion = hrnPgCatalogVersion(PG_VERSION_90);
manifestTargetAdd(manifest, &(ManifestTarget){.name = MANIFEST_TARGET_PGDATA_STR, .path = STRDEF("/pg")});
manifestFileAdd(manifest, &(ManifestFile){.name = STRDEF(MANIFEST_TARGET_PGDATA "/" PG_FILE_PGVERSION)});
@ -1420,7 +1421,8 @@ testRun(void)
MEM_CONTEXT_END();
TEST_RESULT_STR_Z(
restoreSelectiveExpression(manifest), "(^pg_data/base/32768/)|(^pg_tblspc/16387/32768/)", "check expression");
restoreSelectiveExpression(manifest), "(^pg_data/base/32768/)|(^pg_tblspc/16387/PG_9.0_201008051/32768/)",
"check expression");
TEST_RESULT_LOG(
"P00 DETAIL: databases found for selective restore (1, 12168, 16380, 16381, 16384, 16385, 32768)\n"
@ -1999,7 +2001,8 @@ testRun(void)
manifest = manifestNewInternal();
manifest->pub.info = infoNew(NULL);
manifest->pub.data.backupLabel = STRDEF(TEST_LABEL);
manifest->pub.data.pgVersion = PG_VERSION_84;
manifest->pub.data.pgVersion = PG_VERSION_90;
manifest->pub.data.pgCatalogVersion = hrnPgCatalogVersion(PG_VERSION_90);
manifest->pub.data.backupType = backupTypeFull;
manifest->pub.data.backupTimestampCopyStart = 1482182861; // So file timestamps should be less than this
@ -2021,39 +2024,19 @@ testRun(void)
&(ManifestFile){
.name = STRDEF(TEST_PGDATA PG_FILE_PGVERSION), .size = 4, .timestamp = 1482182860,
.mode = 0600, .group = groupName(), .user = userName(),
.checksumSha1 = "797e375b924134687cbf9eacd37a4355f3d825e4"});
HRN_STORAGE_PUT_Z(storageRepoIdxWrite(0), TEST_REPO_PATH PG_FILE_PGVERSION, PG_VERSION_84_STR "\n");
.checksumSha1 = "b74d60e763728399bcd3fb63f7dd1f97b46c6b44"});
HRN_STORAGE_PUT_Z(storageRepoIdxWrite(0), TEST_REPO_PATH PG_FILE_PGVERSION, PG_VERSION_90_STR "\n");
// Store the file also to the encrypted repo
HRN_STORAGE_PUT_Z(
storageRepoIdxWrite(1), TEST_REPO_PATH PG_FILE_PGVERSION, PG_VERSION_84_STR "\n",
storageRepoIdxWrite(1), TEST_REPO_PATH PG_FILE_PGVERSION, PG_VERSION_90_STR "\n",
.cipherType = cipherTypeAes256Cbc, .cipherPass = TEST_CIPHER_PASS_ARCHIVE);
// pg_tblspc/1
manifestTargetAdd(
manifest, &(ManifestTarget){
.type = manifestTargetTypeLink, .name = STRDEF(MANIFEST_TARGET_PGTBLSPC "/1"),
.path = STRDEF(TEST_PATH "/ts/1"), .tablespaceId = 1, .tablespaceName = STRDEF("ts1")});
// pg_tblspc
manifestPathAdd(
manifest, &(ManifestPath){
.name = STRDEF(MANIFEST_TARGET_PGDATA "/" MANIFEST_TARGET_PGTBLSPC), .mode = 0700, .group = groupName(),
.user = userName()});
manifestPathAdd(
manifest, &(ManifestPath){
.name = STRDEF(MANIFEST_TARGET_PGTBLSPC), .mode = 0700, .group = groupName(), .user = userName()});
manifestPathAdd(
manifest, &(ManifestPath){
.name = STRDEF(MANIFEST_TARGET_PGTBLSPC "/1"), .mode = 0700, .group = groupName(), .user = userName()});
manifestLinkAdd(
manifest, &(ManifestLink){
.name = STRDEF(MANIFEST_TARGET_PGDATA "/" MANIFEST_TARGET_PGTBLSPC "/1"),
.destination = STRDEF(TEST_PATH "/ts/1"), .group = groupName(), .user = userName()});
// pg_tblspc/1/16384 path
manifestPathAdd(
manifest, &(ManifestPath){
.name = STRDEF(MANIFEST_TARGET_PGTBLSPC "/1/16384"), .mode = 0700,
.group = groupName(), .user = userName()});
// Always sort
lstSort(manifest->pub.targetList, sortOrderAsc);
@ -2104,17 +2087,12 @@ testRun(void)
" HINT: has a stanza-create been performed?\n"
"P00 INFO: repo2: restore backup set 20161219-212741F\n"
"P00 DETAIL: check '" TEST_PATH "/pg' exists\n"
"P00 DETAIL: check '" TEST_PATH "/ts/1' exists\n"
"P00 DETAIL: create path '" TEST_PATH "/pg/global'\n"
"P00 DETAIL: create path '" TEST_PATH "/pg/pg_tblspc'\n"
"P00 DETAIL: create symlink '" TEST_PATH "/pg/pg_tblspc/1' to '" TEST_PATH "/ts/1'\n"
"P00 DETAIL: create path '" TEST_PATH "/pg/pg_tblspc/1/16384'\n"
"P01 DETAIL: restore file " TEST_PATH "/pg/PG_VERSION (4B, 100%%) checksum 797e375b924134687cbf9eacd37a4355f3d825e4\n"
"P01 DETAIL: restore file " TEST_PATH "/pg/PG_VERSION (4B, 100%%) checksum b74d60e763728399bcd3fb63f7dd1f97b46c6b44\n"
"P00 INFO: write " TEST_PATH "/pg/recovery.conf\n"
"P00 DETAIL: sync path '" TEST_PATH "/pg'\n"
"P00 DETAIL: sync path '" TEST_PATH "/pg/pg_tblspc'\n"
"P00 DETAIL: sync path '" TEST_PATH "/pg/pg_tblspc/1'\n"
"P00 DETAIL: sync path '" TEST_PATH "/pg/pg_tblspc/1/16384'\n"
"P00 WARN: backup does not contain 'global/pg_control' -- cluster will not start\n"
"P00 DETAIL: sync path '" TEST_PATH "/pg/global'\n"
"P00 INFO: restore size = 4B, file total = 1",
@ -2128,13 +2106,7 @@ testRun(void)
". {path}\n"
"PG_VERSION {file, s=4, t=1482182860}\n"
"global {path}\n"
"pg_tblspc {path}\n"
"pg_tblspc/1 {link, d=" TEST_PATH "/ts/1}\n");
testRestoreCompare(
storagePg(), STRDEF("pg_tblspc/1"), manifest,
". {link, d=" TEST_PATH "/ts/1}\n"
"16384 {path}\n");
"pg_tblspc {path}\n");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("full restore with delta force");
@ -2171,7 +2143,6 @@ testRun(void)
HRN_STORAGE_PUT_Z(storagePgWrite(), PG_FILE_PGVERSION, "BOG\n", .modeFile = 0600, .timeModified = 1482182860);
// Change destination of tablespace link
HRN_STORAGE_REMOVE(storagePgWrite(), "pg_tblspc/1", .errorOnMissing = true);
THROW_ON_SYS_ERROR(
symlink("/bogus", strZ(strNewFmt("%s/pg_tblspc/1", strZ(pgPath)))) == -1, FileOpenError,
"unable to create symlink");
@ -2186,16 +2157,42 @@ testRun(void)
.mode = 0600, .group = groupName(), .user = userName(), .checksumSha1 = HASH_TYPE_SHA1_ZERO});
HRN_STORAGE_PUT_EMPTY(storageRepoWrite(), TEST_REPO_PATH PG_FILE_TABLESPACEMAP);
// pg_tblspc/1
manifestTargetAdd(
manifest, &(ManifestTarget){
.type = manifestTargetTypeLink, .name = STRDEF(MANIFEST_TARGET_PGTBLSPC "/1"),
.path = STRDEF(TEST_PATH "/ts/1"), .tablespaceId = 1, .tablespaceName = STRDEF("ts1")});
manifestPathAdd(
manifest, &(ManifestPath){
.name = STRDEF(MANIFEST_TARGET_PGTBLSPC), .mode = 0700, .group = groupName(), .user = userName()});
manifestPathAdd(
manifest, &(ManifestPath){
.name = STRDEF(MANIFEST_TARGET_PGTBLSPC "/1"), .mode = 0700, .group = groupName(), .user = userName()});
manifestPathAdd(
manifest, &(ManifestPath){
.name = STRDEF(MANIFEST_TARGET_PGTBLSPC "/1/PG_9.0_201008051"), .mode = 0700, .group = groupName(),
.user = userName()});
manifestLinkAdd(
manifest, &(ManifestLink){
.name = STRDEF(MANIFEST_TARGET_PGDATA "/" MANIFEST_TARGET_PGTBLSPC "/1"),
.destination = STRDEF(TEST_PATH "/ts/1"), .group = groupName(), .user = userName()});
// pg_tblspc/1/16384 path
manifestPathAdd(
manifest, &(ManifestPath){
.name = STRDEF(MANIFEST_TARGET_PGTBLSPC "/1/16384"), .mode = 0700,
.group = groupName(), .user = userName()});
// pg_tblspc/1/16384/PG_VERSION
manifestFileAdd(
manifest,
&(ManifestFile){
.name = STRDEF(MANIFEST_TARGET_PGTBLSPC "/1/16384/" PG_FILE_PGVERSION), .size = 4,
.timestamp = 1482182860, .mode = 0600, .group = groupName(), .user = userName(),
.checksumSha1 = "797e375b924134687cbf9eacd37a4355f3d825e4"});
.checksumSha1 = "b74d60e763728399bcd3fb63f7dd1f97b46c6b44"});
HRN_STORAGE_PUT_Z(
storageRepoWrite(), STORAGE_REPO_BACKUP "/" TEST_LABEL "/" MANIFEST_TARGET_PGTBLSPC "/1/16384/" PG_FILE_PGVERSION,
PG_VERSION_84_STR "\n");
PG_VERSION_90_STR "\n");
// Always sort
lstSort(manifest->pub.targetList, sortOrderAsc);
@ -2220,24 +2217,25 @@ testRun(void)
TEST_RESULT_LOG(
"P00 INFO: repo1: restore backup set 20161219-212741F\n"
"P00 DETAIL: check '" TEST_PATH "/pg' exists\n"
"P00 DETAIL: check '" TEST_PATH "/ts/1' exists\n"
"P00 DETAIL: check '" TEST_PATH "/ts/1/PG_9.0_201008051' exists\n"
"P00 INFO: remove invalid files/links/paths from '" TEST_PATH "/pg'\n"
"P00 DETAIL: update mode for '" TEST_PATH "/pg' to 0700\n"
"P00 DETAIL: remove invalid file '" TEST_PATH "/pg/bogus-file'\n"
"P00 DETAIL: remove link '" TEST_PATH "/pg/pg_tblspc/1' because destination changed\n"
"P00 DETAIL: remove special file '" TEST_PATH "/pg/pipe'\n"
"P00 INFO: remove invalid files/links/paths from '" TEST_PATH "/ts/1'\n"
"P00 DETAIL: create symlink '" TEST_PATH "/pg/pg_tblspc/1' to '" TEST_PATH "/ts/1'\n"
"P00 DETAIL: create path '" TEST_PATH "/pg/pg_tblspc/1/16384'\n"
"P01 DETAIL: restore file " TEST_PATH "/pg/PG_VERSION - exists and matches size 4 and modification time 1482182860"
" (4B, 50%) checksum 797e375b924134687cbf9eacd37a4355f3d825e4\n"
" (4B, 50%) checksum b74d60e763728399bcd3fb63f7dd1f97b46c6b44\n"
"P01 DETAIL: restore file " TEST_PATH "/pg/tablespace_map (0B, 50%)\n"
"P01 DETAIL: restore file " TEST_PATH "/pg/pg_tblspc/1/16384/PG_VERSION (4B, 100%)"
" checksum 797e375b924134687cbf9eacd37a4355f3d825e4\n"
" checksum b74d60e763728399bcd3fb63f7dd1f97b46c6b44\n"
"P00 WARN: recovery type is preserve but recovery file does not exist at '" TEST_PATH "/pg/recovery.conf'\n"
"P00 DETAIL: sync path '" TEST_PATH "/pg'\n"
"P00 DETAIL: sync path '" TEST_PATH "/pg/pg_tblspc'\n"
"P00 DETAIL: sync path '" TEST_PATH "/pg/pg_tblspc/1'\n"
"P00 DETAIL: sync path '" TEST_PATH "/pg/pg_tblspc/1/16384'\n"
"P00 DETAIL: sync path '" TEST_PATH "/pg/pg_tblspc/1/PG_9.0_201008051'\n"
"P00 WARN: backup does not contain 'global/pg_control' -- cluster will not start\n"
"P00 DETAIL: sync path '" TEST_PATH "/pg/global'\n"
"P00 INFO: restore size = 8B, file total = 3");
@ -2255,7 +2253,8 @@ testRun(void)
storagePg(), STRDEF("pg_tblspc/1"), manifest,
". {link, d=" TEST_PATH "/ts/1}\n"
"16384 {path}\n"
"16384/PG_VERSION {file, s=4, t=1482182860}\n");
"16384/PG_VERSION {file, s=4, t=1482182860}\n"
"PG_9.0_201008051 {path}\n");
// PG_VERSION was not restored because delta force relies on time and size which were the same in the manifest and on disk
TEST_STORAGE_GET(storagePg(), PG_FILE_PGVERSION, "BOG\n", .comment = "check PG_VERSION was not restored");
@ -2281,18 +2280,19 @@ testRun(void)
TEST_RESULT_LOG(
"P00 INFO: repo1: restore backup set 20161219-212741F\n"
"P00 DETAIL: check '" TEST_PATH "/pg' exists\n"
"P00 DETAIL: check '" TEST_PATH "/ts/1' exists\n"
"P00 DETAIL: check '" TEST_PATH "/ts/1/PG_9.0_201008051' exists\n"
"P00 INFO: remove invalid files/links/paths from '" TEST_PATH "/pg'\n"
"P00 INFO: remove invalid files/links/paths from '" TEST_PATH "/ts/1'\n"
"P01 DETAIL: restore file " TEST_PATH "/pg/PG_VERSION (4B, 50%) checksum 797e375b924134687cbf9eacd37a4355f3d825e4\n"
"P00 INFO: remove invalid files/links/paths from '" TEST_PATH "/ts/1/PG_9.0_201008051'\n"
"P01 DETAIL: restore file " TEST_PATH "/pg/PG_VERSION (4B, 50%) checksum b74d60e763728399bcd3fb63f7dd1f97b46c6b44\n"
"P01 DETAIL: restore file " TEST_PATH "/pg/tablespace_map (0B, 50%)\n"
"P01 DETAIL: restore file " TEST_PATH "/pg/pg_tblspc/1/16384/PG_VERSION (4B, 100%)"
" checksum 797e375b924134687cbf9eacd37a4355f3d825e4\n"
" checksum b74d60e763728399bcd3fb63f7dd1f97b46c6b44\n"
"P00 WARN: recovery type is preserve but recovery file does not exist at '" TEST_PATH "/pg/recovery.conf'\n"
"P00 DETAIL: sync path '" TEST_PATH "/pg'\n"
"P00 DETAIL: sync path '" TEST_PATH "/pg/pg_tblspc'\n"
"P00 DETAIL: sync path '" TEST_PATH "/pg/pg_tblspc/1'\n"
"P00 DETAIL: sync path '" TEST_PATH "/pg/pg_tblspc/1/16384'\n"
"P00 DETAIL: sync path '" TEST_PATH "/pg/pg_tblspc/1/PG_9.0_201008051'\n"
"P00 WARN: backup does not contain 'global/pg_control' -- cluster will not start\n"
"P00 DETAIL: sync path '" TEST_PATH "/pg/global'\n"
"P00 INFO: restore size = 8B, file total = 3");
@ -2310,10 +2310,14 @@ testRun(void)
storagePg(), STRDEF("pg_tblspc/1"), manifest,
". {link, d=" TEST_PATH "/ts/1}\n"
"16384 {path}\n"
"16384/PG_VERSION {file, s=4, t=1482182860}\n");
"16384/PG_VERSION {file, s=4, t=1482182860}\n"
"PG_9.0_201008051 {path}\n");
// PG_VERSION was restored by the force option
TEST_STORAGE_GET(storagePg(), PG_FILE_PGVERSION, PG_VERSION_84_STR "\n", .comment = "check PG_VERSION was restored");
TEST_STORAGE_GET(storagePg(), PG_FILE_PGVERSION, PG_VERSION_90_STR "\n", .comment = "check PG_VERSION was restored");
// Remove tablespace
HRN_STORAGE_PATH_REMOVE(storagePgWrite(), MANIFEST_TARGET_PGTBLSPC "/1/PG_9.0_201008051", .recurse = true);
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("incremental delta selective restore");

View File

@ -81,13 +81,15 @@ testRun(void)
HRNPQ_MACRO_OPEN(1, "dbname='testdb' port=5432"),
HRNPQ_MACRO_SET_SEARCH_PATH(1),
HRNPQ_MACRO_SET_CLIENT_ENCODING(1),
HRNPQ_MACRO_VALIDATE_QUERY(1, PG_VERSION_84, TEST_PATH "/pg", NULL, NULL),
HRNPQ_MACRO_VALIDATE_QUERY(1, PG_VERSION_90, TEST_PATH "/pg", NULL, NULL),
HRNPQ_MACRO_SET_APPLICATION_NAME(1),
HRNPQ_MACRO_CLOSE(1),
HRNPQ_MACRO_OPEN(1, "dbname='testdb' port=5432"),
HRNPQ_MACRO_SET_SEARCH_PATH(1),
HRNPQ_MACRO_SET_CLIENT_ENCODING(1),
HRNPQ_MACRO_VALIDATE_QUERY(1, PG_VERSION_84, TEST_PATH "/pg", NULL, NULL),
HRNPQ_MACRO_VALIDATE_QUERY(1, PG_VERSION_90, TEST_PATH "/pg", NULL, NULL),
HRNPQ_MACRO_SET_APPLICATION_NAME(1),
HRNPQ_MACRO_WAL_SWITCH(1, "xlog", "000000030000000200000003"),
HRNPQ_MACRO_CLOSE(1),
@ -143,7 +145,7 @@ testRun(void)
// -------------------------------------------------------------------------------------------------------------
TEST_TITLE("open and free database");
TEST_ASSIGN(db, dbNew(NULL, client, storagePgIdx(0), STRDEF("test")), "create db");
TEST_ASSIGN(db, dbNew(NULL, client, storagePgIdx(0), STRDEF(PROJECT_NAME " [" CFGCMD_BACKUP "]")), "create db");
TRY_BEGIN()
{
@ -162,7 +164,7 @@ testRun(void)
// -------------------------------------------------------------------------------------------------------------
TEST_TITLE("remote commands");
TEST_ASSIGN(db, dbNew(NULL, client, storagePgIdx(0), STRDEF("test")), "create db");
TEST_ASSIGN(db, dbNew(NULL, client, storagePgIdx(0), STRDEF(PROJECT_NAME " [" CFGCMD_BACKUP "]")), "create db");
TRY_BEGIN()
{
@ -257,22 +259,19 @@ testRun(void)
" HINT: is the pg_read_all_settings role assigned for PostgreSQL >= 10?");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("PostgreSQL 8.3 start backup with no start fast");
TEST_TITLE("PostgreSQL 9.0 start backup with no WAL switch");
harnessPqScriptSet((HarnessPq [])
{
// Connect to primary
HRNPQ_MACRO_OPEN_LE_91(1, "dbname='backupdb' port=5432", PG_VERSION_83, TEST_PATH "/pg1", NULL, NULL),
HRNPQ_MACRO_OPEN_LE_91(1, "dbname='backupdb' port=5432", PG_VERSION_90, TEST_PATH "/pg1", NULL, NULL),
// Get advisory lock
HRNPQ_MACRO_ADVISORY_LOCK(1, true),
// Start backup with no start fast
// Start backup with no wal switch
HRNPQ_MACRO_CURRENT_WAL_LE_96(1, "000000010000000100000001"),
HRNPQ_MACRO_START_BACKUP_83(1, "1/1", "000000010000000100000001"),
// Ping
HRNPQ_MACRO_TIME_QUERY(1, 0),
HRNPQ_MACRO_START_BACKUP_LE_95(1, false, "1/1", "000000010000000100000001"),
// Close primary
HRNPQ_MACRO_CLOSE(1),
@ -314,7 +313,7 @@ testRun(void)
// Start backup
HRNPQ_MACRO_ADVISORY_LOCK(1, true),
HRNPQ_MACRO_IS_IN_BACKUP(1, false),
HRNPQ_MACRO_START_BACKUP_84_95(1, false, "2/3", "000000010000000200000003"),
HRNPQ_MACRO_START_BACKUP_LE_95(1, false, "2/3", "000000010000000200000003"),
HRNPQ_MACRO_DATABASE_LIST_1(1, "test1"),
HRNPQ_MACRO_TABLESPACE_LIST_0(1),
@ -370,7 +369,7 @@ testRun(void)
HRNPQ_MACRO_STOP_BACKUP_LE_95(1, "1/1", "000000010000000100000001"),
// Start backup
HRNPQ_MACRO_START_BACKUP_84_95(1, true, "2/5", "000000010000000200000005"),
HRNPQ_MACRO_START_BACKUP_LE_95(1, true, "2/5", "000000010000000200000005"),
// Stop backup
HRNPQ_MACRO_STOP_BACKUP_LE_95(1, "2/6", "000000010000000200000006"),
@ -473,7 +472,7 @@ testRun(void)
// Start backup
HRNPQ_MACRO_ADVISORY_LOCK(1, true),
HRNPQ_MACRO_START_BACKUP_84_95(1, false, "5/4", "000000050000000500000004"),
HRNPQ_MACRO_START_BACKUP_LE_95(1, false, "5/4", "000000050000000500000004"),
// Wait for standby to sync
HRNPQ_MACRO_REPLAY_WAIT_LE_95(2, "5/4"),
@ -745,7 +744,7 @@ testRun(void)
harnessPqScriptSet((HarnessPq [])
{
HRNPQ_MACRO_OPEN_LE_91(1, "dbname='postgres' port=5432 user='bob'", PG_VERSION_84, TEST_PATH "/pg1", NULL, NULL),
HRNPQ_MACRO_OPEN_LE_91(1, "dbname='postgres' port=5432 user='bob'", PG_VERSION_90, TEST_PATH "/pg1", NULL, NULL),
HRNPQ_MACRO_CLOSE(1),
HRNPQ_MACRO_DONE()
});
@ -756,7 +755,7 @@ testRun(void)
TEST_RESULT_BOOL(result.primary != NULL, true, "check primary");
TEST_RESULT_INT(result.standbyIdx, 0, "check standby id");
TEST_RESULT_BOOL(result.standby == NULL, true, "check standby");
TEST_RESULT_INT(dbPgVersion(result.primary), PG_VERSION_84, "version set");
TEST_RESULT_INT(dbPgVersion(result.primary), PG_VERSION_90, "version set");
TEST_RESULT_STR_Z(dbPgDataPath(result.primary), TEST_PATH "/pg1", "path set");
TEST_RESULT_VOID(dbFree(result.primary), "free primary");
@ -777,8 +776,8 @@ testRun(void)
harnessPqScriptSet((HarnessPq [])
{
HRNPQ_MACRO_OPEN_LE_91(1, "dbname='postgres' port=5432", PG_VERSION_84, TEST_PATH "/pg1", NULL, NULL),
HRNPQ_MACRO_OPEN_LE_91(8, "dbname='postgres' port=5433", PG_VERSION_84, TEST_PATH "/pg8", NULL, NULL),
HRNPQ_MACRO_OPEN_LE_91(1, "dbname='postgres' port=5432", PG_VERSION_90, TEST_PATH "/pg1", NULL, NULL),
HRNPQ_MACRO_OPEN_LE_91(8, "dbname='postgres' port=5433", PG_VERSION_90, TEST_PATH "/pg8", NULL, NULL),
HRNPQ_MACRO_CLOSE(1),
HRNPQ_MACRO_CLOSE(8),

View File

@ -45,24 +45,6 @@ testRun(void)
"backup-timestamp-stop=0\n" \
"backup-type=\"full\"\n"
#define TEST_MANIFEST_DB_83 \
"\n" \
"[backup:db]\n" \
"db-catalog-version=200711281\n" \
"db-control-version=833\n" \
"db-id=0\n" \
"db-system-id=0\n" \
"db-version=\"8.3\"\n"
#define TEST_MANIFEST_DB_84 \
"\n" \
"[backup:db]\n" \
"db-catalog-version=200904091\n" \
"db-control-version=843\n" \
"db-id=0\n" \
"db-system-id=0\n" \
"db-version=\"8.4\"\n"
#define TEST_MANIFEST_DB_90 \
"\n" \
"[backup:db]\n" \
@ -187,10 +169,50 @@ testRun(void)
Storage *storagePgWrite = storagePosixNewP(STRDEF(TEST_PATH "/pg"), .write = true);
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("8.3 with custom exclusions and special file");
TEST_TITLE("manifest with all features - 9.0");
// Version
HRN_STORAGE_PUT_Z(storagePgWrite, PG_FILE_PGVERSION, "8.3\n", .modeFile = 0600, .timeModified = 1565282100);
HRN_STORAGE_PUT_Z(storagePgWrite, PG_FILE_PGVERSION, "9.0\n", .modeFile = 0600, .timeModified = 1565282100);
// base/1 directory
HRN_STORAGE_PATH_CREATE(storagePgWrite, PG_PATH_BASE, .mode = 0700);
HRN_STORAGE_PATH_CREATE(storagePgWrite, PG_PATH_BASE "/1", .mode = 0700);
// Temp relations to ignore
HRN_STORAGE_PUT_EMPTY(storagePgWrite, PG_PATH_BASE "/1/t1_1", .modeFile = 0600, .timeModified = 1565282113);
HRN_STORAGE_PUT_EMPTY(storagePgWrite, PG_PATH_BASE "/1/t1_1.1", .modeFile = 0600, .timeModified = 1565282113);
HRN_STORAGE_PUT_EMPTY(storagePgWrite, PG_PATH_BASE "/1/t8888888_8888888_vm", .modeFile = 0600, .timeModified = 1565282113);
HRN_STORAGE_PUT_EMPTY(
storagePgWrite, PG_PATH_BASE "/1/t8888888_8888888_vm.999999", .modeFile = 0600, .timeModified = 1565282113);
// Unlogged relations (pgVersion > 9.1)
HRN_STORAGE_PUT_EMPTY(
storagePgWrite, PG_PATH_BASE "/1/555", .modeFile = 0600, .timeModified = 1565282114,
.comment = "skip file because there is an _init");
HRN_STORAGE_PUT_EMPTY(
storagePgWrite, PG_PATH_BASE "/1/555_fsm", .modeFile = 0600, .timeModified = 1565282114,
.comment = "skip file because there is an _init");
HRN_STORAGE_PUT_EMPTY(
storagePgWrite, PG_PATH_BASE "/1/555_vm.1", .modeFile = 0600, .timeModified = 1565282114,
.comment = "skip file because there is an _init");
HRN_STORAGE_PUT_EMPTY(
storagePgWrite, PG_PATH_BASE "/1/555_init", .modeFile = 0600, .timeModified = 1565282114,
.comment = "do not skip _init");
HRN_STORAGE_PUT_EMPTY(
storagePgWrite, PG_PATH_BASE "/1/555_init.1", .modeFile = 0600, .timeModified = 1565282114,
.comment = "do not skip _init with segment");
HRN_STORAGE_PUT_EMPTY(
storagePgWrite, PG_PATH_BASE "/1/555_vm.1_vm", .modeFile = 0600, .timeModified = 1565282114,
.comment = "do not skip files that do not have valid endings as we are not sure what they are");
// Config directory and file links
HRN_STORAGE_PATH_CREATE(storageTest, "config", .mode = 0700);
THROW_ON_SYS_ERROR(
symlink("../config/postgresql.conf", TEST_PATH "/pg/postgresql.conf") == -1, FileOpenError, "unable to create symlink");
HRN_STORAGE_PUT_Z(storageTest, "config/postgresql.conf", "POSTGRESQLCONF", .modeFile = 0600, .timeModified = 1565282116);
THROW_ON_SYS_ERROR(
symlink("../config/pg_hba.conf", TEST_PATH "/pg/pg_hba.conf") == -1, FileOpenError, "unable to create symlink");
HRN_STORAGE_PUT_Z(storageTest, "config/pg_hba.conf", "PGHBACONF", .modeFile = 0600, .timeModified = 1565282117);
// Create special file
HRN_SYSTEM_FMT("mkfifo -m 666 %s", TEST_PATH "/pg/testpipe");
@ -235,208 +257,12 @@ testRun(void)
storagePgWrite, PG_PATH_GLOBAL "/" PG_FILE_PGINTERNALINIT ".allow", .modeFile = 0600, .timeModified = 1565282114);
HRN_STORAGE_PUT_EMPTY(storagePgWrite, PG_PATH_GLOBAL "/t1_1", .modeFile = 0600, .timeModified = 1565282114);
// base/1 directory
HRN_STORAGE_PATH_CREATE(storagePgWrite, PG_PATH_BASE, .mode = 0700);
HRN_STORAGE_PATH_CREATE(storagePgWrite, PG_PATH_BASE "/1", .mode = 0700);
StringList *exclusionList = strLstNew();
strLstAddZ(exclusionList, PG_PATH_GLOBAL "/" PG_FILE_PGINTERNALINIT);
strLstAddZ(exclusionList, "bogus");
strLstAddZ(exclusionList, PG_PATH_BASE "/");
strLstAddZ(exclusionList, "bogus/");
Manifest *manifest = NULL;
TEST_ASSIGN(
manifest,
manifestNewBuild(storagePg, PG_VERSION_83, hrnPgCatalogVersion(PG_VERSION_83), false, false, exclusionList, NULL),
"build manifest");
Buffer *contentSave = bufNew(0);
TEST_RESULT_VOID(manifestSave(manifest, ioBufferWriteNew(contentSave)), "save manifest");
TEST_RESULT_STR(
strNewBuf(contentSave),
strNewBuf(harnessInfoChecksumZ(
TEST_MANIFEST_HEADER
TEST_MANIFEST_DB_83
TEST_MANIFEST_OPTION_ALL
"\n"
"[backup:target]\n"
"pg_data={\"path\":\"" TEST_PATH "/pg\",\"type\":\"path\"}\n"
"\n"
"[target:file]\n"
"pg_data/PG_VERSION={\"size\":4,\"timestamp\":1565282100}\n"
"pg_data/global/pg_internal.init.allow={\"mas""ter\":false,\"size\":0,\"timestamp\":1565282114}\n"
"pg_data/global/t1_1={\"mas""ter\":false,\"size\":0,\"timestamp\":1565282114}\n"
"pg_data/pg_dynshmem/BOGUS={\"size\":0,\"timestamp\":1565282101}\n"
"pg_data/pg_notify/BOGUS={\"size\":0,\"timestamp\":1565282102}\n"
"pg_data/pg_replslot/BOGUS={\"size\":0,\"timestamp\":1565282103}\n"
"pg_data/pg_serial/BOGUS={\"size\":0,\"timestamp\":1565282104}\n"
"pg_data/pg_snapshots/BOGUS={\"size\":4,\"timestamp\":1565282105}\n"
"pg_data/pg_stat_tmp/BOGUS={\"mode\":\"0640\",\"size\":0,\"timestamp\":1565282106}\n"
"pg_data/pg_xlog/BOGUS={\"size\":0,\"timestamp\":1565282108}\n"
"pg_data/pg_xlog/archive_status/BOGUS={\"size\":0,\"timestamp\":1565282108}\n"
TEST_MANIFEST_FILE_DEFAULT_PRIMARY_TRUE
"\n"
"[target:path]\n"
"pg_data={}\n"
"pg_data/base={}\n"
"pg_data/global={}\n"
"pg_data/pg_dynshmem={}\n"
"pg_data/pg_notify={}\n"
"pg_data/pg_replslot={}\n"
"pg_data/pg_serial={}\n"
"pg_data/pg_snapshots={}\n"
"pg_data/pg_stat_tmp={\"mode\":\"0750\"}\n"
"pg_data/pg_subtrans={}\n"
"pg_data/pg_xlog={}\n"
"pg_data/pg_xlog/archive_status={}\n"
TEST_MANIFEST_PATH_DEFAULT)),
"check manifest");
TEST_RESULT_LOG(
"P00 INFO: exclude contents of '" TEST_PATH "/pg/base' from backup using 'base/' exclusion\n"
"P00 INFO: exclude '" TEST_PATH "/pg/global/pg_internal.init' from backup using 'global/pg_internal.init' exclusion\n"
"P00 WARN: exclude special file '" TEST_PATH "/pg/testpipe' from backup");
TEST_RESULT_VOID(
storageRemoveP(storageTest, STRDEF(TEST_PATH "/pg/testpipe"), .errorOnMissing = true), "error if special file removed");
// Set up for manifestNewBuild tests
// -------------------------------------------------------------------------------------------------------------------------
// Temp relations to ignore
HRN_STORAGE_PUT_EMPTY(storagePgWrite, PG_PATH_BASE "/1/t1_1", .modeFile = 0600, .timeModified = 1565282113);
HRN_STORAGE_PUT_EMPTY(storagePgWrite, PG_PATH_BASE "/1/t1_1.1", .modeFile = 0600, .timeModified = 1565282113);
HRN_STORAGE_PUT_EMPTY(storagePgWrite, PG_PATH_BASE "/1/t8888888_8888888_vm", .modeFile = 0600, .timeModified = 1565282113);
HRN_STORAGE_PUT_EMPTY(
storagePgWrite, PG_PATH_BASE "/1/t8888888_8888888_vm.999999", .modeFile = 0600, .timeModified = 1565282113);
// Unlogged relations (pgVersion > 9.1)
HRN_STORAGE_PUT_EMPTY(
storagePgWrite, PG_PATH_BASE "/1/555", .modeFile = 0600, .timeModified = 1565282114,
.comment = "skip file because there is an _init");
HRN_STORAGE_PUT_EMPTY(
storagePgWrite, PG_PATH_BASE "/1/555_fsm", .modeFile = 0600, .timeModified = 1565282114,
.comment = "skip file because there is an _init");
HRN_STORAGE_PUT_EMPTY(
storagePgWrite, PG_PATH_BASE "/1/555_vm.1", .modeFile = 0600, .timeModified = 1565282114,
.comment = "skip file because there is an _init");
HRN_STORAGE_PUT_EMPTY(
storagePgWrite, PG_PATH_BASE "/1/555_init", .modeFile = 0600, .timeModified = 1565282114,
.comment = "do not skip _init");
HRN_STORAGE_PUT_EMPTY(
storagePgWrite, PG_PATH_BASE "/1/555_init.1", .modeFile = 0600, .timeModified = 1565282114,
.comment = "do not skip _init with segment");
HRN_STORAGE_PUT_EMPTY(
storagePgWrite, PG_PATH_BASE "/1/555_vm.1_vm", .modeFile = 0600, .timeModified = 1565282114,
.comment = "do not skip files that do not have valid endings as we are not sure what they are");
// Config directory and file links
HRN_STORAGE_PATH_CREATE(storageTest, "config", .mode = 0700);
THROW_ON_SYS_ERROR(
symlink("../config/postgresql.conf", TEST_PATH "/pg/postgresql.conf") == -1, FileOpenError, "unable to create symlink");
HRN_STORAGE_PUT_Z(storageTest, "config/postgresql.conf", "POSTGRESQLCONF", .modeFile = 0600, .timeModified = 1565282116);
THROW_ON_SYS_ERROR(
symlink("../config/pg_hba.conf", TEST_PATH "/pg/pg_hba.conf") == -1, FileOpenError, "unable to create symlink");
HRN_STORAGE_PUT_Z(storageTest, "config/pg_hba.conf", "PGHBACONF", .modeFile = 0600, .timeModified = 1565282117);
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("manifest with all features - 8.4, online");
// Version
HRN_STORAGE_PUT_Z(storagePgWrite, PG_FILE_PGVERSION, "8.4\n", .modeFile = 0600, .timeModified = 1565282100);
// Tablespace 1 (old tablespace dir format)
HRN_STORAGE_PATH_CREATE(storageTest, "ts/1", .mode = 0777);
HRN_STORAGE_PATH_CREATE(storageTest, "ts/1/1", .mode = 0700);
HRN_STORAGE_PATH_CREATE(storagePgWrite, MANIFEST_TARGET_PGTBLSPC, .mode = 0700);
THROW_ON_SYS_ERROR(symlink("../../ts/1", TEST_PATH "/pg/pg_tblspc/1") == -1, FileOpenError, "unable to create symlink");
HRN_STORAGE_PUT_Z(storagePgWrite, "pg_tblspc/1/1/16384", "TESTDATA", .modeFile = 0600, .timeModified = 1565282115);
HRN_STORAGE_PUT_Z(
storagePgWrite, "pg_tblspc/1/1/t123_123_fsm", "TEMP_RELATION", .modeFile = 0600, .timeModified = 1565282115);
// Test manifest - mode stored for shared cluster tablespace dir, pg_xlog contents ignored because online
TEST_ASSIGN(
manifest, manifestNewBuild(storagePg, PG_VERSION_84, hrnPgCatalogVersion(PG_VERSION_84), true, false, NULL, NULL),
"build manifest");
contentSave = bufNew(0);
TEST_RESULT_VOID(manifestSave(manifest, ioBufferWriteNew(contentSave)), "save manifest");
TEST_RESULT_STR(
strNewBuf(contentSave),
strNewBuf(harnessInfoChecksumZ(
TEST_MANIFEST_HEADER
TEST_MANIFEST_DB_84
TEST_MANIFEST_OPTION_ARCHIVE
TEST_MANIFEST_OPTION_CHECKSUM_PAGE_FALSE
TEST_MANIFEST_OPTION_ONLINE_TRUE
"\n"
"[backup:target]\n"
"pg_data={\"path\":\"" TEST_PATH "/pg\",\"type\":\"path\"}\n"
"pg_data/pg_hba.conf={\"file\":\"pg_hba.conf\",\"path\":\"../config\",\"type\":\"link\"}\n"
"pg_data/postgresql.conf={\"file\":\"postgresql.conf\",\"path\":\"../config\",\"type\":\"link\"}\n"
"pg_tblspc/1={\"path\":\"../../ts/1\",\"tablespace-id\":\"1\",\"tablespace-name\":\"ts1\",\"type\":\"link\"}\n"
"\n"
"[target:file]\n"
"pg_data/PG_VERSION={\"mas""ter\":true,\"size\":4,\"timestamp\":1565282100}\n"
"pg_data/base/1/555={\"size\":0,\"timestamp\":1565282114}\n"
"pg_data/base/1/555_fsm={\"size\":0,\"timestamp\":1565282114}\n"
"pg_data/base/1/555_init={\"size\":0,\"timestamp\":1565282114}\n"
"pg_data/base/1/555_init.1={\"size\":0,\"timestamp\":1565282114}\n"
"pg_data/base/1/555_vm.1={\"size\":0,\"timestamp\":1565282114}\n"
"pg_data/base/1/555_vm.1_vm={\"size\":0,\"timestamp\":1565282114}\n"
"pg_data/base/1/t1_1={\"size\":0,\"timestamp\":1565282113}\n"
"pg_data/base/1/t1_1.1={\"size\":0,\"timestamp\":1565282113}\n"
"pg_data/base/1/t8888888_8888888_vm={\"size\":0,\"timestamp\":1565282113}\n"
"pg_data/base/1/t8888888_8888888_vm.999999={\"size\":0,\"timestamp\":1565282113}\n"
"pg_data/global/pg_internal.init.allow={\"size\":0,\"timestamp\":1565282114}\n"
"pg_data/global/t1_1={\"size\":0,\"timestamp\":1565282114}\n"
"pg_data/pg_dynshmem/BOGUS={\"mas""ter\":true,\"size\":0,\"timestamp\":1565282101}\n"
"pg_data/pg_hba.conf={\"mas""ter\":true,\"size\":9,\"timestamp\":1565282117}\n"
"pg_data/pg_notify/BOGUS={\"mas""ter\":true,\"size\":0,\"timestamp\":1565282102}\n"
"pg_data/pg_replslot/BOGUS={\"mas""ter\":true,\"size\":0,\"timestamp\":1565282103}\n"
"pg_data/pg_serial/BOGUS={\"mas""ter\":true,\"size\":0,\"timestamp\":1565282104}\n"
"pg_data/pg_snapshots/BOGUS={\"mas""ter\":true,\"size\":4,\"timestamp\":1565282105}\n"
"pg_data/postgresql.conf={\"mas""ter\":true,\"size\":14,\"timestamp\":1565282116}\n"
"pg_tblspc/1/1/16384={\"size\":8,\"timestamp\":1565282115}\n"
"pg_tblspc/1/1/t123_123_fsm={\"size\":13,\"timestamp\":1565282115}\n"
TEST_MANIFEST_FILE_DEFAULT_PRIMARY_FALSE
"\n"
"[target:link]\n"
"pg_data/pg_hba.conf={\"destination\":\"../config/pg_hba.conf\"}\n"
"pg_data/pg_tblspc/1={\"destination\":\"../../ts/1\"}\n"
"pg_data/postgresql.conf={\"destination\":\"../config/postgresql.conf\"}\n"
TEST_MANIFEST_LINK_DEFAULT
"\n"
"[target:path]\n"
"pg_data={}\n"
"pg_data/base={}\n"
"pg_data/base/1={}\n"
"pg_data/global={}\n"
"pg_data/pg_dynshmem={}\n"
"pg_data/pg_notify={}\n"
"pg_data/pg_replslot={}\n"
"pg_data/pg_serial={}\n"
"pg_data/pg_snapshots={}\n"
"pg_data/pg_stat_tmp={\"mode\":\"0750\"}\n"
"pg_data/pg_subtrans={}\n"
"pg_data/pg_tblspc={}\n"
"pg_data/pg_xlog={}\n"
"pg_data/pg_xlog/archive_status={}\n"
"pg_tblspc={}\n"
"pg_tblspc/1={\"mode\":\"0777\"}\n"
"pg_tblspc/1/1={}\n"
TEST_MANIFEST_PATH_DEFAULT)),
"check manifest");
// Remove directory
HRN_STORAGE_PATH_REMOVE(storageTest, "ts/1/1", .recurse = true);
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("manifest with all features - 9.0");
// Version
HRN_STORAGE_PUT_Z(storagePgWrite, PG_FILE_PGVERSION, "9.0\n", .modeFile = 0600, .timeModified = 1565282100);
// Make 'pg_xlog/archive_status' a link (if other links in the pg_xlog dir (should not be), they will be followed and added
// when online but archive_status (and pg_xlog), whether a link of not, will will only be followed if offline)
HRN_STORAGE_PATH_REMOVE(storagePgWrite, "pg_xlog/archive_status", .recurse = true);
@ -449,6 +275,8 @@ testRun(void)
// Tablespace 1
HRN_STORAGE_PATH_CREATE(storageTest, "ts/1/PG_9.0_201008051/1", .mode = 0700);
HRN_STORAGE_PATH_CREATE(storagePgWrite, MANIFEST_TARGET_PGTBLSPC, .mode = 0700);
THROW_ON_SYS_ERROR(symlink("../../ts/1", TEST_PATH "/pg/pg_tblspc/1") == -1, FileOpenError, "unable to create symlink");
HRN_STORAGE_PUT_Z(
storagePgWrite,"pg_tblspc/1/PG_9.0_201008051/1/16384", "TESTDATA", .modeFile = 0600, .timeModified = 1565282115);
HRN_STORAGE_PUT_Z(
@ -464,7 +292,8 @@ testRun(void)
// Test tablespace error
TEST_ERROR(
manifestNewBuild(storagePg, PG_VERSION_90, hrnPgCatalogVersion(PG_VERSION_90), false, false, NULL, tablespaceList),
manifestNewBuild(
storagePg, PG_VERSION_90, hrnPgCatalogVersion(PG_VERSION_90), false, false, exclusionList, tablespaceList),
AssertError,
"tablespace with oid 1 not found in tablespace map\n"
"HINT: was a tablespace created or dropped during the backup?");
@ -476,12 +305,15 @@ testRun(void)
varLstAdd(tablespaceList, varNewVarLst(tablespace));
// Test manifest - temp tables and pg_notify files ignored
Manifest *manifest = NULL;
TEST_ASSIGN(
manifest,
manifestNewBuild(storagePg, PG_VERSION_90, hrnPgCatalogVersion(PG_VERSION_90), false, false, NULL, tablespaceList),
"build manifest");
contentSave = bufNew(0);
Buffer *contentSave = bufNew(0);
TEST_RESULT_VOID(manifestSave(manifest, ioBufferWriteNew(contentSave)), "save manifest");
TEST_RESULT_STR(
strNewBuf(contentSave),
@ -546,6 +378,15 @@ testRun(void)
TEST_MANIFEST_PATH_DEFAULT)),
"check manifest");
TEST_RESULT_LOG(
"P00 INFO: exclude contents of '" TEST_PATH "/pg/base' from backup using 'base/' exclusion\n"
"P00 INFO: exclude '" TEST_PATH "/pg/global/pg_internal.init' from backup using 'global/pg_internal.init' exclusion\n"
"P00 WARN: exclude special file '" TEST_PATH "/pg/testpipe' from backup");
// Remove special file
TEST_RESULT_VOID(
storageRemoveP(storageTest, STRDEF(TEST_PATH "/pg/testpipe"), .errorOnMissing = true), "error if special file removed");
// Remove symlinks and directories
THROW_ON_SYS_ERROR(unlink(TEST_PATH "/pg/pg_tblspc/1") == -1, FileRemoveError, "unable to remove symlink");
HRN_STORAGE_PATH_REMOVE(storageTest,"ts/1/PG_9.0_201008051", .recurse = true);
@ -1067,8 +908,6 @@ testRun(void)
LinkDestinationError, "link '" TEST_PATH "/pg/linktolink' cannot reference another link '" TEST_PATH "/linktest'");
#undef TEST_MANIFEST_HEADER
#undef TEST_MANIFEST_DB_83
#undef TEST_MANIFEST_DB_84
#undef TEST_MANIFEST_DB_90
#undef TEST_MANIFEST_DB_91
#undef TEST_MANIFEST_DB_92

View File

@ -28,14 +28,14 @@ testRun(void)
//--------------------------------------------------------------------------------------------------------------------------
TEST_RESULT_STR_Z(pgVersionToStr(PG_VERSION_11), "11", "infoPgVersionToString 11");
TEST_RESULT_STR_Z(pgVersionToStr(PG_VERSION_96), "9.6", "infoPgVersionToString 9.6");
TEST_RESULT_STR_Z(pgVersionToStr(83456), "8.34", "infoPgVersionToString 83456");
TEST_RESULT_STR_Z(pgVersionToStr(93456), "9.34", "infoPgVersionToString 93456");
}
// *****************************************************************************************************************************
if (testBegin("pgControlVersion()"))
{
TEST_ERROR(pgControlVersion(70300), AssertError, "invalid PostgreSQL version 70300");
TEST_RESULT_UINT(pgControlVersion(PG_VERSION_83), 833, "8.3 control version");
TEST_RESULT_UINT(pgControlVersion(PG_VERSION_90), 903, "9.0 control version");
TEST_RESULT_UINT(pgControlVersion(PG_VERSION_11), 1100, "11 control version");
}
@ -88,13 +88,13 @@ testRun(void)
//--------------------------------------------------------------------------------------------------------------------------
HRN_PG_CONTROL_PUT(
storageTest, PG_VERSION_83, .systemId = 0xEFEFEFEFEF, .catalogVersion = hrnPgCatalogVersion(PG_VERSION_83),
storageTest, PG_VERSION_90, .systemId = 0xEFEFEFEFEF, .catalogVersion = hrnPgCatalogVersion(PG_VERSION_90),
.checkpoint = 0xAABBAABBEEFFEEFF, .timeline = 88);
TEST_ASSIGN(info, pgControlFromFile(storageTest), "get control info v83");
TEST_ASSIGN(info, pgControlFromFile(storageTest), "get control info v90");
TEST_RESULT_UINT(info.systemId, 0xEFEFEFEFEF, " check system id");
TEST_RESULT_UINT(info.version, PG_VERSION_83, " check version");
TEST_RESULT_UINT(info.catalogVersion, 200711281, " check catalog version");
TEST_RESULT_UINT(info.version, PG_VERSION_90, " check version");
TEST_RESULT_UINT(info.catalogVersion, 201008051, " check catalog version");
TEST_RESULT_UINT(info.checkpoint, 0xAABBAABBEEFFEEFF, "check checkpoint");
TEST_RESULT_UINT(info.timeline, 88, "check timeline");
}
@ -157,7 +157,6 @@ testRun(void)
TEST_RESULT_STR_Z(pgLsnName(PG_VERSION_96), "location", "check location name");
TEST_RESULT_STR_Z(pgLsnName(PG_VERSION_10), "lsn", "check lsn name");
TEST_RESULT_STR_Z(pgTablespaceId(PG_VERSION_84, 200904091), NULL, "check 8.4 tablespace id");
TEST_RESULT_STR_Z(pgTablespaceId(PG_VERSION_90, 201008051), "PG_9.0_201008051", "check 9.0 tablespace id");
TEST_RESULT_STR_Z(pgTablespaceId(PG_VERSION_94, 999999999), "PG_9.4_999999999", "check 9.4 tablespace id");
@ -220,18 +219,18 @@ testRun(void)
//--------------------------------------------------------------------------------------------------------------------------
memset(bufPtr(result), 0, bufSize(result));
hrnPgWalToBuffer(
(PgWal){.version = PG_VERSION_83, .systemId = 0xEAEAEAEA, .size = PG_WAL_SEGMENT_SIZE_DEFAULT * 2}, result);
(PgWal){.version = PG_VERSION_90, .systemId = 0xEAEAEAEA, .size = PG_WAL_SEGMENT_SIZE_DEFAULT * 2}, result);
TEST_ERROR(pgWalFromBuffer(result), FormatError, "wal segment size is 33554432 but must be 16777216 for PostgreSQL <= 10");
//--------------------------------------------------------------------------------------------------------------------------
memset(bufPtr(result), 0, bufSize(result));
hrnPgWalToBuffer((PgWal){.version = PG_VERSION_83, .systemId = 0xEAEAEAEA, .size = PG_WAL_SEGMENT_SIZE_DEFAULT}, result);
hrnPgWalToBuffer((PgWal){.version = PG_VERSION_90, .systemId = 0xEAEAEAEA, .size = PG_WAL_SEGMENT_SIZE_DEFAULT}, result);
storagePutP(storageNewWriteP(storageTest, walFile), result);
TEST_ASSIGN(info, pgWalFromFile(walFile, storageTest), "get wal info v8.3");
TEST_ASSIGN(info, pgWalFromFile(walFile, storageTest), "get wal info v9.0");
TEST_RESULT_UINT(info.systemId, 0xEAEAEAEA, " check system id");
TEST_RESULT_UINT(info.version, PG_VERSION_83, " check version");
TEST_RESULT_UINT(info.version, PG_VERSION_90, " check version");
TEST_RESULT_UINT(info.size, PG_WAL_SEGMENT_SIZE_DEFAULT, " check size");
}