1
0
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:
Cynthia Shang
2019-09-30 12:39:38 -04:00
committed by David Steele
parent 33ec5a3aac
commit f96c54c4ba
8 changed files with 538 additions and 16 deletions

View File

@ -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();