You've already forked pgbackrest
							
							
				mirror of
				https://github.com/pgbackrest/pgbackrest.git
				synced 2025-10-30 23:37:45 +02:00 
			
		
		
		
	Add/remove dependent backups during backup.info reconstruct.
Prior to performing a backup or expiring backups, the backup.info file is validated by reconstructing it from the backups in the repository. When a backup had already been removed from the repo, it was removed from the backup.info file but its dependents were not. Now, the dependent backups will also be removed from backup.info and only backups in the repo that have their full dependency chain will be added to backup.info if they are missing.
This commit is contained in:
		
				
					committed by
					
						 David Steele
						David Steele
					
				
			
			
				
	
			
			
			
						parent
						
							f3ae74b0d6
						
					
				
				
					commit
					3fbde30c6f
				
			| @@ -694,9 +694,34 @@ infoBackupLoadFileReconstruct(const Storage *storage, const String *fileName, Ci | ||||
|                 .expression = backupRegExpP(.full = true, .differential = true, .incremental = true)), | ||||
|             sortOrderAsc); | ||||
|  | ||||
|         // Get the current list of backups from backup.info | ||||
|         // Get the list of current backups and remove backups from current that are no longer in the repository | ||||
|         StringList *backupCurrentList = strLstSort(infoBackupDataLabelList(infoBackup, NULL), sortOrderAsc); | ||||
|  | ||||
|         for (unsigned int backupCurrIdx = 0; backupCurrIdx < strLstSize(backupCurrentList); backupCurrIdx++) | ||||
|         { | ||||
|             String *backupLabel = strLstGet(backupCurrentList, backupCurrIdx); | ||||
|             String *manifestFileName = strNewFmt(STORAGE_REPO_BACKUP "/%s/" BACKUP_MANIFEST_FILE, strPtr(backupLabel)); | ||||
|  | ||||
|             // If the manifest does not exist on disk and this backup has not already been deleted from the current list in the | ||||
|             // infoBackup object, then remove it and its dependencies | ||||
|             if (!storageExistsP(storage, manifestFileName) && infoBackupDataByLabel(infoBackup, backupLabel) != NULL) | ||||
|             { | ||||
|                 StringList *backupList = strLstSort(infoBackupDataDependentList(infoBackup, backupLabel), sortOrderDesc); | ||||
|  | ||||
|                 for (unsigned int backupIdx = 0; backupIdx < strLstSize(backupList); backupIdx++) | ||||
|                 { | ||||
|                     String *removeBackup = strLstGet(backupList, backupIdx); | ||||
|  | ||||
|                     LOG_WARN_FMT("backup '%s' missing manifest removed from " INFO_BACKUP_FILE, strPtr(removeBackup)); | ||||
|  | ||||
|                     infoBackupDataDelete(infoBackup, removeBackup); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Get the updated current list of backups from backup.info | ||||
|         backupCurrentList = strLstSort(infoBackupDataLabelList(infoBackup, NULL), sortOrderAsc); | ||||
|  | ||||
|         // For each backup in the repo, check if it exists in backup.info | ||||
|         for (unsigned int backupIdx = 0; backupIdx < strLstSize(backupList); backupIdx++) | ||||
|         { | ||||
| @@ -721,9 +746,12 @@ infoBackupLoadFileReconstruct(const Storage *storage, const String *fileName, Ci | ||||
|                     { | ||||
|                         InfoPgData pgHistory = infoPgData(infoBackup->infoPg, pgIdx); | ||||
|  | ||||
|                         // If there is an exact match with the history, system and version then add it to the current backup list | ||||
|                         // If there is an exact match with the history, system and version and there is no backup-prior dependency | ||||
|                         // or there is a backup-prior and it is in the list, then add this backup to the current backup list | ||||
|                         if (manData->pgId == pgHistory.id && manData->pgSystemId == pgHistory.systemId && | ||||
|                             manData->pgVersion == pgHistory.version) | ||||
|                             manData->pgVersion == pgHistory.version && | ||||
|                             (manData->backupLabelPrior == NULL || | ||||
|                                 infoBackupDataByLabel(infoBackup, manData->backupLabelPrior) != NULL)) | ||||
|                         { | ||||
|                             LOG_WARN_FMT("backup '%s' found in repository added to " INFO_BACKUP_FILE, strPtr(backupLabel)); | ||||
|                             infoBackupDataAdd(infoBackup, manifest); | ||||
| @@ -737,22 +765,6 @@ infoBackupLoadFileReconstruct(const Storage *storage, const String *fileName, Ci | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Get the updated list of current backups and remove backups from current that are no longer in the repository | ||||
|         backupCurrentList = infoBackupDataLabelList(infoBackup, NULL); | ||||
|  | ||||
|         for (unsigned int backupCurrIdx = 0; backupCurrIdx < strLstSize(backupCurrentList); backupCurrIdx++) | ||||
|         { | ||||
|             String *backupLabel = strLstGet(backupCurrentList, backupCurrIdx); | ||||
|             String *manifestFileName = strNewFmt(STORAGE_REPO_BACKUP "/%s/" BACKUP_MANIFEST_FILE, strPtr(backupLabel)); | ||||
|  | ||||
|             // Remove backup from the current list in the infoBackup object | ||||
|             if (!storageExistsP(storage, manifestFileName)) | ||||
|             { | ||||
|                 LOG_WARN_FMT("backup '%s' missing manifest removed from " INFO_BACKUP_FILE, strPtr(backupLabel)); | ||||
|                 infoBackupDataDelete(infoBackup, backupLabel); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     MEM_CONTEXT_TEMP_END(); | ||||
|  | ||||
|   | ||||
| @@ -335,7 +335,7 @@ testRun(void) | ||||
|             "template0={\"db-id\":12168,\"db-last-system-id\":12168}\n"                                                            \ | ||||
|             "template1={\"db-id\":1,\"db-last-system-id\":12168}\n"                                                                \ | ||||
|  | ||||
|         manifestContent = harnessInfoChecksumZ | ||||
|         const Buffer *manifestContentIncr = harnessInfoChecksumZ | ||||
|         ( | ||||
|             "[backup]\n" | ||||
|             "backup-archive-start=\"000000030000028500000089\"\n" | ||||
| @@ -405,7 +405,7 @@ testRun(void) | ||||
|             TEST_MANIFEST_PATH_DEFAULT | ||||
|         ); | ||||
|  | ||||
|         TEST_ASSIGN(manifest, manifestNewLoad(ioBufferReadNew(manifestContent)), "load manifest"); | ||||
|         TEST_ASSIGN(manifest, manifestNewLoad(ioBufferReadNew(manifestContentIncr)), "load manifest"); | ||||
|         TEST_RESULT_VOID(infoBackupDataAdd(infoBackup, manifest), "add a backup"); | ||||
|         TEST_RESULT_UINT(infoBackupDataTotal(infoBackup), 2, "backup added to current"); | ||||
|         TEST_ASSIGN(backupData, infoBackupData(infoBackup, 1), "get added backup"); | ||||
| @@ -668,6 +668,11 @@ testRun(void) | ||||
|             strNew(STORAGE_REPO_BACKUP "/20190818-084777F/" BACKUP_MANIFEST_FILE)), | ||||
|             manifestContent), "write manifest - invalid backup version mismatch"); | ||||
|  | ||||
|         TEST_RESULT_VOID( | ||||
|             storagePutP(storageNewWriteP(storageRepoWrite(), | ||||
|             strNew(STORAGE_REPO_BACKUP "/20190818-084502F_20190820-084502I/" BACKUP_MANIFEST_FILE)), | ||||
|             manifestContentIncr), "write manifest for dependent backup that will be removed from backup.info"); | ||||
|  | ||||
|         TEST_RESULT_VOID( | ||||
|             storagePathCreateP(storageRepoWrite(), strNew(STORAGE_REPO_BACKUP "/20190818-084502F")), | ||||
|             "create backup on disk that is in current but no manifest"); | ||||
| @@ -680,8 +685,8 @@ testRun(void) | ||||
|                         .expression = backupRegExpP(.full = true, .differential = true, .incremental = true)), | ||||
|                     sortOrderAsc), | ||||
|                 ", "), | ||||
|             "20190818-084444F, 20190818-084502F, 20190818-084555F, 20190818-084666F, 20190818-084777F, 20190923-164324F", | ||||
|             "confirm backups on disk"); | ||||
|             "20190818-084444F, 20190818-084502F, 20190818-084502F_20190820-084502I, 20190818-084555F, 20190818-084666F, " | ||||
|             "20190818-084777F, 20190923-164324F", "confirm backups on disk"); | ||||
|  | ||||
|         // With the infoBackup from above, upgrade the DB so there a 2 histories then save to disk | ||||
|         TEST_ASSIGN(infoBackup, infoBackupPgSet(infoBackup, PG_VERSION_11, 6739907367085689196), "upgrade db"); | ||||
| @@ -701,34 +706,100 @@ testRun(void) | ||||
|         TEST_RESULT_INT(infoBackupDataTotal(infoBackup), 1, "backup list contains 1 backup"); | ||||
|         TEST_ASSIGN(backupData, infoBackupData(infoBackup, 0), "get the backup"); | ||||
|         TEST_RESULT_STR_Z( | ||||
|             backupData.backupLabel, "20190923-164324F", | ||||
|             "backups not on disk removed, valid backup on disk added, manifest copy-only ignored"); | ||||
|             backupData.backupLabel, "20190923-164324F", "backups not on disk removed, dependent backup removed and not added back, " | ||||
|             "valid backup on disk added, manifest copy-only ignored"); | ||||
|         harnessLogResult( | ||||
|             "P00   WARN: backup '20190818-084502F_20190820-084502I' missing manifest removed from backup.info\n" | ||||
|             "P00   WARN: backup '20190818-084502F' missing manifest removed from backup.info\n" | ||||
|             "P00   WARN: invalid backup '20190818-084502F_20190820-084502I' cannot be added to current backups\n" | ||||
|             "P00   WARN: invalid backup '20190818-084555F' cannot be added to current backups\n" | ||||
|             "P00   WARN: invalid backup '20190818-084666F' cannot be added to current backups\n" | ||||
|             "P00   WARN: invalid backup '20190818-084777F' cannot be added to current backups\n" | ||||
|             "P00   WARN: backup '20190923-164324F' found in repository added to backup.info\n" | ||||
|             "P00   WARN: backup '20190818-084502F' missing manifest removed from backup.info\n" | ||||
|             "P00   WARN: backup '20190818-084502F_20190820-084502I' missing manifest removed from backup.info"); | ||||
|             "P00   WARN: backup '20190923-164324F' found in repository added to backup.info"); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         TEST_RESULT_VOID( | ||||
|             storagePathRemoveP(storageRepoWrite(), strNew(STORAGE_REPO_BACKUP "/20190818-084502F_20190820-084502I"), | ||||
|             .recurse = true), "remove dependent backup from disk"); | ||||
|         TEST_ASSIGN( | ||||
|             infoBackup, infoBackupLoadFileReconstruct(storageRepo(), INFO_BACKUP_PATH_FILE_STR, cipherTypeNone, NULL), | ||||
|             "reconstruct does not attempt to add back dependent backup"); | ||||
|         harnessLogResult( | ||||
|             "P00   WARN: backup '20190818-084502F_20190820-084502I' missing manifest removed from backup.info\n" | ||||
|             "P00   WARN: backup '20190818-084502F' missing manifest removed from backup.info\n" | ||||
|             "P00   WARN: invalid backup '20190818-084555F' cannot be added to current backups\n" | ||||
|             "P00   WARN: invalid backup '20190818-084666F' cannot be added to current backups\n" | ||||
|             "P00   WARN: invalid backup '20190818-084777F' cannot be added to current backups\n" | ||||
|             "P00   WARN: backup '20190923-164324F' found in repository added to backup.info"); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         TEST_RESULT_VOID( | ||||
|             storageCopyP( | ||||
|                 storageNewReadP(storageRepo(), strNew(STORAGE_REPO_BACKUP "/20190818-084444F/" BACKUP_MANIFEST_FILE INFO_COPY_EXT)), | ||||
|                 storageNewWriteP(storageRepoWrite(), strNew(STORAGE_REPO_BACKUP "/20190818-084444F/" BACKUP_MANIFEST_FILE))), | ||||
|                 "write manifest from copy-only for pgId=1"); | ||||
|  | ||||
|         manifestContentIncr = harnessInfoChecksumZ | ||||
|         ( | ||||
|             "[backup]\n" | ||||
|             "backup-archive-start=\"000000030000028500000089\"\n" | ||||
|             "backup-archive-stop=\"000000030000028500000090\"\n" | ||||
|             "backup-label=\"20190818-084444F_20190924-084502D\"\n" | ||||
|             "backup-lsn-start=\"285/89000028\"\n" | ||||
|             "backup-lsn-stop=\"285/89001F88\"\n" | ||||
|             "backup-prior=\"20190818-084444F\"\n" | ||||
|             "backup-timestamp-copy-start=1565282141\n" | ||||
|             "backup-timestamp-start=1565282140\n" | ||||
|             "backup-timestamp-stop=1565282142\n" | ||||
|             "backup-type=\"diff\"\n" | ||||
|             TEST_MANIFEST_BACKUPDB | ||||
|             "\n" | ||||
|             "[backup:option]\n" | ||||
|             "option-archive-check=true\n" | ||||
|             "option-archive-copy=true\n" | ||||
|             "option-backup-standby=true\n" | ||||
|             "option-buffer-size=16384\n" | ||||
|             "option-checksum-page=true\n" | ||||
|             "option-compress=true\n" | ||||
|             "option-compress-level=3\n" | ||||
|             "option-compress-level-network=3\n" | ||||
|             "option-delta=false\n" | ||||
|             "option-hardlink=true\n" | ||||
|             "option-online=true\n" | ||||
|             "option-process-max=32\n" | ||||
|             "\n" | ||||
|             "[backup:target]\n" | ||||
|             "pg_data={\"path\":\"/pg/base\",\"type\":\"path\"}\n" | ||||
|             "\n" | ||||
|             "[target:file]\n" | ||||
|             "pg_data/PG_VERSION={\"checksum\":\"184473f470864e067ee3a22e64b47b0a1c356f29\",\"size\":4,\"timestamp\":1565282114}\n" | ||||
|             TEST_MANIFEST_FILE_DEFAULT | ||||
|             "\n" | ||||
|             "[target:path]\n" | ||||
|             "pg_data={}\n" | ||||
|             TEST_MANIFEST_PATH_DEFAULT | ||||
|         ); | ||||
|  | ||||
|         TEST_RESULT_VOID( | ||||
|             storagePutP(storageNewWriteP(storageRepoWrite(), | ||||
|             strNew(STORAGE_REPO_BACKUP "/20190818-084444F_20190924-084502D/" BACKUP_MANIFEST_FILE)), | ||||
|             manifestContentIncr), "write manifest for dependent backup to be added to full already in backup.info"); | ||||
|  | ||||
|         TEST_RESULT_VOID( | ||||
|             infoBackupSaveFile(infoBackup, storageRepoWrite(), INFO_BACKUP_PATH_FILE_STR, cipherTypeNone, NULL), | ||||
|             "save updated backup info"); | ||||
|  | ||||
|         infoBackup = NULL; | ||||
|         TEST_ASSIGN( | ||||
|             infoBackup, infoBackupLoadFileReconstruct(storageRepo(), INFO_BACKUP_PATH_FILE_STR, cipherTypeNone, NULL), | ||||
|             "reconstruct"); | ||||
|         TEST_RESULT_STR_Z( | ||||
|             strLstJoin(infoBackupDataLabelList(infoBackup, NULL), ", "), "20190818-084444F, 20190923-164324F", | ||||
|             "previously ignored pgId=1 manifest copy-only now added before existing"); | ||||
|             strLstJoin(infoBackupDataLabelList(infoBackup, NULL), ", "), | ||||
|             "20190818-084444F, 20190818-084444F_20190924-084502D, 20190923-164324F", | ||||
|             "previously ignored pgId=1 manifest copy-only now added before existing, and add dependent found"); | ||||
|         harnessLogResult( | ||||
|             "P00   WARN: backup '20190818-084444F' found in repository added to backup.info\n" | ||||
|             "P00   WARN: backup '20190818-084444F_20190924-084502D' found in repository added to backup.info\n" | ||||
|             "P00   WARN: invalid backup '20190818-084555F' cannot be added to current backups\n" | ||||
|             "P00   WARN: invalid backup '20190818-084666F' cannot be added to current backups\n" | ||||
|             "P00   WARN: invalid backup '20190818-084777F' cannot be added to current backups"); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user