From f7a7ab16c9652179945717ebf9b68af3aa8a0b0e Mon Sep 17 00:00:00 2001 From: David Steele Date: Sat, 2 Mar 2024 12:29:10 +1300 Subject: [PATCH] Skip zero-length files for block incremental delta restore. a42614e introduced the capability to preserve smaller than expected files for block incremental restore delta, but failed to take into account that zero-length files are both useless and cause the block checksum filter to error. Fix this by skipping zero-length files during block incremental restore delta. --- doc/xml/release/2024/2.51.xml | 16 ++++++++++++++++ doc/xml/release/contributor.xml | 10 ++++++++++ src/command/restore/file.c | 6 ++++-- test/src/module/command/restoreTest.c | 12 ++++++++++++ 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/doc/xml/release/2024/2.51.xml b/doc/xml/release/2024/2.51.xml index 52133f961..43ae80a2a 100644 --- a/doc/xml/release/2024/2.51.xml +++ b/doc/xml/release/2024/2.51.xml @@ -1,5 +1,21 @@ + + + + + + + + + + + + +

Skip zero-length files for block incremental delta restore.

+
+
+ diff --git a/doc/xml/release/contributor.xml b/doc/xml/release/contributor.xml index 75773f022..fe9edaf1a 100644 --- a/doc/xml/release/contributor.xml +++ b/doc/xml/release/contributor.xml @@ -855,6 +855,11 @@ vidierr + + René Højbjerg Larsen + rhl-jfm + + Robert Donovan rob-donovan @@ -910,6 +915,11 @@ slardiere + + Sebastian Krause + sekrause + + Seth Daniel sethdaniel diff --git a/src/command/restore/file.c b/src/command/restore/file.c index 7f25abee7..d59a6a338 100644 --- a/src/command/restore/file.c +++ b/src/command/restore/file.c @@ -88,8 +88,10 @@ restoreFile( // Else use size and checksum else { - // Only continue delta if the file size is as expected or larger - if (info.size >= file->size || file->blockIncrMapSize != 0) + // Only continue delta if the file size is as expected or larger (for normal files) or if block + // incremental and the file to delta is not zero-length. Block incremental can potentially use almost + // any portion of an existing file, but of course zero-length files do not have anything to reuse. + if (info.size >= file->size || (file->blockIncrMapSize != 0 && info.size != 0)) { const char *const fileName = strZ(storagePathP(storagePg(), file->name)); diff --git a/test/src/module/command/restoreTest.c b/test/src/module/command/restoreTest.c index 52910a7c4..766a10d0b 100644 --- a/test/src/module/command/restoreTest.c +++ b/test/src/module/command/restoreTest.c @@ -3165,6 +3165,13 @@ testRun(void) HRN_STORAGE_PUT(storagePgWrite(), PG_PATH_BASE "/1/2", relation, .timeModified = timeBase - 2); + // Zeroed file large enough to use block incr (that will be truncated to zero before restore) + relation = bufNew(16 * 1024); + memset(bufPtr(relation), 0, bufSize(relation)); + bufUsedSet(relation, bufSize(relation)); + + HRN_STORAGE_PUT(storagePgWrite(), PG_PATH_BASE "/1/44", relation, .timeModified = timeBase - 2); + // Add postgresql.auto.conf to contain recovery settings HRN_STORAGE_PUT_EMPTY(storagePgWrite(), PG_FILE_POSTGRESQLAUTOCONF, .timeModified = timeBase - 1); @@ -3234,6 +3241,7 @@ testRun(void) "base/1/\n" "base/1/2\n" "base/1/3\n" + "base/1/44\n" "global/\n" "global/pg_control\n" "postgresql.auto.conf\n", @@ -3245,6 +3253,9 @@ testRun(void) // Use detail log level to catch block incremental restore message harnessLogLevelSet(logLevelDetail); + // Truncate file to ensure delta is skipped + HRN_STORAGE_PUT_EMPTY(storagePgWrite(), PG_PATH_BASE "/1/44"); + // Shrink file to make sure block incremental delta will reuse it relation = bufNew(128 * 1024); memset(bufPtr(relation), 0, bufSize(relation)); @@ -3271,6 +3282,7 @@ testRun(void) "base/1/\n" "base/1/2\n" "base/1/3\n" + "base/1/44\n" "global/\n" "global/pg_control\n" "postgresql.auto.conf\n",