mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-01-30 05:39:12 +02:00
Add --dry-run option to the expire command.
Use dry-run to see which backups/archive would be removed by the expire command without actually removing anything.
This commit is contained in:
parent
4608ca473e
commit
2fa69af8da
@ -128,6 +128,8 @@ use constant CFGOPT_CONFIG_INCLUDE_PATH => 'config-i
|
||||
push @EXPORT, qw(CFGOPT_CONFIG_INCLUDE_PATH);
|
||||
use constant CFGOPT_DELTA => 'delta';
|
||||
push @EXPORT, qw(CFGOPT_DELTA);
|
||||
use constant CFGOPT_DRYRUN => 'dry-run';
|
||||
push @EXPORT, qw(CFGOPT_DRYRUN);
|
||||
use constant CFGOPT_FORCE => 'force';
|
||||
push @EXPORT, qw(CFGOPT_FORCE);
|
||||
use constant CFGOPT_ONLINE => 'online';
|
||||
@ -760,6 +762,16 @@ my %hConfigDefine =
|
||||
&CFGDEF_NEGATE => false,
|
||||
},
|
||||
|
||||
&CFGOPT_DRYRUN =>
|
||||
{
|
||||
&CFGDEF_TYPE => CFGDEF_TYPE_BOOLEAN,
|
||||
&CFGDEF_DEFAULT => false,
|
||||
&CFGDEF_COMMAND =>
|
||||
{
|
||||
&CFGCMD_EXPIRE => {},
|
||||
},
|
||||
},
|
||||
|
||||
&CFGOPT_FORCE =>
|
||||
{
|
||||
&CFGDEF_TYPE => CFGDEF_TYPE_BOOLEAN,
|
||||
|
@ -935,6 +935,15 @@
|
||||
<example>/conf/pgbackrest</example>
|
||||
</option>
|
||||
|
||||
<!-- OPERATION - GENERAL - DRY-RUN OPTION -->
|
||||
<option id="dry-run" name="Dry Run">
|
||||
<summary>Execute a dry-run for the command.</summary>
|
||||
|
||||
<text>The <br-option>{[dash]}-dry-run</br-option> option is a command-line only option and can be passed when it is desireable to determine what modifications will be made by the command without the command actually making any modifications.</text>
|
||||
|
||||
<example>y</example>
|
||||
</option>
|
||||
|
||||
<!-- OPERATION - GENERAL - RAW -->
|
||||
<option id="raw" name="Raw Data">
|
||||
<summary>Do not transform data.</summary>
|
||||
|
@ -24,6 +24,17 @@
|
||||
|
||||
<p>Note that setting <br-option>compress-type=lz4</br-option> will make new backups and archive incompatible (unrestorable) with prior versions of <backrest/>.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<release-item-contributor-list>
|
||||
<release-item-contributor id="cynthia.shang"/>
|
||||
<release-item-contributor id="luca.ferrari"/>
|
||||
</release-item-contributor-list>
|
||||
|
||||
<p>Add <br-option>--dry-run</br-option> option to the <cmd>expire</cmd> command.</p>
|
||||
|
||||
<p>Use dry-run to see which backups/archive would be removed by the <cmd>expire</cmd> command without actually removing anything.</p>
|
||||
</release-item>
|
||||
</release-feature-list>
|
||||
|
||||
<release-improvement-list>
|
||||
|
@ -1539,7 +1539,7 @@
|
||||
|
||||
<p>Although <backrest/> automatically removes archived WAL segments when expiring backups (the default expires WAL for full backups based on the <br-option>repo1-retention-full</br-option> option), it may be useful to expire archive more aggressively to save disk space. Note that full backups are treated as differential backups for the purpose of differential archive retention.</p>
|
||||
|
||||
<p>Expiring archive will never remove WAL segments that are required to make a backup consistent. However, since Point-in-Time-Recovery (PITR) only works on a continuous WAL stream, care should be taken when aggressively expiring archive outside of the normal backup expiration process.</p>
|
||||
<p>Expiring archive will never remove WAL segments that are required to make a backup consistent. However, since Point-in-Time-Recovery (PITR) only works on a continuous WAL stream, care should be taken when aggressively expiring archive outside of the normal backup expiration process. To determine what will be expired without actually expiring anything, the <br-option>dry-run</br-option> option can be provided on the command line with the <cmd>expire</cmd> command.</p>
|
||||
|
||||
<backrest-config host="{[host-pg1]}" file="{[backrest-config-demo]}">
|
||||
<title>Configure <br-option>repo1-retention-diff</br-option></title>
|
||||
|
@ -59,9 +59,14 @@ expireBackup(InfoBackup *infoBackup, String *removeBackupLabel, String *backupEx
|
||||
ASSERT(removeBackupLabel != NULL);
|
||||
ASSERT(backupExpired != NULL);
|
||||
|
||||
storageRemoveP(storageRepoWrite(), strNewFmt(STORAGE_REPO_BACKUP "/%s/" BACKUP_MANIFEST_FILE, strPtr(removeBackupLabel)));
|
||||
storageRemoveP(
|
||||
storageRepoWrite(), strNewFmt(STORAGE_REPO_BACKUP "/%s/" BACKUP_MANIFEST_FILE INFO_COPY_EXT, strPtr(removeBackupLabel)));
|
||||
// Execute the real expiration and deletion only if the dry-run option is disabled
|
||||
if (!cfgOptionValid(cfgOptDryRun) || !cfgOptionBool(cfgOptDryRun))
|
||||
{
|
||||
storageRemoveP(storageRepoWrite(), strNewFmt(STORAGE_REPO_BACKUP "/%s/" BACKUP_MANIFEST_FILE, strPtr(removeBackupLabel)));
|
||||
storageRemoveP(
|
||||
storageRepoWrite(),
|
||||
strNewFmt(STORAGE_REPO_BACKUP "/%s/" BACKUP_MANIFEST_FILE INFO_COPY_EXT, strPtr(removeBackupLabel)));
|
||||
}
|
||||
|
||||
// Remove the backup from the info object
|
||||
infoBackupDataDelete(infoBackup, removeBackupLabel);
|
||||
@ -359,8 +364,12 @@ removeExpiredArchive(InfoBackup *infoBackup)
|
||||
{
|
||||
String *fullPath = storagePathP(
|
||||
storageRepo(), strNewFmt(STORAGE_REPO_ARCHIVE "/%s", strPtr(archiveId)));
|
||||
storagePathRemoveP(storageRepoWrite(), fullPath, .recurse = true);
|
||||
|
||||
LOG_INFO_FMT("remove archive path: %s", strPtr(fullPath));
|
||||
|
||||
// Execute the real expiration and deletion only if the dry-run option is disabled
|
||||
if (!cfgOptionValid(cfgOptDryRun) || !cfgOptionBool(cfgOptDryRun))
|
||||
storagePathRemoveP(storageRepoWrite(), fullPath, .recurse = true);
|
||||
}
|
||||
|
||||
// Continue to next directory
|
||||
@ -503,9 +512,14 @@ removeExpiredArchive(InfoBackup *infoBackup)
|
||||
// Remove the entire directory if all archive is expired
|
||||
if (removeArchive)
|
||||
{
|
||||
storagePathRemoveP(
|
||||
storageRepoWrite(), strNewFmt(STORAGE_REPO_ARCHIVE "/%s/%s", strPtr(archiveId),
|
||||
strPtr(walPath)), .recurse = true);
|
||||
// Execute the real expiration and deletion only if the dry-run mode is disabled
|
||||
if (!cfgOptionValid(cfgOptDryRun) || !cfgOptionBool(cfgOptDryRun))
|
||||
{
|
||||
storagePathRemoveP(
|
||||
storageRepoWrite(),
|
||||
strNewFmt(STORAGE_REPO_ARCHIVE "/%s/%s", strPtr(archiveId), strPtr(walPath)),
|
||||
.recurse = true);
|
||||
}
|
||||
|
||||
archiveExpire.total++;
|
||||
archiveExpire.start = strDup(walPath);
|
||||
@ -547,10 +561,15 @@ removeExpiredArchive(InfoBackup *infoBackup)
|
||||
// Remove archive log if it is not used in a backup
|
||||
if (removeArchive)
|
||||
{
|
||||
storageRemoveP(
|
||||
storageRepoWrite(),
|
||||
strNewFmt(STORAGE_REPO_ARCHIVE "/%s/%s/%s",
|
||||
strPtr(archiveId), strPtr(walPath), strPtr(walSubPath)));
|
||||
// Execute the real expiration and deletion only if the dry-run mode is disabled
|
||||
if (!cfgOptionValid(cfgOptDryRun) || !cfgOptionBool(cfgOptDryRun))
|
||||
{
|
||||
storageRemoveP(
|
||||
storageRepoWrite(),
|
||||
strNewFmt(
|
||||
STORAGE_REPO_ARCHIVE "/%s/%s/%s", strPtr(archiveId), strPtr(walPath),
|
||||
strPtr(walSubPath)));
|
||||
}
|
||||
|
||||
// Track that this archive was removed
|
||||
archiveExpire.total++;
|
||||
@ -610,9 +629,13 @@ removeExpiredBackup(InfoBackup *infoBackup)
|
||||
{
|
||||
LOG_INFO_FMT("remove expired backup %s", strPtr(strLstGet(backupList, backupIdx)));
|
||||
|
||||
storagePathRemoveP(
|
||||
storageRepoWrite(), strNewFmt(STORAGE_REPO_BACKUP "/%s", strPtr(strLstGet(backupList, backupIdx))),
|
||||
.recurse = true);
|
||||
// Execute the real expiration and deletion only if the dry-run mode is disabled
|
||||
if (!cfgOptionValid(cfgOptDryRun) || !cfgOptionBool(cfgOptDryRun))
|
||||
{
|
||||
storagePathRemoveP(
|
||||
storageRepoWrite(), strNewFmt(STORAGE_REPO_BACKUP "/%s", strPtr(strLstGet(backupList, backupIdx))),
|
||||
.recurse = true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -640,9 +663,13 @@ cmdExpire(void)
|
||||
expireFullBackup(infoBackup);
|
||||
expireDiffBackup(infoBackup);
|
||||
|
||||
infoBackupSaveFile(
|
||||
infoBackup, storageRepoWrite(), INFO_BACKUP_PATH_FILE_STR, cipherType(cfgOptionStr(cfgOptRepoCipherType)),
|
||||
cfgOptionStr(cfgOptRepoCipherPass));
|
||||
// Store the new backup info only if the dry-run mode is disabled
|
||||
if (!cfgOptionValid(cfgOptDryRun) || !cfgOptionBool(cfgOptDryRun))
|
||||
{
|
||||
infoBackupSaveFile(
|
||||
infoBackup, storageRepoWrite(), INFO_BACKUP_PATH_FILE_STR, cipherType(cfgOptionStr(cfgOptRepoCipherType)),
|
||||
cfgOptionStr(cfgOptRepoCipherPass));
|
||||
}
|
||||
|
||||
removeExpiredBackup(infoBackup);
|
||||
removeExpiredArchive(infoBackup);
|
||||
|
@ -304,6 +304,7 @@ STRING_EXTERN(CFGOPT_CONFIG_PATH_STR, CFGOPT_CONFI
|
||||
STRING_EXTERN(CFGOPT_DB_INCLUDE_STR, CFGOPT_DB_INCLUDE);
|
||||
STRING_EXTERN(CFGOPT_DB_TIMEOUT_STR, CFGOPT_DB_TIMEOUT);
|
||||
STRING_EXTERN(CFGOPT_DELTA_STR, CFGOPT_DELTA);
|
||||
STRING_EXTERN(CFGOPT_DRY_RUN_STR, CFGOPT_DRY_RUN);
|
||||
STRING_EXTERN(CFGOPT_EXCLUDE_STR, CFGOPT_EXCLUDE);
|
||||
STRING_EXTERN(CFGOPT_FILTER_STR, CFGOPT_FILTER);
|
||||
STRING_EXTERN(CFGOPT_FORCE_STR, CFGOPT_FORCE);
|
||||
@ -633,6 +634,14 @@ static ConfigOptionData configOptionData[CFG_OPTION_TOTAL] = CONFIG_OPTION_LIST
|
||||
CONFIG_OPTION_DEFINE_ID(cfgDefOptDelta)
|
||||
)
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
CONFIG_OPTION
|
||||
(
|
||||
CONFIG_OPTION_NAME(CFGOPT_DRY_RUN)
|
||||
CONFIG_OPTION_INDEX(0)
|
||||
CONFIG_OPTION_DEFINE_ID(cfgDefOptDryRun)
|
||||
)
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
CONFIG_OPTION
|
||||
(
|
||||
|
@ -95,6 +95,8 @@ Option constants
|
||||
STRING_DECLARE(CFGOPT_DB_TIMEOUT_STR);
|
||||
#define CFGOPT_DELTA "delta"
|
||||
STRING_DECLARE(CFGOPT_DELTA_STR);
|
||||
#define CFGOPT_DRY_RUN "dry-run"
|
||||
STRING_DECLARE(CFGOPT_DRY_RUN_STR);
|
||||
#define CFGOPT_EXCLUDE "exclude"
|
||||
STRING_DECLARE(CFGOPT_EXCLUDE_STR);
|
||||
#define CFGOPT_FILTER "filter"
|
||||
@ -406,7 +408,7 @@ Option constants
|
||||
#define CFGOPT_TYPE "type"
|
||||
STRING_DECLARE(CFGOPT_TYPE_STR);
|
||||
|
||||
#define CFG_OPTION_TOTAL 176
|
||||
#define CFG_OPTION_TOTAL 177
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Command enum
|
||||
@ -461,6 +463,7 @@ typedef enum
|
||||
cfgOptDbInclude,
|
||||
cfgOptDbTimeout,
|
||||
cfgOptDelta,
|
||||
cfgOptDryRun,
|
||||
cfgOptExclude,
|
||||
cfgOptFilter,
|
||||
cfgOptForce,
|
||||
|
@ -1108,6 +1108,37 @@ static ConfigDefineOptionData configDefineOptionData[] = CFGDEFDATA_OPTION_LIST
|
||||
)
|
||||
)
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
CFGDEFDATA_OPTION
|
||||
(
|
||||
CFGDEFDATA_OPTION_NAME("dry-run")
|
||||
CFGDEFDATA_OPTION_REQUIRED(true)
|
||||
CFGDEFDATA_OPTION_SECTION(cfgDefSectionCommandLine)
|
||||
CFGDEFDATA_OPTION_TYPE(cfgDefOptTypeBoolean)
|
||||
CFGDEFDATA_OPTION_INTERNAL(false)
|
||||
|
||||
CFGDEFDATA_OPTION_INDEX_TOTAL(1)
|
||||
CFGDEFDATA_OPTION_SECURE(false)
|
||||
|
||||
CFGDEFDATA_OPTION_HELP_SECTION("general")
|
||||
CFGDEFDATA_OPTION_HELP_SUMMARY("Execute a dry-run for the command.")
|
||||
CFGDEFDATA_OPTION_HELP_DESCRIPTION
|
||||
(
|
||||
"The --dry-run option is a command-line only option and can be passed when it is desireable to determine what "
|
||||
"modifications will be made by the command without the command actually making any modifications."
|
||||
)
|
||||
|
||||
CFGDEFDATA_OPTION_COMMAND_LIST
|
||||
(
|
||||
CFGDEFDATA_OPTION_COMMAND(cfgDefCmdExpire)
|
||||
)
|
||||
|
||||
CFGDEFDATA_OPTION_OPTIONAL_LIST
|
||||
(
|
||||
CFGDEFDATA_OPTION_OPTIONAL_DEFAULT("0")
|
||||
)
|
||||
)
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
CFGDEFDATA_OPTION
|
||||
(
|
||||
|
@ -73,6 +73,7 @@ typedef enum
|
||||
cfgDefOptDbInclude,
|
||||
cfgDefOptDbTimeout,
|
||||
cfgDefOptDelta,
|
||||
cfgDefOptDryRun,
|
||||
cfgDefOptExclude,
|
||||
cfgDefOptFilter,
|
||||
cfgDefOptForce,
|
||||
|
@ -279,6 +279,13 @@ static const struct option optionList[] =
|
||||
.val = PARSE_OPTION_FLAG | PARSE_RESET_FLAG | cfgOptDelta,
|
||||
},
|
||||
|
||||
// dry-run option
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
{
|
||||
.name = CFGOPT_DRY_RUN,
|
||||
.val = PARSE_OPTION_FLAG | cfgOptDryRun,
|
||||
},
|
||||
|
||||
// exclude option
|
||||
// -----------------------------------------------------------------------------------------------------------------------------
|
||||
{
|
||||
@ -2380,6 +2387,7 @@ static const ConfigOption optionResolveOrder[] =
|
||||
cfgOptDbInclude,
|
||||
cfgOptDbTimeout,
|
||||
cfgOptDelta,
|
||||
cfgOptDryRun,
|
||||
cfgOptExclude,
|
||||
cfgOptFilter,
|
||||
cfgOptHostId,
|
||||
|
354
test/lib/pgBackRestTest/LibCAuto.pm
Normal file
354
test/lib/pgBackRestTest/LibCAuto.pm
Normal file
@ -0,0 +1,354 @@
|
||||
####################################################################################################################################
|
||||
# Automatically generated by Build.pm -- do not modify directly.
|
||||
####################################################################################################################################
|
||||
package pgBackRest::LibCAuto;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
# Configuration option value constants
|
||||
sub libcAutoConstant
|
||||
{
|
||||
return
|
||||
{
|
||||
CFGOPTVAL_INFO_OUTPUT_TEXT => 'text',
|
||||
CFGOPTVAL_INFO_OUTPUT_JSON => 'json',
|
||||
|
||||
CFGOPTVAL_LS_OUTPUT_TEXT => 'text',
|
||||
CFGOPTVAL_LS_OUTPUT_JSON => 'json',
|
||||
|
||||
CFGOPTVAL_REMOTE_TYPE_PG => 'pg',
|
||||
CFGOPTVAL_REMOTE_TYPE_REPO => 'repo',
|
||||
|
||||
CFGOPTVAL_REPO_CIPHER_TYPE_NONE => 'none',
|
||||
CFGOPTVAL_REPO_CIPHER_TYPE_AES_256_CBC => 'aes-256-cbc',
|
||||
|
||||
CFGOPTVAL_REPO_RETENTION_ARCHIVE_TYPE_FULL => 'full',
|
||||
CFGOPTVAL_REPO_RETENTION_ARCHIVE_TYPE_DIFF => 'diff',
|
||||
CFGOPTVAL_REPO_RETENTION_ARCHIVE_TYPE_INCR => 'incr',
|
||||
|
||||
CFGOPTVAL_REPO_S3_URI_STYLE_HOST => 'host',
|
||||
CFGOPTVAL_REPO_S3_URI_STYLE_PATH => 'path',
|
||||
|
||||
CFGOPTVAL_REPO_TYPE_CIFS => 'cifs',
|
||||
CFGOPTVAL_REPO_TYPE_POSIX => 'posix',
|
||||
CFGOPTVAL_REPO_TYPE_S3 => 's3',
|
||||
|
||||
CFGOPTVAL_SORT_NONE => 'none',
|
||||
CFGOPTVAL_SORT_ASC => 'asc',
|
||||
CFGOPTVAL_SORT_DESC => 'desc',
|
||||
|
||||
CFGOPTVAL_RESTORE_TARGET_ACTION_PAUSE => 'pause',
|
||||
CFGOPTVAL_RESTORE_TARGET_ACTION_PROMOTE => 'promote',
|
||||
CFGOPTVAL_RESTORE_TARGET_ACTION_SHUTDOWN => 'shutdown',
|
||||
|
||||
CFGOPTVAL_BACKUP_TYPE_FULL => 'full',
|
||||
CFGOPTVAL_BACKUP_TYPE_DIFF => 'diff',
|
||||
CFGOPTVAL_BACKUP_TYPE_INCR => 'incr',
|
||||
|
||||
CFGOPTVAL_RESTORE_TYPE_NAME => 'name',
|
||||
CFGOPTVAL_RESTORE_TYPE_TIME => 'time',
|
||||
CFGOPTVAL_RESTORE_TYPE_XID => 'xid',
|
||||
CFGOPTVAL_RESTORE_TYPE_PRESERVE => 'preserve',
|
||||
CFGOPTVAL_RESTORE_TYPE_NONE => 'none',
|
||||
CFGOPTVAL_RESTORE_TYPE_IMMEDIATE => 'immediate',
|
||||
CFGOPTVAL_RESTORE_TYPE_DEFAULT => 'default',
|
||||
CFGOPTVAL_RESTORE_TYPE_STANDBY => 'standby',
|
||||
|
||||
CFGDEF_TYPE_BOOLEAN => 0,
|
||||
CFGDEF_TYPE_FLOAT => 1,
|
||||
CFGDEF_TYPE_HASH => 2,
|
||||
CFGDEF_TYPE_INTEGER => 3,
|
||||
CFGDEF_TYPE_LIST => 4,
|
||||
CFGDEF_TYPE_PATH => 5,
|
||||
CFGDEF_TYPE_SIZE => 6,
|
||||
CFGDEF_TYPE_STRING => 7,
|
||||
|
||||
ENCODE_TYPE_BASE64 => 0,
|
||||
|
||||
CIPHER_MODE_ENCRYPT => 0,
|
||||
CIPHER_MODE_DECRYPT => 1,
|
||||
}
|
||||
}
|
||||
|
||||
# Export function and constants
|
||||
sub libcAutoExportTag
|
||||
{
|
||||
return
|
||||
{
|
||||
checksum =>
|
||||
[
|
||||
'pageChecksum',
|
||||
],
|
||||
|
||||
config =>
|
||||
[
|
||||
'CFGOPTVAL_INFO_OUTPUT_TEXT',
|
||||
'CFGOPTVAL_INFO_OUTPUT_JSON',
|
||||
'CFGOPTVAL_LS_OUTPUT_TEXT',
|
||||
'CFGOPTVAL_LS_OUTPUT_JSON',
|
||||
'CFGOPTVAL_REMOTE_TYPE_PG',
|
||||
'CFGOPTVAL_REMOTE_TYPE_REPO',
|
||||
'CFGOPTVAL_REPO_CIPHER_TYPE_NONE',
|
||||
'CFGOPTVAL_REPO_CIPHER_TYPE_AES_256_CBC',
|
||||
'CFGOPTVAL_REPO_RETENTION_ARCHIVE_TYPE_FULL',
|
||||
'CFGOPTVAL_REPO_RETENTION_ARCHIVE_TYPE_DIFF',
|
||||
'CFGOPTVAL_REPO_RETENTION_ARCHIVE_TYPE_INCR',
|
||||
'CFGOPTVAL_REPO_S3_URI_STYLE_HOST',
|
||||
'CFGOPTVAL_REPO_S3_URI_STYLE_PATH',
|
||||
'CFGOPTVAL_REPO_TYPE_CIFS',
|
||||
'CFGOPTVAL_REPO_TYPE_POSIX',
|
||||
'CFGOPTVAL_REPO_TYPE_S3',
|
||||
'CFGOPTVAL_SORT_NONE',
|
||||
'CFGOPTVAL_SORT_ASC',
|
||||
'CFGOPTVAL_SORT_DESC',
|
||||
'CFGOPTVAL_RESTORE_TARGET_ACTION_PAUSE',
|
||||
'CFGOPTVAL_RESTORE_TARGET_ACTION_PROMOTE',
|
||||
'CFGOPTVAL_RESTORE_TARGET_ACTION_SHUTDOWN',
|
||||
'CFGOPTVAL_BACKUP_TYPE_FULL',
|
||||
'CFGOPTVAL_BACKUP_TYPE_DIFF',
|
||||
'CFGOPTVAL_BACKUP_TYPE_INCR',
|
||||
'CFGOPTVAL_RESTORE_TYPE_NAME',
|
||||
'CFGOPTVAL_RESTORE_TYPE_TIME',
|
||||
'CFGOPTVAL_RESTORE_TYPE_XID',
|
||||
'CFGOPTVAL_RESTORE_TYPE_PRESERVE',
|
||||
'CFGOPTVAL_RESTORE_TYPE_NONE',
|
||||
'CFGOPTVAL_RESTORE_TYPE_IMMEDIATE',
|
||||
'CFGOPTVAL_RESTORE_TYPE_DEFAULT',
|
||||
'CFGOPTVAL_RESTORE_TYPE_STANDBY',
|
||||
'CFGCMD_ARCHIVE_GET',
|
||||
'CFGCMD_ARCHIVE_PUSH',
|
||||
'CFGCMD_BACKUP',
|
||||
'CFGCMD_CHECK',
|
||||
'CFGCMD_EXPIRE',
|
||||
'CFGCMD_HELP',
|
||||
'CFGCMD_INFO',
|
||||
'CFGCMD_LS',
|
||||
'CFGCMD_RESTORE',
|
||||
'CFGCMD_STANZA_CREATE',
|
||||
'CFGCMD_STANZA_DELETE',
|
||||
'CFGCMD_STANZA_UPGRADE',
|
||||
'CFGCMD_START',
|
||||
'CFGCMD_STOP',
|
||||
'CFGCMD_VERSION',
|
||||
'CFGOPT_ARCHIVE_ASYNC',
|
||||
'CFGOPT_ARCHIVE_CHECK',
|
||||
'CFGOPT_ARCHIVE_COPY',
|
||||
'CFGOPT_ARCHIVE_GET_QUEUE_MAX',
|
||||
'CFGOPT_ARCHIVE_PUSH_QUEUE_MAX',
|
||||
'CFGOPT_ARCHIVE_TIMEOUT',
|
||||
'CFGOPT_BACKUP_STANDBY',
|
||||
'CFGOPT_BUFFER_SIZE',
|
||||
'CFGOPT_CHECKSUM_PAGE',
|
||||
'CFGOPT_CMD_SSH',
|
||||
'CFGOPT_COMPRESS',
|
||||
'CFGOPT_COMPRESS_LEVEL',
|
||||
'CFGOPT_COMPRESS_LEVEL_NETWORK',
|
||||
'CFGOPT_CONFIG',
|
||||
'CFGOPT_CONFIG_INCLUDE_PATH',
|
||||
'CFGOPT_CONFIG_PATH',
|
||||
'CFGOPT_DB_INCLUDE',
|
||||
'CFGOPT_DB_TIMEOUT',
|
||||
'CFGOPT_DELTA',
|
||||
'CFGOPT_DRY_RUN',
|
||||
'CFGOPT_EXCLUDE',
|
||||
'CFGOPT_FILTER',
|
||||
'CFGOPT_FORCE',
|
||||
'CFGOPT_HOST_ID',
|
||||
'CFGOPT_LINK_ALL',
|
||||
'CFGOPT_LINK_MAP',
|
||||
'CFGOPT_LOCK_PATH',
|
||||
'CFGOPT_LOG_LEVEL_CONSOLE',
|
||||
'CFGOPT_LOG_LEVEL_FILE',
|
||||
'CFGOPT_LOG_LEVEL_STDERR',
|
||||
'CFGOPT_LOG_PATH',
|
||||
'CFGOPT_LOG_SUBPROCESS',
|
||||
'CFGOPT_LOG_TIMESTAMP',
|
||||
'CFGOPT_MANIFEST_SAVE_THRESHOLD',
|
||||
'CFGOPT_NEUTRAL_UMASK',
|
||||
'CFGOPT_ONLINE',
|
||||
'CFGOPT_OUTPUT',
|
||||
'CFGOPT_PG_HOST',
|
||||
'CFGOPT_PG_HOST2',
|
||||
'CFGOPT_PG_HOST3',
|
||||
'CFGOPT_PG_HOST4',
|
||||
'CFGOPT_PG_HOST5',
|
||||
'CFGOPT_PG_HOST6',
|
||||
'CFGOPT_PG_HOST7',
|
||||
'CFGOPT_PG_HOST8',
|
||||
'CFGOPT_PG_HOST_CMD',
|
||||
'CFGOPT_PG_HOST_CMD2',
|
||||
'CFGOPT_PG_HOST_CMD3',
|
||||
'CFGOPT_PG_HOST_CMD4',
|
||||
'CFGOPT_PG_HOST_CMD5',
|
||||
'CFGOPT_PG_HOST_CMD6',
|
||||
'CFGOPT_PG_HOST_CMD7',
|
||||
'CFGOPT_PG_HOST_CMD8',
|
||||
'CFGOPT_PG_HOST_CONFIG',
|
||||
'CFGOPT_PG_HOST_CONFIG2',
|
||||
'CFGOPT_PG_HOST_CONFIG3',
|
||||
'CFGOPT_PG_HOST_CONFIG4',
|
||||
'CFGOPT_PG_HOST_CONFIG5',
|
||||
'CFGOPT_PG_HOST_CONFIG6',
|
||||
'CFGOPT_PG_HOST_CONFIG7',
|
||||
'CFGOPT_PG_HOST_CONFIG8',
|
||||
'CFGOPT_PG_HOST_CONFIG_INCLUDE_PATH',
|
||||
'CFGOPT_PG_HOST_CONFIG_INCLUDE_PATH2',
|
||||
'CFGOPT_PG_HOST_CONFIG_INCLUDE_PATH3',
|
||||
'CFGOPT_PG_HOST_CONFIG_INCLUDE_PATH4',
|
||||
'CFGOPT_PG_HOST_CONFIG_INCLUDE_PATH5',
|
||||
'CFGOPT_PG_HOST_CONFIG_INCLUDE_PATH6',
|
||||
'CFGOPT_PG_HOST_CONFIG_INCLUDE_PATH7',
|
||||
'CFGOPT_PG_HOST_CONFIG_INCLUDE_PATH8',
|
||||
'CFGOPT_PG_HOST_CONFIG_PATH',
|
||||
'CFGOPT_PG_HOST_CONFIG_PATH2',
|
||||
'CFGOPT_PG_HOST_CONFIG_PATH3',
|
||||
'CFGOPT_PG_HOST_CONFIG_PATH4',
|
||||
'CFGOPT_PG_HOST_CONFIG_PATH5',
|
||||
'CFGOPT_PG_HOST_CONFIG_PATH6',
|
||||
'CFGOPT_PG_HOST_CONFIG_PATH7',
|
||||
'CFGOPT_PG_HOST_CONFIG_PATH8',
|
||||
'CFGOPT_PG_HOST_PORT',
|
||||
'CFGOPT_PG_HOST_PORT2',
|
||||
'CFGOPT_PG_HOST_PORT3',
|
||||
'CFGOPT_PG_HOST_PORT4',
|
||||
'CFGOPT_PG_HOST_PORT5',
|
||||
'CFGOPT_PG_HOST_PORT6',
|
||||
'CFGOPT_PG_HOST_PORT7',
|
||||
'CFGOPT_PG_HOST_PORT8',
|
||||
'CFGOPT_PG_HOST_USER',
|
||||
'CFGOPT_PG_HOST_USER2',
|
||||
'CFGOPT_PG_HOST_USER3',
|
||||
'CFGOPT_PG_HOST_USER4',
|
||||
'CFGOPT_PG_HOST_USER5',
|
||||
'CFGOPT_PG_HOST_USER6',
|
||||
'CFGOPT_PG_HOST_USER7',
|
||||
'CFGOPT_PG_HOST_USER8',
|
||||
'CFGOPT_PG_PATH',
|
||||
'CFGOPT_PG_PATH2',
|
||||
'CFGOPT_PG_PATH3',
|
||||
'CFGOPT_PG_PATH4',
|
||||
'CFGOPT_PG_PATH5',
|
||||
'CFGOPT_PG_PATH6',
|
||||
'CFGOPT_PG_PATH7',
|
||||
'CFGOPT_PG_PATH8',
|
||||
'CFGOPT_PG_PORT',
|
||||
'CFGOPT_PG_PORT2',
|
||||
'CFGOPT_PG_PORT3',
|
||||
'CFGOPT_PG_PORT4',
|
||||
'CFGOPT_PG_PORT5',
|
||||
'CFGOPT_PG_PORT6',
|
||||
'CFGOPT_PG_PORT7',
|
||||
'CFGOPT_PG_PORT8',
|
||||
'CFGOPT_PG_SOCKET_PATH',
|
||||
'CFGOPT_PG_SOCKET_PATH2',
|
||||
'CFGOPT_PG_SOCKET_PATH3',
|
||||
'CFGOPT_PG_SOCKET_PATH4',
|
||||
'CFGOPT_PG_SOCKET_PATH5',
|
||||
'CFGOPT_PG_SOCKET_PATH6',
|
||||
'CFGOPT_PG_SOCKET_PATH7',
|
||||
'CFGOPT_PG_SOCKET_PATH8',
|
||||
'CFGOPT_PG_USER',
|
||||
'CFGOPT_PG_USER2',
|
||||
'CFGOPT_PG_USER3',
|
||||
'CFGOPT_PG_USER4',
|
||||
'CFGOPT_PG_USER5',
|
||||
'CFGOPT_PG_USER6',
|
||||
'CFGOPT_PG_USER7',
|
||||
'CFGOPT_PG_USER8',
|
||||
'CFGOPT_PROCESS',
|
||||
'CFGOPT_PROCESS_MAX',
|
||||
'CFGOPT_PROTOCOL_TIMEOUT',
|
||||
'CFGOPT_RECOVERY_OPTION',
|
||||
'CFGOPT_RECURSE',
|
||||
'CFGOPT_REMOTE_TYPE',
|
||||
'CFGOPT_REPO_CIPHER_PASS',
|
||||
'CFGOPT_REPO_CIPHER_TYPE',
|
||||
'CFGOPT_REPO_HARDLINK',
|
||||
'CFGOPT_REPO_HOST',
|
||||
'CFGOPT_REPO_HOST_CMD',
|
||||
'CFGOPT_REPO_HOST_CONFIG',
|
||||
'CFGOPT_REPO_HOST_CONFIG_INCLUDE_PATH',
|
||||
'CFGOPT_REPO_HOST_CONFIG_PATH',
|
||||
'CFGOPT_REPO_HOST_PORT',
|
||||
'CFGOPT_REPO_HOST_USER',
|
||||
'CFGOPT_REPO_PATH',
|
||||
'CFGOPT_REPO_RETENTION_ARCHIVE',
|
||||
'CFGOPT_REPO_RETENTION_ARCHIVE_TYPE',
|
||||
'CFGOPT_REPO_RETENTION_DIFF',
|
||||
'CFGOPT_REPO_RETENTION_FULL',
|
||||
'CFGOPT_REPO_S3_BUCKET',
|
||||
'CFGOPT_REPO_S3_CA_FILE',
|
||||
'CFGOPT_REPO_S3_CA_PATH',
|
||||
'CFGOPT_REPO_S3_ENDPOINT',
|
||||
'CFGOPT_REPO_S3_HOST',
|
||||
'CFGOPT_REPO_S3_KEY',
|
||||
'CFGOPT_REPO_S3_KEY_SECRET',
|
||||
'CFGOPT_REPO_S3_PORT',
|
||||
'CFGOPT_REPO_S3_REGION',
|
||||
'CFGOPT_REPO_S3_TOKEN',
|
||||
'CFGOPT_REPO_S3_URI_STYLE',
|
||||
'CFGOPT_REPO_S3_VERIFY_TLS',
|
||||
'CFGOPT_REPO_TYPE',
|
||||
'CFGOPT_RESUME',
|
||||
'CFGOPT_SET',
|
||||
'CFGOPT_SORT',
|
||||
'CFGOPT_SPOOL_PATH',
|
||||
'CFGOPT_STANZA',
|
||||
'CFGOPT_START_FAST',
|
||||
'CFGOPT_STOP_AUTO',
|
||||
'CFGOPT_TABLESPACE_MAP',
|
||||
'CFGOPT_TABLESPACE_MAP_ALL',
|
||||
'CFGOPT_TARGET',
|
||||
'CFGOPT_TARGET_ACTION',
|
||||
'CFGOPT_TARGET_EXCLUSIVE',
|
||||
'CFGOPT_TARGET_TIMELINE',
|
||||
'CFGOPT_TYPE',
|
||||
'cfgCommandName',
|
||||
'cfgOptionIndexTotal',
|
||||
'cfgOptionName',
|
||||
],
|
||||
|
||||
configDefine =>
|
||||
[
|
||||
'CFGDEF_TYPE_BOOLEAN',
|
||||
'CFGDEF_TYPE_FLOAT',
|
||||
'CFGDEF_TYPE_HASH',
|
||||
'CFGDEF_TYPE_INTEGER',
|
||||
'CFGDEF_TYPE_LIST',
|
||||
'CFGDEF_TYPE_PATH',
|
||||
'CFGDEF_TYPE_SIZE',
|
||||
'CFGDEF_TYPE_STRING',
|
||||
'cfgCommandId',
|
||||
'cfgDefOptionDefault',
|
||||
'cfgDefOptionPrefix',
|
||||
'cfgDefOptionSecure',
|
||||
'cfgDefOptionType',
|
||||
'cfgDefOptionValid',
|
||||
'cfgOptionId',
|
||||
'cfgOptionTotal',
|
||||
],
|
||||
|
||||
crypto =>
|
||||
[
|
||||
'cryptoHashOne',
|
||||
],
|
||||
|
||||
debug =>
|
||||
[
|
||||
'libcUvSize',
|
||||
],
|
||||
|
||||
storage =>
|
||||
[
|
||||
'storageRepoFree',
|
||||
],
|
||||
|
||||
test =>
|
||||
[
|
||||
'cfgParseTest',
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
@ -716,6 +716,7 @@ testRun(void)
|
||||
strLstAddZ(argList, "--repo1-retention-diff=3");
|
||||
strLstAddZ(argList, "--repo1-retention-archive=2");
|
||||
strLstAddZ(argList, "--repo1-retention-archive-type=diff");
|
||||
strLstAddZ(argList, "--dry-run");
|
||||
harnessCfgLoad(cfgCmdExpire, argList);
|
||||
|
||||
// Write backup.manifest so infoBackup reconstruct produces same results as backup.info on disk
|
||||
@ -741,6 +742,64 @@ testRun(void)
|
||||
storageNewWriteP(storageTest, strNewFmt("%s/20181119-152900F_20181119-152500I/" BACKUP_MANIFEST_FILE,
|
||||
strPtr(backupStanzaPath))), BUFSTRDEF("tmp"));
|
||||
|
||||
TEST_RESULT_VOID(cmdExpire(), "expire (dry-run) do not remove last backup in archive sub path or sub path");
|
||||
TEST_RESULT_BOOL(
|
||||
storagePathExistsP(storageTest, strNewFmt("%s/%s", strPtr(archiveStanzaPath), "9.4-1/0000000100000000")),
|
||||
true, " archive sub path not removed");
|
||||
TEST_RESULT_BOOL(
|
||||
storageExistsP(storageTest, strNewFmt("%s/20181119-152138F/" BACKUP_MANIFEST_FILE, strPtr(backupStanzaPath))),
|
||||
true, " backup not removed");
|
||||
harnessLogResult(
|
||||
"P00 INFO: expire full backup 20181119-152138F\n"
|
||||
"P00 INFO: remove expired backup 20181119-152138F");
|
||||
|
||||
// Save a copy of the info files for a later test
|
||||
storageCopy(
|
||||
storageNewReadP(storageTest, backupInfoFileName),
|
||||
storageNewWriteP(storageTest, strNewFmt("%s%s", strPtr(backupInfoFileName), ".save")));
|
||||
storageCopy(
|
||||
storageNewReadP(storageTest, archiveInfoFileName),
|
||||
storageNewWriteP(storageTest, strNewFmt("%s%s", strPtr(archiveInfoFileName), ".save")));
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
argList = strLstDup(argListBase);
|
||||
strLstAddZ(argList, "--repo1-retention-full=2");
|
||||
strLstAddZ(argList, "--repo1-retention-diff=3");
|
||||
strLstAddZ(argList, "--repo1-retention-archive=2");
|
||||
strLstAddZ(argList, "--repo1-retention-archive-type=diff");
|
||||
strLstAdd(argList, strNewFmt("--pg1-path=%s/pg", testPath()));
|
||||
harnessCfgLoad(cfgCmdBackup, argList);
|
||||
|
||||
TEST_RESULT_VOID(cmdExpire(), "via backup command: expire last backup in archive sub path and remove sub path");
|
||||
TEST_RESULT_BOOL(
|
||||
storagePathExistsP(storageTest, strNewFmt("%s/%s", strPtr(archiveStanzaPath), "9.4-1/0000000100000000")),
|
||||
false, " archive sub path removed");
|
||||
harnessLogResult(
|
||||
"P00 INFO: expire full backup 20181119-152138F\n"
|
||||
"P00 INFO: remove expired backup 20181119-152138F");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
argList = strLstDup(argListBase);
|
||||
strLstAddZ(argList, "--repo1-retention-full=2");
|
||||
strLstAddZ(argList, "--repo1-retention-diff=3");
|
||||
strLstAddZ(argList, "--repo1-retention-archive=2");
|
||||
strLstAddZ(argList, "--repo1-retention-archive-type=diff");
|
||||
harnessCfgLoad(cfgCmdExpire, argList);
|
||||
|
||||
// Restore info files from a previous test
|
||||
storageCopy(
|
||||
storageNewReadP(storageTest, strNewFmt("%s%s", strPtr(backupInfoFileName), ".save")),
|
||||
storageNewWriteP(storageTest, backupInfoFileName));
|
||||
storageCopy(
|
||||
storageNewReadP(storageTest, strNewFmt("%s%s", strPtr(archiveInfoFileName), ".save")),
|
||||
storageNewWriteP(storageTest, archiveInfoFileName));
|
||||
|
||||
// Write out manifest and archive that will be removed
|
||||
storagePutP(
|
||||
storageNewWriteP(storageTest, strNewFmt("%s/20181119-152138F/" BACKUP_MANIFEST_FILE, strPtr(backupStanzaPath))),
|
||||
BUFSTRDEF("tmp"));
|
||||
archiveGenerate(storageTest, archiveStanzaPath, 2, 2, "9.4-1", "0000000100000000");
|
||||
|
||||
TEST_RESULT_VOID(cmdExpire(), "expire last backup in archive sub path and remove sub path");
|
||||
TEST_RESULT_BOOL(
|
||||
storagePathExistsP(storageTest, strNewFmt("%s/%s", strPtr(archiveStanzaPath), "9.4-1/0000000100000000")),
|
||||
@ -752,9 +811,37 @@ testRun(void)
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
argList = strLstDup(argListAvoidWarn);
|
||||
strLstAddZ(argList, "--repo1-retention-archive=1");
|
||||
strLstAddZ(argList, "--dry-run");
|
||||
harnessCfgLoad(cfgCmdExpire, argList);
|
||||
|
||||
TEST_RESULT_VOID(cmdExpire(), "expire last backup in archive path and remove path");
|
||||
TEST_RESULT_VOID(cmdExpire(), "expire (dry-run) - log expired backups and archive path to remove");
|
||||
TEST_RESULT_BOOL(
|
||||
storagePathExistsP(storageTest, strNewFmt("%s/%s", strPtr(archiveStanzaPath), "9.4-1")),
|
||||
true, " archive path not removed");
|
||||
TEST_RESULT_BOOL(
|
||||
(storageExistsP(storageTest, strNewFmt("%s/20181119-152800F/" BACKUP_MANIFEST_FILE, strPtr(backupStanzaPath))) &&
|
||||
storageExistsP(
|
||||
storageTest, strNewFmt("%s/20181119-152800F_20181119-152152D/" BACKUP_MANIFEST_FILE, strPtr(backupStanzaPath))) &&
|
||||
storageExistsP(
|
||||
storageTest, strNewFmt("%s/20181119-152800F_20181119-152155I/" BACKUP_MANIFEST_FILE, strPtr(backupStanzaPath))) &&
|
||||
storageExistsP(
|
||||
storageTest, strNewFmt("%s/20181119-152800F_20181119-152252D/" BACKUP_MANIFEST_FILE, strPtr(backupStanzaPath)))),
|
||||
true, " backup not removed");
|
||||
harnessLogResult(strPtr(strNewFmt(
|
||||
"P00 INFO: expire full backup set: 20181119-152800F, 20181119-152800F_20181119-152152D, "
|
||||
"20181119-152800F_20181119-152155I, 20181119-152800F_20181119-152252D\n"
|
||||
"P00 INFO: remove expired backup 20181119-152800F_20181119-152252D\n"
|
||||
"P00 INFO: remove expired backup 20181119-152800F_20181119-152155I\n"
|
||||
"P00 INFO: remove expired backup 20181119-152800F_20181119-152152D\n"
|
||||
"P00 INFO: remove expired backup 20181119-152800F\n"
|
||||
"P00 INFO: remove archive path: %s/%s/9.4-1", testPath(), strPtr(archiveStanzaPath))));
|
||||
|
||||
argList = strLstDup(argListAvoidWarn);
|
||||
strLstAddZ(argList, "--repo1-retention-archive=1");
|
||||
strLstAdd(argList, strNewFmt("--pg1-path=%s/pg", testPath()));
|
||||
harnessCfgLoad(cfgCmdBackup, argList);
|
||||
|
||||
TEST_RESULT_VOID(cmdExpire(), "via backup command: expire backups and remove archive path");
|
||||
TEST_RESULT_BOOL(
|
||||
storagePathExistsP(storageTest, strNewFmt("%s/%s", strPtr(archiveStanzaPath), "9.4-1")),
|
||||
false, " archive path removed");
|
||||
@ -774,6 +861,15 @@ testRun(void)
|
||||
strLstJoin(strLstSort(infoBackupDataLabelList(infoBackup, NULL), sortOrderAsc), ", "),
|
||||
"20181119-152900F, 20181119-152900F_20181119-152500I", " remaining current backups correct");
|
||||
|
||||
archiveGenerate(storageTest, archiveStanzaPath, 1, 1, "9.4-1", "0000000100000000");
|
||||
argList = strLstDup(argListAvoidWarn);
|
||||
strLstAddZ(argList, "--repo1-retention-archive=1");
|
||||
harnessCfgLoad(cfgCmdExpire, argList);
|
||||
|
||||
TEST_RESULT_VOID(cmdExpire(), "expire remove archive path");
|
||||
harnessLogResult(
|
||||
strPtr(strNewFmt("P00 INFO: remove archive path: %s/%s/9.4-1", testPath(), strPtr(archiveStanzaPath))));
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
storagePutP(storageNewWriteP(storageTest, backupInfoFileName),
|
||||
harnessInfoChecksumZ(
|
||||
|
Loading…
x
Reference in New Issue
Block a user