diff --git a/docs/faq.rst b/docs/faq.rst index f50c844b05..0fe53abf81 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -424,6 +424,37 @@ needs to be ascertained and fixed. issues. We recommend to first run without ``--repair`` to assess the situation. If the found issues and proposed repairs seem right, re-run "check" with ``--repair`` enabled. +The recommended order of operations is: + +1. Run ``borg check`` without ``--repair``. It only reads the repository and reports + the extent of the damage: corrupt or missing packs, missing chunks and the files + and archives that reference them. + +2. Run ``borg check --repair``, preferably after making a copy of the repository. + + At the repository level, it salvages each corrupt pack: the pack is replaced by one + holding only the objects whose header, metadata and data still authenticate with + the key. It rebuilds the chunk index and removes the index entries of the chunks + stored in missing packs. + + At the archive level, it might remove archives whose archive metadata chunk is + corrupt or lost, and it reports the files that reference missing chunks. + +3. Run another backup of the same data. A file in an archive refers to its content + chunks by their ids, so a missing chunk that ``borg create`` stores again makes + every archive referencing it complete again at once. A following ``borg check`` + reports the chunks that are still missing. + +4. Chunks that are still missing then belong to data that is permanently lost. + ``borg extract`` writes all-zero data in place of such a chunk and reports the + affected file with a warning. To get rid of the affected files, remove them from + the archives with :ref:`borg_recreate`. Always look at what would be removed first:: + + borg -r REPO recreate --dry-run --list --exclude 'path/to/damaged-file' + + If the output is as intended, run the same command without ``--dry-run``. + Excluding files only rewrites archive metadata, so this is comparatively fast. + How probable is it to get a hash collision problem? --------------------------------------------------- diff --git a/src/borg/archiver/check_cmd.py b/src/borg/archiver/check_cmd.py index 21e6f692e2..33664c47da 100644 --- a/src/borg/archiver/check_cmd.py +++ b/src/borg/archiver/check_cmd.py @@ -339,6 +339,11 @@ def build_parser_check(self, subparsers, common_parser, mid_common_parser): remove whole archives from the manifest if their archive metadata chunk is corrupt or lost. Borg will also report files that reference missing chunks. + An item's chunk id list always refers to the correct chunks of the file content. + Thus, if a later ``borg create`` of the same data stores a missing chunk again, + every archive referencing that chunk is complete again at once, without a further + ``borg check --repair`` run. + If ``--repair --find-lost-archives`` is given, previously lost entries will be recreated in the archive directory. This is only possible before ``borg compact`` would remove the archives' data completely. diff --git a/src/borg/archiver/recreate_cmd.py b/src/borg/archiver/recreate_cmd.py index 7d67131282..621784b267 100644 --- a/src/borg/archiver/recreate_cmd.py +++ b/src/borg/archiver/recreate_cmd.py @@ -99,10 +99,10 @@ def build_parser_recreate(self, subparsers, common_parser, mid_common_parser): at least the entire deduplicated size of the archives using the previous chunker params. - If your most recent borg check found missing chunks, please first run another - backup for the same data, before doing any rechunking. If you are lucky, that - will recreate the missing chunks. Optionally, do another borg check to see - if the chunks are still missing. + If your most recent borg check found missing chunks, first run another backup of + the same data, before doing any rechunking. A missing chunk that this backup stores + again is picked up by all archives referencing it. A following borg check reports + the chunks that are still missing. """ ) subparser = ArgumentParser(