1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-12 10:04:14 +02:00

Add archive-mode-check option.

This option disallows the PostgreSQL archive_mode=always setting and disabling it allows the setting.
This commit is contained in:
Stefan Fercot 2021-02-02 19:43:14 +01:00 committed by GitHub
parent 101bf5d114
commit 4b46115345
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 142 additions and 3 deletions

View File

@ -294,6 +294,7 @@ use constant CFGOPT_ARCHIVE_PUSH_QUEUE_MAX => 'archive-
#-----------------------------------------------------------------------------------------------------------------------------------
use constant CFGOPT_ARCHIVE_CHECK => 'archive-check';
use constant CFGOPT_ARCHIVE_COPY => 'archive-copy';
use constant CFGOPT_ARCHIVE_MODE_CHECK => 'archive-mode-check';
use constant CFGOPT_BACKUP_STANDBY => 'backup-standby';
use constant CFGOPT_CHECKSUM_PAGE => 'checksum-page';
use constant CFGOPT_EXCLUDE => 'exclude';
@ -2841,6 +2842,27 @@ my %hConfigDefine =
},
},
&CFGOPT_ARCHIVE_MODE_CHECK =>
{
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,
&CFGDEF_TYPE => CFGDEF_TYPE_BOOLEAN,
&CFGDEF_DEFAULT => true,
&CFGDEF_COMMAND =>
{
&CFGCMD_BACKUP => {},
&CFGCMD_CHECK => {},
},
&CFGDEF_DEPEND =>
{
&CFGDEF_DEPEND_OPTION => CFGOPT_ARCHIVE_CHECK,
&CFGDEF_DEPEND_LIST => [true],
},
&CFGDEF_COMMAND_ROLE =>
{
&CFGCMD_ROLE_DEFAULT => {},
},
},
&CFGOPT_BACKUP_STANDBY =>
{
&CFGDEF_SECTION => CFGDEF_SECTION_GLOBAL,

View File

@ -744,6 +744,19 @@
<example>y</example>
</config-key>
<!-- ======================================================================================================= -->
<config-key id="archive-mode-check" name="Check Archive Mode">
<summary>Check the <postgres/> <setting>archive_mode</setting> setting.</summary>
<text>Enabled by default, this option disallows <postgres/> <setting>archive_mode=always</setting>.
WAL segments pushed from a standby server might be logically the same as WAL segments pushed from the primary but have different checksums. Disabling archiving from multiple sources is recommended to avoid conflicts.
<admonition type="caution">If this option is disabled then it is critical to ensure that only one archiver is writing to the repository via the <cmd>archive-push</cmd> command.</admonition></text>
<example>n</example>
</config-key>
<!-- CONFIG - BACKUP SECTION - BACKUP-STANDBY KEY -->
<config-key id="backup-standby" name="Backup from Standby">
<summary>Backup from the standby cluster.</summary>

View File

@ -25,6 +25,19 @@
</release-item>
</release-bug-list>
<release-feature-list>
<release-item>
<release-item-contributor-list>
<release-item-contributor id="stefan.fercot"/>
<release-item-reviewer id="david.steele"/>
<!-- Actually tester, but we don't have a tag for that yet -->
<release-item-reviewer id="michael.banck"/>
</release-item-contributor-list>
<p>Add <br-setting>archive-mode-check</br-setting> option.</p>
</release-item>
</release-feature-list>
<release-improvement-list>
<release-item>
<release-item-contributor-list>
@ -9375,6 +9388,11 @@
<contributor-id type="github">mibiio</contributor-id>
</contributor>
<contributor id="michael.banck">
<contributor-name-display>Michael Banck</contributor-name-display>
<contributor-id type="github">mbanck</contributor-id>
</contributor>
<contributor id="michael.paquier">
<contributor-name-display>Michael Paquier</contributor-name-display>
<contributor-id type="github">michaelpq</contributor-id>

View File

@ -78,8 +78,8 @@ checkDbConfig(const unsigned int pgVersion, const unsigned int pgIdx, const Db *
THROW(ArchiveDisabledError, "archive_mode must be enabled");
}
// Error if archive_mode = always (support has not been added yet)
if (strCmpZ(dbArchiveMode(dbObject), "always") == 0)
// Error if archive_mode = always unless check is disabled (support has not been added yet)
if (cfgOptionBool(cfgOptArchiveModeCheck) && strCmpZ(dbArchiveMode(dbObject), "always") == 0)
{
THROW(FeatureNotSupportedError, "archive_mode=always not supported");
}

View File

@ -652,6 +652,39 @@ static const unsigned char helpDataPack[] =
0x20, 0x6E, 0x6F, 0x74, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6C, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x6F, 0x6E, 0x20, 0x50, 0x6F,
0x73, 0x74, 0x67, 0x72, 0x65, 0x53, 0x51, 0x4C, 0x20, 0x3C, 0x20, 0x31, 0x32, 0x2E,
// archive-mode-check option
// -------------------------------------------------------------------------------------------------------------------------
pckTypeStr << 4 | 0x0B, 0x06, // Section
0x62, 0x61, 0x63, 0x6B, 0x75, 0x70,
pckTypeStr << 4 | 0x08, 0x2A, // Summary
0x43, 0x68, 0x65, 0x63, 0x6B, 0x20, 0x74, 0x68, 0x65, 0x20, 0x50, 0x6F, 0x73, 0x74, 0x67, 0x72, 0x65, 0x53, 0x51, 0x4C,
0x20, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x5F, 0x6D, 0x6F, 0x64, 0x65, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E,
0x67, 0x2E,
pckTypeStr << 4 | 0x08, 0xB9, 0x03, // Description
0x45, 0x6E, 0x61, 0x62, 0x6C, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x2C, 0x20,
0x74, 0x68, 0x69, 0x73, 0x20, 0x6F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x64, 0x69, 0x73, 0x61, 0x6C, 0x6C, 0x6F, 0x77,
0x73, 0x20, 0x50, 0x6F, 0x73, 0x74, 0x67, 0x72, 0x65, 0x53, 0x51, 0x4C, 0x20, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65,
0x5F, 0x6D, 0x6F, 0x64, 0x65, 0x3D, 0x61, 0x6C, 0x77, 0x61, 0x79, 0x73, 0x2E, 0x0A, 0x0A,
0x57, 0x41, 0x4C, 0x20, 0x73, 0x65, 0x67, 0x6D, 0x65, 0x6E, 0x74, 0x73, 0x20, 0x70, 0x75, 0x73, 0x68, 0x65, 0x64, 0x20,
0x66, 0x72, 0x6F, 0x6D, 0x20, 0x61, 0x20, 0x73, 0x74, 0x61, 0x6E, 0x64, 0x62, 0x79, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65,
0x72, 0x20, 0x6D, 0x69, 0x67, 0x68, 0x74, 0x20, 0x62, 0x65, 0x20, 0x6C, 0x6F, 0x67, 0x69, 0x63, 0x61, 0x6C, 0x6C, 0x79,
0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6D, 0x65, 0x20, 0x61, 0x73, 0x20, 0x57, 0x41, 0x4C, 0x20, 0x73, 0x65, 0x67,
0x6D, 0x65, 0x6E, 0x74, 0x73, 0x20, 0x70, 0x75, 0x73, 0x68, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6F, 0x6D, 0x20, 0x74, 0x68,
0x65, 0x20, 0x70, 0x72, 0x69, 0x6D, 0x61, 0x72, 0x79, 0x20, 0x62, 0x75, 0x74, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x64,
0x69, 0x66, 0x66, 0x65, 0x72, 0x65, 0x6E, 0x74, 0x20, 0x63, 0x68, 0x65, 0x63, 0x6B, 0x73, 0x75, 0x6D, 0x73, 0x2E, 0x20,
0x44, 0x69, 0x73, 0x61, 0x62, 0x6C, 0x69, 0x6E, 0x67, 0x20, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x69, 0x6E, 0x67, 0x20,
0x66, 0x72, 0x6F, 0x6D, 0x20, 0x6D, 0x75, 0x6C, 0x74, 0x69, 0x70, 0x6C, 0x65, 0x20, 0x73, 0x6F, 0x75, 0x72, 0x63, 0x65,
0x73, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x63, 0x6F, 0x6D, 0x6D, 0x65, 0x6E, 0x64, 0x65, 0x64, 0x20, 0x74, 0x6F, 0x20,
0x61, 0x76, 0x6F, 0x69, 0x64, 0x20, 0x63, 0x6F, 0x6E, 0x66, 0x6C, 0x69, 0x63, 0x74, 0x73, 0x2E, 0x0A, 0x0A, 0x0A,
0x43, 0x41, 0x55, 0x54, 0x49, 0x4F, 0x4E, 0x3A, 0x20, 0x49, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6F, 0x70, 0x74,
0x69, 0x6F, 0x6E, 0x20, 0x69, 0x73, 0x20, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6C, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6E,
0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6C, 0x20, 0x74, 0x6F, 0x20, 0x65,
0x6E, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x6F, 0x6E, 0x6C, 0x79, 0x20, 0x6F, 0x6E, 0x65, 0x20,
0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x20, 0x69, 0x73, 0x20, 0x77, 0x72, 0x69, 0x74, 0x69, 0x6E, 0x67, 0x20,
0x74, 0x6F, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x6F, 0x72, 0x79, 0x20, 0x76, 0x69,
0x61, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2D, 0x70, 0x75, 0x73, 0x68, 0x20, 0x63,
0x6F, 0x6D, 0x6D, 0x61, 0x6E, 0x64, 0x2E,
// archive-push-queue-max option
// -------------------------------------------------------------------------------------------------------------------------
pckTypeStr << 4 | 0x0B, 0x07, // Section

View File

@ -262,6 +262,7 @@ STRING_EXTERN(CFGOPT_ARCHIVE_CHECK_STR, CFGOPT_ARCHI
STRING_EXTERN(CFGOPT_ARCHIVE_COPY_STR, CFGOPT_ARCHIVE_COPY);
STRING_EXTERN(CFGOPT_ARCHIVE_GET_QUEUE_MAX_STR, CFGOPT_ARCHIVE_GET_QUEUE_MAX);
STRING_EXTERN(CFGOPT_ARCHIVE_MODE_STR, CFGOPT_ARCHIVE_MODE);
STRING_EXTERN(CFGOPT_ARCHIVE_MODE_CHECK_STR, CFGOPT_ARCHIVE_MODE_CHECK);
STRING_EXTERN(CFGOPT_ARCHIVE_PUSH_QUEUE_MAX_STR, CFGOPT_ARCHIVE_PUSH_QUEUE_MAX);
STRING_EXTERN(CFGOPT_ARCHIVE_TIMEOUT_STR, CFGOPT_ARCHIVE_TIMEOUT);
STRING_EXTERN(CFGOPT_BACKUP_STANDBY_STR, CFGOPT_BACKUP_STANDBY);

View File

@ -70,6 +70,8 @@ Option constants
STRING_DECLARE(CFGOPT_ARCHIVE_GET_QUEUE_MAX_STR);
#define CFGOPT_ARCHIVE_MODE "archive-mode"
STRING_DECLARE(CFGOPT_ARCHIVE_MODE_STR);
#define CFGOPT_ARCHIVE_MODE_CHECK "archive-mode-check"
STRING_DECLARE(CFGOPT_ARCHIVE_MODE_CHECK_STR);
#define CFGOPT_ARCHIVE_PUSH_QUEUE_MAX "archive-push-queue-max"
STRING_DECLARE(CFGOPT_ARCHIVE_PUSH_QUEUE_MAX_STR);
#define CFGOPT_ARCHIVE_TIMEOUT "archive-timeout"
@ -207,7 +209,7 @@ Option constants
#define CFGOPT_TYPE "type"
STRING_DECLARE(CFGOPT_TYPE_STR);
#define CFG_OPTION_TOTAL 128
#define CFG_OPTION_TOTAL 129
/***********************************************************************************************************************************
Command enum
@ -256,6 +258,7 @@ typedef enum
cfgOptArchiveCopy,
cfgOptArchiveGetQueueMax,
cfgOptArchiveMode,
cfgOptArchiveModeCheck,
cfgOptArchivePushQueueMax,
cfgOptArchiveTimeout,
cfgOptBackupStandby,

View File

@ -431,6 +431,32 @@ static const ParseRuleOption parseRuleOption[CFG_OPTION_TOTAL] =
),
),
// -----------------------------------------------------------------------------------------------------------------------------
PARSE_RULE_OPTION
(
PARSE_RULE_OPTION_NAME("archive-mode-check"),
PARSE_RULE_OPTION_TYPE(cfgOptTypeBoolean),
PARSE_RULE_OPTION_REQUIRED(true),
PARSE_RULE_OPTION_SECTION(cfgSectionGlobal),
PARSE_RULE_OPTION_COMMAND_ROLE_DEFAULT_VALID_LIST
(
PARSE_RULE_OPTION_COMMAND(cfgCmdBackup)
PARSE_RULE_OPTION_COMMAND(cfgCmdCheck)
),
PARSE_RULE_OPTION_OPTIONAL_LIST
(
PARSE_RULE_OPTION_OPTIONAL_DEPEND_LIST
(
cfgOptArchiveCheck,
"1"
),
PARSE_RULE_OPTION_OPTIONAL_DEFAULT("1"),
),
),
// -----------------------------------------------------------------------------------------------------------------------------
PARSE_RULE_OPTION
(
@ -6479,6 +6505,21 @@ static const struct option optionList[] =
.val = PARSE_OPTION_FLAG | PARSE_RESET_FLAG | cfgOptArchiveMode,
},
// archive-mode-check option
// -----------------------------------------------------------------------------------------------------------------------------
{
.name = "archive-mode-check",
.val = PARSE_OPTION_FLAG | cfgOptArchiveModeCheck,
},
{
.name = "no-archive-mode-check",
.val = PARSE_OPTION_FLAG | PARSE_NEGATE_FLAG | cfgOptArchiveModeCheck,
},
{
.name = "reset-archive-mode-check",
.val = PARSE_OPTION_FLAG | PARSE_RESET_FLAG | cfgOptArchiveModeCheck,
},
// archive-push-queue-max option and deprecations
// -----------------------------------------------------------------------------------------------------------------------------
{
@ -10513,6 +10554,7 @@ static const ConfigOption optionResolveOrder[] =
cfgOptType,
cfgOptArchiveCheck,
cfgOptArchiveCopy,
cfgOptArchiveModeCheck,
cfgOptForce,
cfgOptPgDatabase,
cfgOptPgHost,

View File

@ -465,6 +465,13 @@ testRun(void)
checkDbConfig(PG_VERSION_92, db.primaryIdx, db.primary, false), FeatureNotSupportedError,
"archive_mode=always not supported");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("disable archive_mode=always check");
strLstAddZ(argList, "--no-archive-mode-check");
harnessCfgLoad(cfgCmdCheck, argList);
TEST_RESULT_VOID(checkDbConfig(PG_VERSION_92, db.primaryIdx, db.primary, false), "check");
TEST_RESULT_VOID(dbFree(db.primary), "free primary");
}