pgbackrest.git / summary / log / commit / refs
commit e3fcd8cd9e0be42a32fc4cbd2ae3db2c072eabcd
Author: Stefan Fercot <stefan.fercot@enterprisedb.com>
Commit: GitHub <noreply@github.com>
Date: Thu Aug 31 20:36:52 2023 +0000
Add backup size completed/total to info command JSON output.
This allows for backup progress to be monitored by external processes, whereas before backup progress was only available via text output.
doc/xml/release.xml | 14 ++++++++++++++
src/command/backup/backup.c | 10 +++++++---
src/command/info/info.c | 16 ++++++++++++++--
src/common/lock.c | 16 ++++++++++++++++
src/common/lock.h | 6 +++++-
test/src/module/command/infoTest.c | 8 ++++++--
test/src/module/common/lockTest.c | 27 ++++++++++++++++++---------
7 files changed, 80 insertions(+), 17 deletions(-)
diff --git a/doc/xml/release.xml b/doc/xml/release.xml
index 1460d9922..35ec4c077 100644
--- a/doc/xml/release.xml
+++ b/doc/xml/release.xml
@@ -16,6 +16,20 @@
<release-list>
<release date="XXXX-XX-XX" version="2.48dev" title="Under Development">
<release-core-list>
+ <release-feature-list>
+ <release-item>
+ <github-issue id="2007"/>
+ <github-pull-request id="2141"/>
+
+ <release-item-contributor-list>
+ <release-item-contributor id="stefan.fercot"/>
+ <release-item-reviewer id="david.steele"/>
+ </release-item-contributor-list>
+
+ <p>Add backup size completed/total to <cmd>info</cmd> command <proper>JSON</proper> output.</p>
+ </release-item>
+ </release-feature-list>
+
<release-improvement-list>
<release-item>
<github-pull-request id="2057"/>
diff --git a/src/command/backup/backup.c b/src/command/backup/backup.c
index f74e19e87..1422d38d5 100644
--- a/src/command/backup/backup.c
+++ b/src/command/backup/backup.c
@@ -1585,7 +1585,9 @@ backupJobResult(
if (percentComplete - *currentPercentComplete > 10)
{
*currentPercentComplete = percentComplete;
- lockWriteDataP(lockTypeBackup, .percentComplete = VARUINT(*currentPercentComplete));
+ lockWriteDataP(
+ lockTypeBackup, .percentComplete = VARUINT(*currentPercentComplete), .sizeComplete = VARUINT64(*sizeProgress),
+ .size = VARUINT64(sizeTotal));
}
}
MEM_CONTEXT_TEMP_END();
@@ -2193,9 +2195,11 @@ backupProcess(
// Process jobs
uint64_t sizeProgress = 0;
- // Initialize the percent complete to zero
+ // Initialize percent complete and bytes completed/total
unsigned int currentPercentComplete = 0;
- lockWriteDataP(lockTypeBackup, .percentComplete = VARUINT(currentPercentComplete));
+ lockWriteDataP(
+ lockTypeBackup, .percentComplete = VARUINT(currentPercentComplete), .sizeComplete = VARUINT64(sizeProgress),
+ .size = VARUINT64(sizeTotal));
MEM_CONTEXT_TEMP_RESET_BEGIN()
{
diff --git a/src/command/info/info.c b/src/command/info/info.c
index 9f40f8e68..530490f7c 100644
--- a/src/command/info/info.c
+++ b/src/command/info/info.c
@@ -75,6 +75,8 @@ VARIANT_STRDEF_STATIC(STATUS_KEY_LOCK_VAR, "lock");
VARIANT_STRDEF_STATIC(STATUS_KEY_LOCK_BACKUP_VAR, "backup");
VARIANT_STRDEF_STATIC(STATUS_KEY_LOCK_BACKUP_HELD_VAR, "held");
VARIANT_STRDEF_STATIC(STATUS_KEY_LOCK_BACKUP_PERCENT_COMPLETE_VAR, "pct-cplt");
+VARIANT_STRDEF_STATIC(STATUS_KEY_LOCK_BACKUP_SIZE_COMPLETE_VAR, "size-cplt");
+VARIANT_STRDEF_STATIC(STATUS_KEY_LOCK_BACKUP_SIZE_VAR, "size");
VARIANT_STRDEF_STATIC(STATUS_KEY_MESSAGE_VAR, "message");
#define INFO_STANZA_STATUS_OK "ok"
@@ -134,6 +136,8 @@ typedef struct InfoStanzaRepo
bool backupLockChecked; // Has the check for a backup lock already been performed?
bool backupLockHeld; // Is backup lock held on the system where info command is run?
const Variant *percentComplete; // Percentage of backup complete * 100 (when not NULL)
+ const Variant *sizeComplete; // Completed size of the backup in bytes
+ const Variant *size; // Total size of the backup in bytes
InfoRepoData *repoList; // List of configured repositories
} InfoStanzaRepo;
@@ -239,6 +243,12 @@ stanzaStatus(const int code, const InfoStanzaRepo *const stanzaData, Variant *st
if (stanzaData->percentComplete != NULL && cfgOptionStrId(cfgOptOutput) != CFGOPTVAL_OUTPUT_JSON)
kvPut(backupLockKv, STATUS_KEY_LOCK_BACKUP_PERCENT_COMPLETE_VAR, stanzaData->percentComplete);
+ if (stanzaData->sizeComplete != NULL)
+ kvPut(backupLockKv, STATUS_KEY_LOCK_BACKUP_SIZE_COMPLETE_VAR, stanzaData->sizeComplete);
+
+ if (stanzaData->size != NULL)
+ kvPut(backupLockKv, STATUS_KEY_LOCK_BACKUP_SIZE_VAR, stanzaData->size);
+
FUNCTION_TEST_RETURN_VOID();
}
@@ -1290,8 +1300,10 @@ infoUpdateStanza(
if (stanzaRepo->backupLockHeld)
{
- stanzaRepo->percentComplete =
- lockRead(cfgOptionStr(cfgOptLockPath), stanzaRepo->name, lockTypeBackup).data.percentComplete;
+ const LockData lockData = lockRead(cfgOptionStr(cfgOptLockPath), stanzaRepo->name, lockTypeBackup).data;
+ stanzaRepo->percentComplete = lockData.percentComplete;
+ stanzaRepo->sizeComplete = lockData.sizeComplete;
+ stanzaRepo->size = lockData.size;
}
}
}
diff --git a/src/common/lock.c b/src/common/lock.c
index 5e27e3db4..76d049cff 100644
--- a/src/common/lock.c
+++ b/src/common/lock.c
@@ -35,6 +35,8 @@ Constants
#define LOCK_KEY_EXEC_ID STRID6("execId", 0x12e0c56051)
#define LOCK_KEY_PERCENT_COMPLETE STRID6("pctCplt", 0x14310a140d01)
#define LOCK_KEY_PROCESS_ID STRID5("pid", 0x11300)
+#define LOCK_KEY_SIZE_COMPLETE STRID6("szCplt", 0x50c4286931)
+#define LOCK_KEY_SIZE STRID5("sz", 0x3530)
/***********************************************************************************************************************************
Lock type names
@@ -152,6 +154,12 @@ lockReadFileData(const String *const lockFile, const int fd)
result.percentComplete = varNewUInt(jsonReadUInt(json));
result.processId = jsonReadInt(jsonReadKeyRequireStrId(json, LOCK_KEY_PROCESS_ID));
+
+ if (jsonReadKeyExpectStrId(json, LOCK_KEY_SIZE))
+ result.size = varNewUInt64(jsonReadUInt(json));
+
+ if (jsonReadKeyExpectStrId(json, LOCK_KEY_SIZE_COMPLETE))
+ result.sizeComplete = varNewUInt64(jsonReadUInt(json));
}
MEM_CONTEXT_PRIOR_END();
}
@@ -266,6 +274,8 @@ lockWriteData(const LockType lockType, const LockWriteDataParam param)
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(ENUM, lockType);
FUNCTION_LOG_PARAM(VARIANT, param.percentComplete);
+ FUNCTION_LOG_PARAM(VARIANT, param.sizeComplete);
+ FUNCTION_LOG_PARAM(VARIANT, param.size);
FUNCTION_LOG_END();
ASSERT(lockType < lockTypeAll);
@@ -285,6 +295,12 @@ lockWriteData(const LockType lockType, const LockWriteDataParam param)
jsonWriteInt(jsonWriteKeyStrId(json, LOCK_KEY_PROCESS_ID), getpid());
+ if (param.size != NULL)
+ jsonWriteUInt64(jsonWriteKeyStrId(json, LOCK_KEY_SIZE), varUInt64(param.size));
+
+ if (param.sizeComplete != NULL)
+ jsonWriteUInt64(jsonWriteKeyStrId(json, LOCK_KEY_SIZE_COMPLETE), varUInt64(param.sizeComplete));
+
jsonWriteObjectEnd(json);
if (lockType == lockTypeBackup && lockLocal.held)
diff --git a/src/common/lock.h b/src/common/lock.h
index 950c8fc87..48df7a409 100644
--- a/src/common/lock.h
+++ b/src/common/lock.h
@@ -24,7 +24,9 @@ typedef struct LockData
{
pid_t processId; // Process holding the lock
const String *execId; // Exec id of process holding the lock
- Variant *percentComplete; // Percentage of backup complete * 100 (when not NULL)
+ const Variant *percentComplete; // Percentage of backup complete * 100 (when not NULL)
+ const Variant *sizeComplete; // Completed size of the backup in bytes
+ const Variant *size; // Total size of the backup in bytes
} LockData;
#include "common/time.h"
@@ -65,6 +67,8 @@ typedef struct LockWriteDataParam
{
VAR_PARAM_HEADER;
const Variant *percentComplete; // Percentage of backup complete * 100 (when not NULL)
+ const Variant *sizeComplete; // Completed size of the backup in bytes
+ const Variant *size; // Total size of the backup in bytes
} LockWriteDataParam;
#define lockWriteDataP(lockType, ...) \
diff --git a/test/src/module/command/infoTest.c b/test/src/module/command/infoTest.c
index 86b2bd088..bd330b4f6 100644
--- a/test/src/module/command/infoTest.c
+++ b/test/src/module/command/infoTest.c
@@ -1025,7 +1025,11 @@ testRun(void)
{
lockInit(cfgOptionStr(cfgOptLockPath), STRDEF("999-ffffffff"), STRDEF("stanza2"), lockTypeBackup);
TEST_RESULT_INT_NE(lockAcquireP(), -1, "create backup/expire lock");
- TEST_RESULT_VOID(lockWriteDataP(lockTypeBackup, .percentComplete = VARUINT(4545)), "write lock data");
+ TEST_RESULT_VOID(
+ lockWriteDataP(
+ lockTypeBackup, .percentComplete = VARUINT(4545), .sizeComplete = VARUINT64(1435765),
+ .size = VARUINT64(3159000)),
+ "write lock data");
// Notify parent that lock has been acquired
HRN_FORK_CHILD_NOTIFY_PUT();
@@ -1365,7 +1369,7 @@ testRun(void)
"],"
"\"status\":{"
"\"code\":4,"
- "\"lock\":{\"backup\":{\"held\":true}},"
+ "\"lock\":{\"backup\":{\"held\":true,\"size\":3159000,\"size-cplt\":1435765}},"
"\"message\":\"different across repos\""
"}"
"},"
diff --git a/test/src/module/common/lockTest.c b/test/src/module/common/lockTest.c
index 5407ef444..cd042b15c 100644
--- a/test/src/module/common/lockTest.c
+++ b/test/src/module/common/lockTest.c
@@ -224,21 +224,30 @@ testRun(void)
TEST_RESULT_PTR(
lockReadFileData(backupLockFile, lockLocal.file[lockTypeBackup].fd).percentComplete, NULL, "verify percentComplete");
- TEST_RESULT_VOID(lockWriteDataP(lockTypeBackup, .percentComplete = VARUINT(5555)), "write lock data");
+ TEST_RESULT_VOID(
+ lockWriteDataP(
+ lockTypeBackup, .percentComplete = VARUINT(5555), .sizeComplete = VARUINT64(1754824), .size = VARUINT64(3159000)),
+ "write lock data");
+
THROW_ON_SYS_ERROR_FMT(
lseek(lockLocal.file[lockTypeBackup].fd, 0, SEEK_SET) == -1, FileOpenError, STORAGE_ERROR_READ_SEEK, (uint64_t)0,
strZ(lockLocal.file[lockTypeBackup].name));
- TEST_RESULT_UINT(
- varUInt(lockReadFileData(backupLockFile, lockLocal.file[lockTypeBackup].fd).percentComplete), 5555,
- "verify percentComplete");
-
- TEST_RESULT_VOID(lockWriteDataP(lockTypeBackup, .percentComplete = VARUINT(8888)), "write lock data");
+ LockData lockDataResult = lockReadFileData(backupLockFile, lockLocal.file[lockTypeBackup].fd);
+ TEST_RESULT_UINT(varUInt(lockDataResult.percentComplete), 5555, "verify percentComplete");
+ TEST_RESULT_UINT(varUInt64(lockDataResult.sizeComplete), 1754824, "verify sizeProgress");
+ TEST_RESULT_UINT(varUInt64(lockDataResult.size), 3159000, "verify sizeTotal");
+
+ TEST_RESULT_VOID(
+ lockWriteDataP(
+ lockTypeBackup, .percentComplete = VARUINT(8888), .sizeComplete = VARUINT64(2807719), .size = VARUINT64(3159000)),
+ "write lock data");
THROW_ON_SYS_ERROR_FMT(
lseek(lockLocal.file[lockTypeBackup].fd, 0, SEEK_SET) == -1, FileOpenError, STORAGE_ERROR_READ_SEEK, (uint64_t)0,
strZ(lockLocal.file[lockTypeBackup].name));
- TEST_RESULT_UINT(
- varUInt(lockReadFileData(backupLockFile, lockLocal.file[lockTypeBackup].fd).percentComplete), 8888,
- "verify percentComplete");
+ lockDataResult = lockReadFileData(backupLockFile, lockLocal.file[lockTypeBackup].fd);
+ TEST_RESULT_UINT(varUInt(lockDataResult.percentComplete), 8888, "verify percentComplete");
+ TEST_RESULT_UINT(varUInt64(lockDataResult.sizeComplete), 2807719, "verify sizeProgress");
+ TEST_RESULT_UINT(varUInt64(lockDataResult.size), 3159000, "verify sizeTotal");
TEST_ERROR(
lockAcquireP(.returnOnNoLock = true), AssertError,
[parent: fbd992adc7b1]