Skip to content

Commit

Permalink
Improve stanza-create command so that it does not error when the stan…
Browse files Browse the repository at this point in the history
…za already exists.

Contributed by Cynthia Shang.
  • Loading branch information
cmwshang authored and dwsteele committed Feb 1, 2018
1 parent 298b339 commit dc73abd
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 168 deletions.
8 changes: 8 additions & 0 deletions doc/xml/release.xml
Expand Up @@ -69,6 +69,14 @@
<release-item>
<p>The <file>{[project-exe]}</file> executable is now a C binary instead of Perl. This allows certain time-critical commands (like async <cmd>archive-push</cmd>) to run more quickly.</p>
</release-item>

<release-item>
<release-item-contributor-list>
<release-item-contributor id="shang.cynthia"/>
</release-item-contributor-list>

<p>Improve <cmd>stanza-create</cmd> command so that it does not error when the stanza already exists.</p>
</release-item>
</release-improvement-list>

<release-development-list>
Expand Down
77 changes: 55 additions & 22 deletions lib/pgBackRest/Stanza.pm
Expand Up @@ -32,7 +32,7 @@ use pgBackRest::Protocol::Storage::Helper;
####################################################################################################################################
# Global variables
####################################################################################################################################
my $strHintForce = "\nHINT: use stanza-create --force to force the stanza data to be created.";
my $strHintForce = "\nHINT: use stanza-create --force to force the stanza data to be recreated.";
my $strInfoMissing = " information missing";
my $strStanzaCreateErrorMsg = "not empty";
my $strRepoEncryptedMsg = " and repo is encrypted and info file(s) are missing, --force cannot be used";
Expand Down Expand Up @@ -120,6 +120,8 @@ sub stanzaCreate
# Assign function parameters, defaults, and log debug info
my ($strOperation) = logDebugParam(__PACKAGE__ . '->stanzaCreate');

my $bContinue = true;

# Get the parent paths (create if not exist)
my $strParentPathArchive = $self->parentPathGet(STORAGE_REPO_ARCHIVE);
my $strParentPathBackup = $self->parentPathGet(STORAGE_REPO_BACKUP);
Expand All @@ -136,10 +138,23 @@ sub stanzaCreate
my $strBackupInfoFile = &FILE_BACKUP_INFO;
my $strArchiveInfoFile = &ARCHIVE_INFO_FILE;

# If .info exists, set to true. Do not include .info.copy
# If .info exists, set to true.
my $bBackupInfoFileExists = grep(/^$strBackupInfoFile$/i, @stryFileListBackup);
my $bArchiveInfoFileExists = grep(/^$strArchiveInfoFile$/i, @stryFileListArchive);

# If .info does not exist, check for .info.copy
if (!$bBackupInfoFileExists)
{
$strBackupInfoFile .= &INI_COPY_EXT;
$bBackupInfoFileExists = grep(/^$strBackupInfoFile$/i, @stryFileListBackup);
}

if (!$bArchiveInfoFileExists)
{
$strArchiveInfoFile .= &INI_COPY_EXT;
$bArchiveInfoFileExists = grep(/^$strArchiveInfoFile$/i, @stryFileListArchive);
}

# Determine if a file exists other than the info files
my $strExistingFile = $self->existingFileName(STORAGE_REPO_BACKUP, $strParentPathBackup, &FILE_BACKUP_INFO);
if (!defined($strExistingFile))
Expand Down Expand Up @@ -168,7 +183,6 @@ sub stanzaCreate
$self->errorForce('backup' . $strInfoMissing, ERROR_FILE_MISSING, $strExistingFile, $bBackupInfoFileExists,
$strParentPathArchive, $strParentPathBackup);
}

# If we get here then either both exist or neither exist so if neither file exists and something else exists in the
# directories then need to use force option to recreate the missing info files - unless the repo is encrypted, then force
# cannot be used if other than the info files exist. If only the info files exist then force must be used to overwrite the
Expand All @@ -181,26 +195,39 @@ sub stanzaCreate
(@stryFileListArchive ? 'archive directory ' : '') .
$strStanzaCreateErrorMsg, ERROR_PATH_NOT_EMPTY,
$strExistingFile, $bArchiveInfoFileExists, $strParentPathArchive, $strParentPathBackup);

# If no error was thrown, then do not continue without --force
if (!cfgOption(CFGOPT_FORCE))
{
$bContinue = false;
}
}
}

# Instantiate the info objects. Throws an error and aborts if force not used and an error occurs during instantiation.
my $oArchiveInfo = $self->infoObject(STORAGE_REPO_ARCHIVE, $strParentPathArchive, {bRequired => false, bIgnoreMissing => true});
my $oBackupInfo = $self->infoObject(STORAGE_REPO_BACKUP, $strParentPathBackup, {bRequired => false, bIgnoreMissing => true});

# Create the archive info object
my ($iResult, $strResultMessage) = $self->infoFileCreate($oArchiveInfo);
my $iResult = 0;

if ($iResult == 0)
if ($bContinue)
{
# Create the backup.info file
($iResult, $strResultMessage) = $self->infoFileCreate($oBackupInfo);
}
# Instantiate the info objects. Throws an error and aborts if force not used and an error occurs during instantiation.
my $oArchiveInfo =
$self->infoObject(STORAGE_REPO_ARCHIVE, $strParentPathArchive, {bRequired => false, bIgnoreMissing => true});
my $oBackupInfo =
$self->infoObject(STORAGE_REPO_BACKUP, $strParentPathBackup, {bRequired => false, bIgnoreMissing => true});

if ($iResult != 0)
{
&log(WARN, "unable to create stanza '" . cfgOption(CFGOPT_STANZA) . "'");
confess &log(ERROR, $strResultMessage, $iResult);
# Create the archive info object
($iResult, my $strResultMessage) = $self->infoFileCreate($oArchiveInfo);

if ($iResult == 0)
{
# Create the backup.info file
($iResult, $strResultMessage) = $self->infoFileCreate($oBackupInfo);
}

if ($iResult != 0)
{
&log(WARN, "unable to create stanza '" . cfgOption(CFGOPT_STANZA) . "'");
confess &log(ERROR, $strResultMessage, $iResult);
}
}

# Return from function and log return values if any
Expand Down Expand Up @@ -474,8 +501,8 @@ sub errorForce
}
elsif (!cfgOption(CFGOPT_FORCE))
{
# If info files exist, check to see if an upgrade is required
if ($bInfoFileExists && !defined($strFileName) && $iErrorCode == ERROR_PATH_NOT_EMPTY)
# If info files exist, check to see if the DB sections match the database - else an upgrade is required
if ($bInfoFileExists && $iErrorCode == ERROR_PATH_NOT_EMPTY)
{
if ($self->upgradeCheck(new pgBackRest::Backup::Info($strParentPathBackup), STORAGE_REPO_BACKUP,
ERROR_BACKUP_MISMATCH) ||
Expand All @@ -485,10 +512,16 @@ sub errorForce
confess &log(ERROR, "backup info file or archive info file invalid\n" .
'HINT: use stanza-upgrade if the database has been upgraded or use --force', ERROR_FILE_INVALID);
}
else
{
&log(INFO, "stanza-create was already performed");
}
}
else
{
# If get here something is wrong so indicate force is required
confess &log(ERROR, $strMessage . $strHintForce, $iErrorCode);
}

# If get here just indicate force is required
confess &log(ERROR, $strMessage . $strHintForce, $iErrorCode);
}

# Return from function and log return values if any
Expand Down
2 changes: 1 addition & 1 deletion test/expect/mock-all-001.log
Expand Up @@ -2912,7 +2912,7 @@ stanza-create db - fail on backup directory missing backup.info (db-master host)
------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: stanza-create command begin [BACKREST-VERSION]: --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db1-path=[TEST_PATH]/db-master/db/base-2 --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=detail --log-level-file=trace --log-path=[TEST_PATH]/db-master/log --no-online --protocol-timeout=60 --repo-path=[TEST_PATH]/db-master/repo --stanza=db
P00 ERROR: [055]: backup information missing
HINT: use stanza-create --force to force the stanza data to be created.
HINT: use stanza-create --force to force the stanza data to be recreated.
P00 INFO: stanza-create command end: aborted with exception [055]

+ supplemental file: [TEST_PATH]/db-master/repo/archive/db/archive.info
Expand Down
51 changes: 5 additions & 46 deletions test/expect/mock-stanza-001.log
Expand Up @@ -57,13 +57,12 @@ db-version="9.3"
[db:history]
1={"db-id":1000000000000000093,"db-version":"9.3"}

stanza-create db - fail on rerun of stanza-create - info files exist (db-master host)
stanza-create db - do not fail on rerun of stanza-create - info files exist and DB section ok (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db --log-level-console=detail --no-online stanza-create
------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: stanza-create command begin [BACKREST-VERSION]: --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db1-path=[TEST_PATH]/db-master/db/base --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=detail --log-level-file=trace --log-path=[TEST_PATH]/db-master/log --no-online --protocol-timeout=60 --repo-path=[TEST_PATH]/db-master/repo --stanza=db
P00 ERROR: [040]: backup directory and/or archive directory not empty
HINT: use stanza-create --force to force the stanza data to be created.
P00 INFO: stanza-create command end: aborted with exception [040]
P00 INFO: stanza-create was already performed
P00 INFO: stanza-create command end: completed successfully

+ supplemental file: [TEST_PATH]/db-master/repo/backup/db/backup.info
---------------------------------------------------------------------
Expand Down Expand Up @@ -228,7 +227,7 @@ stanza-create db - fail on archive info file missing from non-empty dir (db-mast
------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: stanza-create command begin [BACKREST-VERSION]: --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db1-path=[TEST_PATH]/db-master/db/base --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=detail --log-level-file=trace --log-path=[TEST_PATH]/db-master/log --no-online --protocol-timeout=60 --repo-path=[TEST_PATH]/db-master/repo --stanza=db
P00 ERROR: [055]: archive information missing
HINT: use stanza-create --force to force the stanza data to be created.
HINT: use stanza-create --force to force the stanza data to be recreated.
P00 INFO: stanza-create command end: aborted with exception [055]

+ supplemental file: [TEST_PATH]/db-master/repo/backup/db/backup.info
Expand Down Expand Up @@ -310,46 +309,6 @@ db-version="9.3"
[db:history]
1={"db-id":1000000000000000093,"db-version":"9.3"}

stanza-create db - repeat create - error that files exist (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db --log-level-console=detail --no-online stanza-create
------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: stanza-create command begin [BACKREST-VERSION]: --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db1-path=[TEST_PATH]/db-master/db/base --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=detail --log-level-file=trace --log-path=[TEST_PATH]/db-master/log --no-online --protocol-timeout=60 --repo-path=[TEST_PATH]/db-master/repo --stanza=db
P00 ERROR: [040]: backup directory and/or archive directory not empty
HINT: use stanza-create --force to force the stanza data to be created.
P00 INFO: stanza-create command end: aborted with exception [040]

+ supplemental file: [TEST_PATH]/db-master/repo/backup/db/backup.info
---------------------------------------------------------------------
[backrest]
backrest-checksum="[CHECKSUM]"
backrest-format=5
backrest-version="[VERSION-1]"

[db]
db-catalog-version=201306121
db-control-version=937
db-id=1
db-system-id=1000000000000000093
db-version="9.3"

[db:history]
1={"db-catalog-version":201306121,"db-control-version":937,"db-system-id":1000000000000000093,"db-version":"9.3"}

+ supplemental file: [TEST_PATH]/db-master/repo/archive/db/archive.info
-----------------------------------------------------------------------
[backrest]
backrest-checksum="[CHECKSUM]"
backrest-format=5
backrest-version="[VERSION-1]"

[db]
db-id=1
db-system-id=1000000000000000093
db-version="9.3"

[db:history]
1={"db-id":1000000000000000093,"db-version":"9.3"}

stanza-create db - force create archive.info from uncompressed file (db-master host)
> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db --log-level-console=detail --no-online --force stanza-create
------------------------------------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -730,7 +689,7 @@ stanza-create db - fail no force to recreate the stanza from backups (db-master
------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: stanza-create command begin [BACKREST-VERSION]: --compress-level=3 --config=[TEST_PATH]/db-master/pgbackrest.conf --db1-path=[TEST_PATH]/db-master/db/base --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=detail --log-level-file=trace --log-path=[TEST_PATH]/db-master/log --no-online --protocol-timeout=60 --repo-path=[TEST_PATH]/db-master/repo --stanza=db
P00 ERROR: [055]: backup information missing
HINT: use stanza-create --force to force the stanza data to be created.
HINT: use stanza-create --force to force the stanza data to be recreated.
P00 INFO: stanza-create command end: aborted with exception [055]

+ supplemental file: [TEST_PATH]/db-master/repo/archive/db/archive.info
Expand Down
34 changes: 3 additions & 31 deletions test/expect/mock-stanza-002.log
Expand Up @@ -63,13 +63,12 @@ db-version="9.3"
[db:history]
1={"db-id":1000000000000000093,"db-version":"9.3"}

stanza-create db - fail on rerun of stanza-create - info files exist (backup host)
stanza-create db - do not fail on rerun of stanza-create - info files exist and DB section ok (backup host)
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db --log-level-console=detail --no-online stanza-create
------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: stanza-create command begin [BACKREST-VERSION]: --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db1-cmd=[BACKREST-BIN] --db1-config=[TEST_PATH]/db-master/pgbackrest.conf --db1-host=db-master --db1-path=[TEST_PATH]/db-master/db/base --db-timeout=45 --db1-user=[USER-1] --lock-path=[TEST_PATH]/backup/lock --log-level-console=detail --log-level-file=trace --log-path=[TEST_PATH]/backup/log --no-online --protocol-timeout=60 --repo-cipher-pass=<redacted> --repo-cipher-type=aes-256-cbc --repo-path=[TEST_PATH]/backup/repo --stanza=db
P00 ERROR: [040]: backup directory and/or archive directory not empty
HINT: use stanza-create --force to force the stanza data to be created.
P00 INFO: stanza-create command end: aborted with exception [040]
P00 INFO: stanza-create was already performed
P00 INFO: stanza-create command end: completed successfully

+ supplemental file: [TEST_PATH]/backup/repo/backup/db/backup.info
------------------------------------------------------------------
Expand Down Expand Up @@ -293,33 +292,6 @@ db-version="9.3"
[db:history]
1={"db-catalog-version":201306121,"db-control-version":937,"db-system-id":1000000000000000093,"db-version":"9.3"}

stanza-create db - repeat create - error that files exist (backup host)
> [CONTAINER-EXEC] backup [BACKREST-BIN] --config=[TEST_PATH]/backup/pgbackrest.conf --stanza=db --log-level-console=detail --no-online stanza-create
------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: stanza-create command begin [BACKREST-VERSION]: --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/backup/pgbackrest.conf --db1-cmd=[BACKREST-BIN] --db1-config=[TEST_PATH]/db-master/pgbackrest.conf --db1-host=db-master --db1-path=[TEST_PATH]/db-master/db/base --db-timeout=45 --db1-user=[USER-1] --lock-path=[TEST_PATH]/backup/lock --log-level-console=detail --log-level-file=trace --log-path=[TEST_PATH]/backup/log --no-online --protocol-timeout=60 --repo-cipher-pass=<redacted> --repo-cipher-type=aes-256-cbc --repo-path=[TEST_PATH]/backup/repo --stanza=db
P00 ERROR: [055]: archive information missing and repo is encrypted and info file(s) are missing, --force cannot be used
P00 INFO: stanza-create command end: aborted with exception [055]

+ supplemental file: [TEST_PATH]/backup/repo/backup/db/backup.info
------------------------------------------------------------------
[backrest]
backrest-checksum="[CHECKSUM]"
backrest-format=5
backrest-version="[VERSION-1]"

[cipher]
cipher-pass=[CIPHER-PASS-1]

[db]
db-catalog-version=201306121
db-control-version=937
db-id=1
db-system-id=1000000000000000093
db-version="9.3"

[db:history]
1={"db-catalog-version":201306121,"db-control-version":937,"db-system-id":1000000000000000093,"db-version":"9.3"}

> [CONTAINER-EXEC] db-master [BACKREST-BIN] --config=[TEST_PATH]/db-master/pgbackrest.conf --stanza=db archive-push [TEST_PATH]/db-master/db/base/pg_xlog/000000010000000100000002
------------------------------------------------------------------------------------------------------------------------------------
P00 INFO: archive-push command begin [BACKREST-VERSION]: --backup-cmd=[BACKREST-BIN] --backup-config=[TEST_PATH]/backup/pgbackrest.conf --backup-host=backup --backup-user=[USER-2] --compress-level=3 --compress-level-network=1 --config=[TEST_PATH]/db-master/pgbackrest.conf --db1-path=[TEST_PATH]/db-master/db/base --db-timeout=45 --lock-path=[TEST_PATH]/db-master/lock --log-level-console=debug --log-level-file=trace --log-level-stderr=off --log-path=[TEST_PATH]/db-master/log --protocol-timeout=60 --stanza=db
Expand Down

0 comments on commit dc73abd

Please sign in to comment.