You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-07-09 00:45:49 +02:00
Add info command set option for detailed text output.
The additional details include databases that can be used for selective restore and a list of tablespaces and symlinks with their default destinations. This information is not included in the JSON output because it requires reading the manifest which is too IO intensive to do for all manifests. We plan to include this information for JSON in a future release.
This commit is contained in:
committed by
David Steele
parent
33ec5a3aac
commit
f96c54c4ba
@ -410,6 +410,130 @@ testRun(void)
|
||||
storagePutNP(storageNewWriteNP(storageLocalWrite(), strNewFmt("%s/backup.info", strPtr(backupStanza1Path))),
|
||||
harnessInfoChecksum(content)), "put backup info to file - stanza1");
|
||||
|
||||
// Manifest with all features
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
#define TEST_MANIFEST_HEADER \
|
||||
"[backup]\n" \
|
||||
"backup-archive-start=\"000000030000028500000089\"\n" \
|
||||
"backup-archive-stop=\"000000030000028500000089\"\n" \
|
||||
"backup-label=\"20190818-084502F_20190820-084502D\"\n" \
|
||||
"backup-lsn-start=\"285/89000028\"\n" \
|
||||
"backup-lsn-stop=\"285/89001F88\"\n" \
|
||||
"backup-prior=\"20190818-084502F\"\n" \
|
||||
"backup-timestamp-copy-start=1565282141\n" \
|
||||
"backup-timestamp-start=1565282140\n" \
|
||||
"backup-timestamp-stop=1565282142\n" \
|
||||
"backup-type=\"full\"\n" \
|
||||
"\n" \
|
||||
"[backup:db]\n" \
|
||||
"db-catalog-version=201409291\n" \
|
||||
"db-control-version=942\n" \
|
||||
"db-id=1\n" \
|
||||
"db-system-id=1000000000000000094\n" \
|
||||
"db-version=\"9.4\"\n" \
|
||||
"\n" \
|
||||
"[backup:option]\n" \
|
||||
"option-archive-check=true\n" \
|
||||
"option-archive-copy=true\n" \
|
||||
"option-backup-standby=false\n" \
|
||||
"option-buffer-size=16384\n" \
|
||||
"option-checksum-page=true\n" \
|
||||
"option-compress=false\n" \
|
||||
"option-compress-level=3\n" \
|
||||
"option-compress-level-network=3\n" \
|
||||
"option-delta=false\n" \
|
||||
"option-hardlink=false\n" \
|
||||
"option-online=false\n" \
|
||||
"option-process-max=32\n"
|
||||
|
||||
#define TEST_MANIFEST_TARGET \
|
||||
"\n" \
|
||||
"[backup:target]\n" \
|
||||
"pg_data={\"path\":\"/pg/base\",\"type\":\"path\"}\n" \
|
||||
"pg_data/pg_hba.conf={\"file\":\"pg_hba.conf\",\"path\":\"../pg_config\",\"type\":\"link\"}\n" \
|
||||
"pg_data/pg_stat={\"path\":\"../pg_stat\",\"type\":\"link\"}\n" \
|
||||
"pg_tblspc/1={\"path\":\"/tblspc/ts1\",\"tablespace-id\":\"1\",\"tablespace-name\":\"ts1\",\"type\":\"link\"}\n" \
|
||||
"pg_tblspc/12={\"path\":\"/tblspc/ts12\",\"tablespace-id\":\"12\",\"tablespace-name\":\"ts12\",\"type\":\"link\"}\n"
|
||||
|
||||
#define TEST_MANIFEST_DB \
|
||||
"\n" \
|
||||
"[db]\n" \
|
||||
"mail={\"db-id\":16456,\"db-last-system-id\":12168}\n" \
|
||||
"postgres={\"db-id\":12173,\"db-last-system-id\":12168}\n" \
|
||||
"template0={\"db-id\":12168,\"db-last-system-id\":12168}\n" \
|
||||
"template1={\"db-id\":1,\"db-last-system-id\":12168}\n" \
|
||||
|
||||
#define TEST_MANIFEST_FILE \
|
||||
"\n" \
|
||||
"[target:file]\n" \
|
||||
"pg_data/PG_VERSION={\"checksum\":\"184473f470864e067ee3a22e64b47b0a1c356f29\",\"master\":true" \
|
||||
",\"reference\":\"20190818-084502F_20190819-084506D\",\"size\":4,\"timestamp\":1565282114}\n" \
|
||||
"pg_data/base/16384/17000={\"checksum\":\"e0101dd8ffb910c9c202ca35b5f828bcb9697bed\",\"checksum-page\":false" \
|
||||
",\"checksum-page-error\":[1],\"repo-size\":4096,\"size\":8192,\"timestamp\":1565282114}\n" \
|
||||
"pg_data/base/16384/PG_VERSION={\"checksum\":\"184473f470864e067ee3a22e64b47b0a1c356f29\",\"group\":false,\"size\":4" \
|
||||
",\"timestamp\":1565282115}\n" \
|
||||
"pg_data/base/32768/33000={\"checksum\":\"7a16d165e4775f7c92e8cdf60c0af57313f0bf90\",\"checksum-page\":true" \
|
||||
",\"reference\":\"20190818-084502F\",\"size\":1073741824,\"timestamp\":1565282116}\n" \
|
||||
"pg_data/base/32768/33000.32767={\"checksum\":\"6e99b589e550e68e934fd235ccba59fe5b592a9e\",\"checksum-page\":true" \
|
||||
",\"reference\":\"20190818-084502F\",\"size\":32768,\"timestamp\":1565282114}\n" \
|
||||
"pg_data/postgresql.conf={\"checksum\":\"6721d92c9fcdf4248acff1f9a1377127d9064807\",\"master\":true,\"size\":4457" \
|
||||
",\"timestamp\":1565282114}\n" \
|
||||
"pg_data/special={\"master\":true,\"mode\":\"0640\",\"size\":0,\"timestamp\":1565282120,\"user\":false}\n"
|
||||
|
||||
#define TEST_MANIFEST_FILE_DEFAULT \
|
||||
"\n" \
|
||||
"[target:file:default]\n" \
|
||||
"group=\"group1\"\n" \
|
||||
"master=false\n" \
|
||||
"mode=\"0600\"\n" \
|
||||
"user=\"user1\"\n"
|
||||
|
||||
#define TEST_MANIFEST_LINK \
|
||||
"\n" \
|
||||
"[target:link]\n" \
|
||||
"pg_data/pg_stat={\"destination\":\"../pg_stat\"}\n" \
|
||||
"pg_data/postgresql.conf={\"destination\":\"../pg_config/postgresql.conf\",\"group\":false,\"user\":\"user1\"}\n"
|
||||
|
||||
#define TEST_MANIFEST_LINK_DEFAULT \
|
||||
"\n" \
|
||||
"[target:link:default]\n" \
|
||||
"group=\"group1\"\n" \
|
||||
"user=false\n"
|
||||
|
||||
#define TEST_MANIFEST_PATH \
|
||||
"\n" \
|
||||
"[target:path]\n" \
|
||||
"pg_data={\"user\":\"user2\"}\n" \
|
||||
"pg_data/base={\"group\":\"group2\"}\n" \
|
||||
"pg_data/base/16384={\"mode\":\"0750\"}\n" \
|
||||
"pg_data/base/32768={}\n" \
|
||||
"pg_data/base/65536={\"user\":false}\n"
|
||||
|
||||
#define TEST_MANIFEST_PATH_DEFAULT \
|
||||
"\n" \
|
||||
"[target:path:default]\n" \
|
||||
"group=false\n" \
|
||||
"mode=\"0700\"\n" \
|
||||
"user=\"user1\"\n"
|
||||
|
||||
const Buffer *contentLoad = harnessInfoChecksumZ
|
||||
(
|
||||
TEST_MANIFEST_HEADER
|
||||
TEST_MANIFEST_TARGET
|
||||
TEST_MANIFEST_DB
|
||||
TEST_MANIFEST_FILE
|
||||
TEST_MANIFEST_FILE_DEFAULT
|
||||
TEST_MANIFEST_LINK
|
||||
TEST_MANIFEST_LINK_DEFAULT
|
||||
TEST_MANIFEST_PATH
|
||||
TEST_MANIFEST_PATH_DEFAULT
|
||||
);
|
||||
|
||||
TEST_RESULT_VOID(
|
||||
storagePutNP(storageNewWriteNP(storageLocalWrite(),
|
||||
strNewFmt("%s/20181119-152138F_20181119-152152I/" BACKUP_MANIFEST_FILE, strPtr(backupStanza1Path))), contentLoad),
|
||||
"write manifest - stanza1");
|
||||
|
||||
String *archiveStanza2Path = strNewFmt("%s/stanza2", strPtr(archivePath));
|
||||
String *backupStanza2Path = strNewFmt("%s/stanza2", strPtr(backupPath));
|
||||
TEST_RESULT_VOID(storagePathCreateNP(storageLocalWrite(), backupStanza1Path), "backup stanza2 directory");
|
||||
@ -651,6 +775,142 @@ testRun(void)
|
||||
" wal archive min/max (9.4-1): none present\n"
|
||||
, "text - multiple stanzas, one with valid backups, archives in latest DB");
|
||||
|
||||
// Backup set requested
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
argList2 = strLstDup(argListText);
|
||||
strLstAddZ(argList2, "--stanza=stanza1");
|
||||
strLstAddZ(argList2, "--set=20181119-152138F_20181119-152152I");
|
||||
harnessCfgLoad(strLstSize(argList2), strLstPtr(argList2));
|
||||
|
||||
TEST_RESULT_STR(strPtr(infoRender()),
|
||||
|
||||
"stanza: stanza1\n"
|
||||
" status: ok\n"
|
||||
" cipher: none\n"
|
||||
"\n"
|
||||
" db (prior)\n"
|
||||
" wal archive min/max (9.4-1): 000000010000000000000002/000000020000000000000003\n"
|
||||
"\n"
|
||||
" incr backup: 20181119-152138F_20181119-152152I\n"
|
||||
" timestamp start/stop: 2018-11-19 15:21:52 / 2018-11-19 15:21:55\n"
|
||||
" wal start/stop: n/a\n"
|
||||
" database size: 19.2MB, backup size: 8.2KB\n"
|
||||
" repository size: 2.3MB, repository backup size: 346B\n"
|
||||
" backup reference list: 20181119-152138F, 20181119-152138F_20181119-152152D\n"
|
||||
" database list: mail (16456), postgres (12173)\n"
|
||||
" symlinks:\n"
|
||||
" pg_hba.conf => ../pg_config/pg_hba.conf\n"
|
||||
" pg_stat => ../pg_stat\n"
|
||||
" tablespaces:\n"
|
||||
" ts1 (1) => /tblspc/ts1\n"
|
||||
" ts12 (12) => /tblspc/ts12\n"
|
||||
, "text - backup set requested");
|
||||
|
||||
strLstAddZ(argList2, "--output=json");
|
||||
harnessCfgLoad(strLstSize(argList2), strLstPtr(argList2));
|
||||
|
||||
TEST_ERROR(strPtr(infoRender()), ConfigError, "option 'set' is currently only valid for text output");
|
||||
|
||||
// Backup set requested but no links
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
argList2 = strLstDup(argListText);
|
||||
strLstAddZ(argList2, "--stanza=stanza1");
|
||||
strLstAddZ(argList2, "--set=20181119-152138F_20181119-152152I");
|
||||
harnessCfgLoad(strLstSize(argList2), strLstPtr(argList2));
|
||||
|
||||
#define TEST_MANIFEST_TARGET_NO_LINK \
|
||||
"\n" \
|
||||
"[backup:target]\n" \
|
||||
"pg_data={\"path\":\"/pg/base\",\"type\":\"path\"}\n" \
|
||||
|
||||
contentLoad = harnessInfoChecksumZ
|
||||
(
|
||||
TEST_MANIFEST_HEADER
|
||||
TEST_MANIFEST_TARGET_NO_LINK
|
||||
TEST_MANIFEST_DB
|
||||
TEST_MANIFEST_FILE
|
||||
TEST_MANIFEST_FILE_DEFAULT
|
||||
TEST_MANIFEST_LINK
|
||||
TEST_MANIFEST_LINK_DEFAULT
|
||||
TEST_MANIFEST_PATH
|
||||
TEST_MANIFEST_PATH_DEFAULT
|
||||
);
|
||||
|
||||
TEST_RESULT_VOID(
|
||||
storagePutNP(
|
||||
storageNewWriteNP(
|
||||
storageRepoWrite(), strNew(STORAGE_REPO_BACKUP "/20181119-152138F_20181119-152152I/" BACKUP_MANIFEST_FILE)),
|
||||
contentLoad),
|
||||
"write manifest");
|
||||
|
||||
TEST_RESULT_STR(strPtr(infoRender()),
|
||||
"stanza: stanza1\n"
|
||||
" status: ok\n"
|
||||
" cipher: none\n"
|
||||
"\n"
|
||||
" db (prior)\n"
|
||||
" wal archive min/max (9.4-1): 000000010000000000000002/000000020000000000000003\n"
|
||||
"\n"
|
||||
" incr backup: 20181119-152138F_20181119-152152I\n"
|
||||
" timestamp start/stop: 2018-11-19 15:21:52 / 2018-11-19 15:21:55\n"
|
||||
" wal start/stop: n/a\n"
|
||||
" database size: 19.2MB, backup size: 8.2KB\n"
|
||||
" repository size: 2.3MB, repository backup size: 346B\n"
|
||||
" backup reference list: 20181119-152138F, 20181119-152138F_20181119-152152D\n"
|
||||
" database list: mail (16456), postgres (12173)\n"
|
||||
, "text - backup set requested, no links");
|
||||
|
||||
|
||||
// Backup set requested but no databases
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
argList2 = strLstDup(argListText);
|
||||
strLstAddZ(argList2, "--stanza=stanza1");
|
||||
strLstAddZ(argList2, "--set=20181119-152138F_20181119-152152I");
|
||||
harnessCfgLoad(strLstSize(argList2), strLstPtr(argList2));
|
||||
|
||||
#define TEST_MANIFEST_NO_DB \
|
||||
"\n" \
|
||||
"[db]\n" \
|
||||
"template0={\"db-id\":12168,\"db-last-system-id\":12168}\n" \
|
||||
"template1={\"db-id\":1,\"db-last-system-id\":12168}\n" \
|
||||
|
||||
contentLoad = harnessInfoChecksumZ
|
||||
(
|
||||
TEST_MANIFEST_HEADER
|
||||
TEST_MANIFEST_TARGET_NO_LINK
|
||||
TEST_MANIFEST_NO_DB
|
||||
TEST_MANIFEST_FILE
|
||||
TEST_MANIFEST_FILE_DEFAULT
|
||||
TEST_MANIFEST_LINK
|
||||
TEST_MANIFEST_LINK_DEFAULT
|
||||
TEST_MANIFEST_PATH
|
||||
TEST_MANIFEST_PATH_DEFAULT
|
||||
);
|
||||
|
||||
TEST_RESULT_VOID(
|
||||
storagePutNP(
|
||||
storageNewWriteNP(
|
||||
storageRepoWrite(), strNew(STORAGE_REPO_BACKUP "/20181119-152138F_20181119-152152I/" BACKUP_MANIFEST_FILE)),
|
||||
contentLoad),
|
||||
"write manifest");
|
||||
|
||||
TEST_RESULT_STR(strPtr(infoRender()),
|
||||
"stanza: stanza1\n"
|
||||
" status: ok\n"
|
||||
" cipher: none\n"
|
||||
"\n"
|
||||
" db (prior)\n"
|
||||
" wal archive min/max (9.4-1): 000000010000000000000002/000000020000000000000003\n"
|
||||
"\n"
|
||||
" incr backup: 20181119-152138F_20181119-152152I\n"
|
||||
" timestamp start/stop: 2018-11-19 15:21:52 / 2018-11-19 15:21:55\n"
|
||||
" wal start/stop: n/a\n"
|
||||
" database size: 19.2MB, backup size: 8.2KB\n"
|
||||
" repository size: 2.3MB, repository backup size: 346B\n"
|
||||
" backup reference list: 20181119-152138F, 20181119-152138F_20181119-152152D\n"
|
||||
" database list: none\n"
|
||||
, "text - backup set requested, no db");
|
||||
|
||||
// Stanza not found
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
argList2 = strLstDup(argList);
|
||||
@ -790,7 +1050,7 @@ testRun(void)
|
||||
kvPut(stanzaInfo, KEY_ARCHIVE_VAR, varNewVarLst(varLstNew()));
|
||||
|
||||
String *result = strNew("");
|
||||
formatTextDb(stanzaInfo, result);
|
||||
formatTextDb(stanzaInfo, result, NULL);
|
||||
|
||||
TEST_RESULT_STR(strPtr(result),
|
||||
"\n"
|
||||
@ -832,6 +1092,21 @@ testRun(void)
|
||||
TEST_RESULT_STR(
|
||||
strPtr(strNewBuf(storageGetNP(storageNewReadNP(storage, stdoutFile)))), "No stanzas exist in the repository.\n",
|
||||
" check text");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
strLstAddZ(argList, "--set=bogus");
|
||||
|
||||
TEST_ERROR_FMT(
|
||||
harnessCfgLoad(strLstSize(argList), strLstPtr(argList)), OptionInvalidError,
|
||||
"option 'set' not valid without option 'stanza'");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
strLstAddZ(argList, "--stanza=stanza1");
|
||||
harnessCfgLoad(strLstSize(argList), strLstPtr(argList));
|
||||
|
||||
TEST_ERROR_FMT(
|
||||
cmdInfo(), FileMissingError, "manifest does not exist for backup 'bogus'\n"
|
||||
"HINT: is the backup listed when running the info command with --stanza option only?");
|
||||
}
|
||||
|
||||
FUNCTION_HARNESS_RESULT_VOID();
|
||||
|
Reference in New Issue
Block a user