1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-03-03 14:52:21 +02:00

Allow files that become zero-length after the backup manifest is built.

It is possible that a file will be be truncated to zero-length after the backup manifest has been built. We could build logic into backupFile() to handle this case but it is hard to test well because of the race condition so tests would need to written directly against backupFile() and backupJobResult(). It hardly seems worth all that effort for a condition that occurs rarely, if ever.

Instead just remove the manifest check and add tests to restore to make sure it handles bundled zero-length files correctly. Logging will show that the file was bundled so if it happens a lot (which seems very unlikely) then we can think about an alternate implementation.
This commit is contained in:
David Steele 2022-03-23 10:41:36 -06:00
parent fe9fd2ff2d
commit 424008d293
3 changed files with 13 additions and 4 deletions

View File

@ -104,6 +104,7 @@
<github-pull-request id="1694"/> <github-pull-request id="1694"/>
</commit> </commit>
<commit subject="Disable repo-hardlink option when repo-bundle option is enabled."/> <commit subject="Disable repo-hardlink option when repo-bundle option is enabled."/>
<commit subject="Allow files that become zero-length after the backup manifest is built."/>
<release-item-contributor-list> <release-item-contributor-list>
<release-item-contributor id="david.steele"/> <release-item-contributor id="david.steele"/>

View File

@ -238,8 +238,6 @@ manifestFilePack(const Manifest *const manifest, const ManifestFile *const file)
ASSERT(manifest != NULL); ASSERT(manifest != NULL);
ASSERT(file != NULL); ASSERT(file != NULL);
CHECK(AssertError, file->size > 0 || file->bundleId == 0, "zero-length files may not be bundled");
uint8_t buffer[512]; uint8_t buffer[512];
size_t bufferPos = 0; size_t bufferPos = 0;

View File

@ -2375,6 +2375,13 @@ testRun(void)
.name = STRDEF(TEST_PGDATA "xxxxx"), .size = 5, .sizeRepo = 5, .timestamp = 1482182860, .name = STRDEF(TEST_PGDATA "xxxxx"), .size = 5, .sizeRepo = 5, .timestamp = 1482182860,
.mode = 0600, .group = groupName(), .user = userName(), .bundleId = 1, .bundleOffset = 11, .mode = 0600, .group = groupName(), .user = userName(), .bundleId = 1, .bundleOffset = 11,
.reference = NULL, .checksumSha1 = "9addbf544119efa4a64223b649750a510f0d463f"}); .reference = NULL, .checksumSha1 = "9addbf544119efa4a64223b649750a510f0d463f"});
// Set bogus sizeRepo and checksumSha1 to ensure this is not handled as a regular file
manifestFileAdd(
manifest,
&(ManifestFile){
.name = STRDEF(TEST_PGDATA "zero-length"), .size = 0, .sizeRepo = 1, .timestamp = 1482182866,
.mode = 0600, .group = groupName(), .user = userName(), .bundleId = 1, .bundleOffset = 16,
.reference = NULL, .checksumSha1 = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"});
manifestFileAdd( manifestFileAdd(
manifest, manifest,
&(ManifestFile){ &(ManifestFile){
@ -2695,6 +2702,7 @@ testRun(void)
" e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98\n" " e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98\n"
"P01 DETAIL: restore file " TEST_PATH "/pg/global/999 (0B, [PCT])\n" "P01 DETAIL: restore file " TEST_PATH "/pg/global/999 (0B, [PCT])\n"
"P01 DETAIL: restore file " TEST_PATH "/pg/global/888 (0B, [PCT])\n" "P01 DETAIL: restore file " TEST_PATH "/pg/global/888 (0B, [PCT])\n"
"P01 DETAIL: restore file " TEST_PATH "/pg/zero-length (bundle 1/16, 0B, [PCT])\n"
"P00 DETAIL: sync path '" TEST_PATH "/config'\n" "P00 DETAIL: sync path '" TEST_PATH "/config'\n"
"P00 DETAIL: sync path '" TEST_PATH "/pg'\n" "P00 DETAIL: sync path '" TEST_PATH "/pg'\n"
"P00 DETAIL: sync path '" TEST_PATH "/pg/base'\n" "P00 DETAIL: sync path '" TEST_PATH "/pg/base'\n"
@ -2708,7 +2716,7 @@ testRun(void)
"P00 DETAIL: sync path '" TEST_PATH "/pg/pg_tblspc/1/PG_10_201707211'\n" "P00 DETAIL: sync path '" TEST_PATH "/pg/pg_tblspc/1/PG_10_201707211'\n"
"P00 INFO: restore global/pg_control (performed last to ensure aborted restores cannot be started)\n" "P00 INFO: restore global/pg_control (performed last to ensure aborted restores cannot be started)\n"
"P00 DETAIL: sync path '" TEST_PATH "/pg/global'\n" "P00 DETAIL: sync path '" TEST_PATH "/pg/global'\n"
"P00 INFO: restore size = [SIZE], file total = 20"); "P00 INFO: restore size = [SIZE], file total = 21");
testRestoreCompare( testRestoreCompare(
storagePg(), NULL, manifest, storagePg(), NULL, manifest,
@ -2741,6 +2749,7 @@ testRun(void)
"postgresql.conf {link, d=../config/postgresql.conf}\n" "postgresql.conf {link, d=../config/postgresql.conf}\n"
"xxxxx {file, s=5, t=1482182860}\n" "xxxxx {file, s=5, t=1482182860}\n"
"yyy {file, s=3, t=1482182860}\n" "yyy {file, s=3, t=1482182860}\n"
"zero-length {file, s=0, t=1482182866}\n"
"zz {file, s=2, t=1482182860}\n"); "zz {file, s=2, t=1482182860}\n");
testRestoreCompare( testRestoreCompare(
@ -2870,6 +2879,7 @@ testRun(void)
" 20161219-212741F_20161219-212900I/2/2, 1B, [PCT]) checksum e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98\n" " 20161219-212741F_20161219-212900I/2/2, 1B, [PCT]) checksum e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98\n"
"P01 DETAIL: restore file " TEST_PATH "/pg/global/999 - exists and is zero size (0B, [PCT])\n" "P01 DETAIL: restore file " TEST_PATH "/pg/global/999 - exists and is zero size (0B, [PCT])\n"
"P01 DETAIL: restore file " TEST_PATH "/pg/global/888 - exists and is zero size (0B, [PCT])\n" "P01 DETAIL: restore file " TEST_PATH "/pg/global/888 - exists and is zero size (0B, [PCT])\n"
"P01 DETAIL: restore file " TEST_PATH "/pg/zero-length - exists and is zero size (bundle 1/16, 0B, [PCT])\n"
"P00 DETAIL: sync path '" TEST_PATH "/config'\n" "P00 DETAIL: sync path '" TEST_PATH "/config'\n"
"P00 DETAIL: sync path '" TEST_PATH "/pg'\n" "P00 DETAIL: sync path '" TEST_PATH "/pg'\n"
"P00 DETAIL: sync path '" TEST_PATH "/pg/base'\n" "P00 DETAIL: sync path '" TEST_PATH "/pg/base'\n"
@ -2883,7 +2893,7 @@ testRun(void)
"P00 DETAIL: sync path '" TEST_PATH "/pg/pg_tblspc/1/PG_10_201707211'\n" "P00 DETAIL: sync path '" TEST_PATH "/pg/pg_tblspc/1/PG_10_201707211'\n"
"P00 INFO: restore global/pg_control (performed last to ensure aborted restores cannot be started)\n" "P00 INFO: restore global/pg_control (performed last to ensure aborted restores cannot be started)\n"
"P00 DETAIL: sync path '" TEST_PATH "/pg/global'\n" "P00 DETAIL: sync path '" TEST_PATH "/pg/global'\n"
"P00 INFO: restore size = [SIZE], file total = 20"); "P00 INFO: restore size = [SIZE], file total = 21");
// Check stanza archive spool path was removed // Check stanza archive spool path was removed
TEST_STORAGE_LIST_EMPTY(storageSpool(), STORAGE_PATH_ARCHIVE); TEST_STORAGE_LIST_EMPTY(storageSpool(), STORAGE_PATH_ARCHIVE);