diff --git a/doc/xml/release/2020s/2026/2.60.0.xml b/doc/xml/release/2020s/2026/2.60.0.xml index a81cb65dc..e6fe9b827 100644 --- a/doc/xml/release/2020s/2026/2.60.0.xml +++ b/doc/xml/release/2020s/2026/2.60.0.xml @@ -63,6 +63,17 @@

Reduce the manifest checks made when reconstructing backup.info.

+ + + + + + + + +

Use original size to determine if a file should be bundled.

+
+ diff --git a/src/command/backup/process.c.inc b/src/command/backup/process.c.inc index 29b945606..66d3e33b8 100644 --- a/src/command/backup/process.c.inc +++ b/src/command/backup/process.c.inc @@ -389,9 +389,10 @@ backupProcessQueueComparator(const void *const item1, const void *const item2) const ManifestFile file1 = manifestFileUnpack(backupProcessQueueComparatorManifest, *(const ManifestFilePack *const *)item1); const ManifestFile file2 = manifestFileUnpack(backupProcessQueueComparatorManifest, *(const ManifestFilePack *const *)item2); - // A file is bundled when bundling is enabled and it is within the bundle limit; larger files are stored unbundled - const bool file1Bundle = backupProcessQueueComparatorBundle && file1.size <= backupProcessQueueComparatorBundleLimit; - const bool file2Bundle = backupProcessQueueComparatorBundle && file2.size <= backupProcessQueueComparatorBundleLimit; + // A file is bundled when bundling is enabled and it is within the bundle limit; larger files are stored unbundled. Use the + // original size since that is how many bytes will be copied -- size may have been set to the prior size during manifest build. + const bool file1Bundle = backupProcessQueueComparatorBundle && file1.sizeOriginal <= backupProcessQueueComparatorBundleLimit; + const bool file2Bundle = backupProcessQueueComparatorBundle && file2.sizeOriginal <= backupProcessQueueComparatorBundleLimit; // Order unbundled files (each copied as its own job) before bundled files if (file1Bundle != file2Bundle) @@ -401,9 +402,9 @@ backupProcessQueueComparator(const void *const item1, const void *const item2) // backup where one process is still copying a large file after the others are idle. This only matters when process-max > 1. if (!file1Bundle) { - if (file1.size < file2.size) + if (file1.sizeOriginal < file2.sizeOriginal) FUNCTION_TEST_RETURN(INT, 1); - else if (file1.size > file2.size) + else if (file1.sizeOriginal > file2.sizeOriginal) FUNCTION_TEST_RETURN(INT, -1); // If size is equal then use name to generate a deterministic ordering (names are unique) @@ -657,7 +658,7 @@ backupJobCallback(void *const data, const unsigned int clientIdx) { param = protocolPackNew(); - if (bundle && file.size <= jobData->bundleLimit) + if (bundle && file.sizeOriginal <= jobData->bundleLimit) { pckWriteStrP(param, backupFileRepoPathP(jobData->backupLabel, .bundleId = jobData->bundleId)); pckWriteU64P(param, jobData->bundleId); diff --git a/test/src/module/command/backupTest.c b/test/src/module/command/backupTest.c index 31c1bc373..0981445a0 100644 --- a/test/src/module/command/backupTest.c +++ b/test/src/module/command/backupTest.c @@ -3698,6 +3698,13 @@ testRun(void) HRN_STORAGE_PUT(storagePgWrite(), "grow-to-block-incr", file, .timeModified = backupTimeStart); + // Block incremental file within the bundle limit that will grow past it + file = bufNew(BLOCK_MIN_FILE_SIZE); + memset(bufPtr(file), 88, bufSize(file)); + bufUsedSet(file, bufSize(file)); + + HRN_STORAGE_PUT(storagePgWrite(), "grow-past-bundle-limit", file, .timeModified = backupTimeStart); + // Run backup hrnBackupPqScriptP(PG_VERSION_11, backupTimeStart, .walCompressType = compressTypeGz, .walTotal = 2, .walSwitch = true); TEST_RESULT_VOID(hrnCmdBackup(), "backup"); @@ -3722,17 +3729,18 @@ testRun(void) "P01 DETAIL: backup file " TEST_PATH "/pg1/block-incr-same (bundle 1/0, 16KB, [PCT]) checksum [SHA1]\n" "P01 DETAIL: backup file " TEST_PATH "/pg1/block-incr-shrink-below (bundle 1/16403, 16KB, [PCT]) checksum [SHA1]\n" "P01 DETAIL: backup file " TEST_PATH "/pg1/block-incr-shrink-block (bundle 1/32809, 16KB, [PCT]) checksum [SHA1]\n" - "P01 DETAIL: backup file " TEST_PATH "/pg1/block-incr-shrink (bundle 1/49215, 16KB, [PCT]) checksum [SHA1]\n" - "P01 DETAIL: backup file " TEST_PATH "/pg1/PG_VERSION (bundle 1/65629, 2B, [PCT]) checksum [SHA1]\n" - "P01 DETAIL: backup file " TEST_PATH "/pg1/normal-same (bundle 1/65631, 4B, [PCT]) checksum [SHA1]\n" - "P01 DETAIL: backup file " TEST_PATH "/pg1/grow-to-block-incr (bundle 1/65635, 16KB, [PCT]) checksum [SHA1]\n" - "P01 DETAIL: backup file " TEST_PATH "/pg1/global/pg_control (bundle 1/82018, 8KB, [PCT]) checksum [SHA1]\n" + "P01 DETAIL: backup file " TEST_PATH "/pg1/grow-past-bundle-limit (bundle 1/49215, 16KB, [PCT]) checksum [SHA1]\n" + "P01 DETAIL: backup file " TEST_PATH "/pg1/block-incr-shrink (bundle 1/65621, 16KB, [PCT]) checksum [SHA1]\n" + "P01 DETAIL: backup file " TEST_PATH "/pg1/PG_VERSION (bundle 1/82035, 2B, [PCT]) checksum [SHA1]\n" + "P01 DETAIL: backup file " TEST_PATH "/pg1/normal-same (bundle 1/82037, 4B, [PCT]) checksum [SHA1]\n" + "P01 DETAIL: backup file " TEST_PATH "/pg1/grow-to-block-incr (bundle 1/82041, 16KB, [PCT]) checksum [SHA1]\n" + "P01 DETAIL: backup file " TEST_PATH "/pg1/global/pg_control (bundle 1/98424, 8KB, [PCT]) checksum [SHA1]\n" "P00 INFO: execute backup stop and wait for all WAL segments to archive\n" "P00 INFO: backup stop archive = 0000000105DC08C000000001, lsn = 5dc08c0/300000\n" "P00 DETAIL: wrote 'backup_label' file returned from backup stop function\n" "P00 INFO: check archive for segment(s) 0000000105DC08C000000000:0000000105DC08C000000001\n" "P00 INFO: new backup label = 20191103-165320F\n" - "P00 INFO: full backup size = [SIZE], file total = 12"); + "P00 INFO: full backup size = [SIZE], file total = 13"); TEST_RESULT_STR_Z( testBackupValidateP(storageRepo(), STRDEF(STORAGE_REPO_BACKUP "/latest")), @@ -3743,6 +3751,7 @@ testRun(void) "bundle/1/pg_data/block-incr-shrink-below {s=16384, m=0:{0,1}}\n" "bundle/1/pg_data/block-incr-shrink-block {s=16384, m=0:{0,1}}\n" "bundle/1/pg_data/global/pg_control {s=8192}\n" + "bundle/1/pg_data/grow-past-bundle-limit {s=16384, m=0:{0,1}}\n" "bundle/1/pg_data/grow-to-block-incr {s=16383}\n" "bundle/1/pg_data/normal-same {s=4}\n" "pg_data/backup_label {s=17, ts=+2}\n" @@ -3838,6 +3847,14 @@ testRun(void) HRN_STORAGE_PUT(storagePgWrite(), "grow-to-block-incr", file, .timeModified = backupTimeStart); + // Grow file past the bundle limit. The prior size is within the limit but the file must be stored unbundled since the + // original size is what will be copied. + file = bufNew(BLOCK_MIN_FILE_SIZE * 2); + memset(bufPtr(file), 88, bufSize(file)); + bufUsedSet(file, bufSize(file)); + + HRN_STORAGE_PUT(storagePgWrite(), "grow-past-bundle-limit", file, .timeModified = backupTimeStart); + // File that gets truncated to zero during the backup HRN_STORAGE_PUT(storagePgWrite(), "truncate-to-zero", BUFSTRDEF("DATA"), .timeModified = backupTimeStart); @@ -3884,6 +3901,7 @@ testRun(void) "P00 INFO: backup '20191103-165320F_20191106-002640D' cannot be resumed: resume only valid for full backup\n" "P01 DETAIL: backup file " TEST_PATH "/pg1/block-incr-larger (1.4MB, [PCT]) checksum [SHA1]\n" "P01 DETAIL: backup file " TEST_PATH "/pg1/block-incr-grow (128KB, [PCT]) checksum [SHA1]\n" + "P01 DETAIL: backup file " TEST_PATH "/pg1/grow-past-bundle-limit (32KB, [PCT]) checksum [SHA1]\n" "P01 DETAIL: store truncated file " TEST_PATH "/pg1/block-incr-truncate (24KB->0B, [PCT])\n" "P01 DETAIL: backup file " TEST_PATH "/pg1/grow-to-block-incr (bundle 1/0, 16KB, [PCT]) checksum [SHA1]\n" "P01 DETAIL: match file from prior backup " TEST_PATH "/pg1/block-incr-same (16KB, [PCT]) checksum [SHA1]\n" @@ -3901,7 +3919,7 @@ testRun(void) "P00 DETAIL: wrote 'backup_label' file returned from backup stop function\n" "P00 INFO: check archive for segment(s) 0000000105DC213000000000:0000000105DC213000000001\n" "P00 INFO: new backup label = 20191103-165320F_20191106-002640D\n" - "P00 INFO: diff backup size = [SIZE], file total = 13"); + "P00 INFO: diff backup size = [SIZE], file total = 14"); TEST_RESULT_STR_Z( testBackupValidateP(storageRepo(), STRDEF(STORAGE_REPO_BACKUP "/latest")), @@ -3914,6 +3932,7 @@ testRun(void) "pg_data/backup_label {s=17, ts=+2}\n" "pg_data/block-incr-grow.pgbi {s=131072, m=0:{0},1:{0},0:{2},1:{1,2,3,4,5,6,7,8,9,10,11,12,13}}\n" "pg_data/block-incr-larger.pgbi {s=1507328, m=1:{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},1:{0,1,2,3,4,5,6}}\n" + "pg_data/grow-past-bundle-limit.pgbi {s=32768, m=0:{0,1},1:{0,1}}\n" "20191103-165320F/bundle/1/pg_data/PG_VERSION {s=2, ts=-200000}\n" "20191103-165320F/bundle/1/pg_data/block-incr-same {s=16384, m=0:{0,1}}\n" "20191103-165320F/bundle/1/pg_data/normal-same {s=4}\n" @@ -3929,6 +3948,7 @@ testRun(void) HRN_STORAGE_REMOVE(storagePgWrite(), "block-incr-shrink-below"); HRN_STORAGE_REMOVE(storagePgWrite(), "block-incr-shrink-block"); HRN_STORAGE_REMOVE(storagePgWrite(), "block-incr-truncate"); + HRN_STORAGE_REMOVE(storagePgWrite(), "grow-past-bundle-limit"); HRN_STORAGE_REMOVE(storagePgWrite(), "grow-to-block-incr"); HRN_STORAGE_REMOVE(storagePgWrite(), "normal-same"); HRN_STORAGE_REMOVE(storagePgWrite(), "truncate-to-zero");