Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions docs/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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?
---------------------------------------------------

Expand Down
5 changes: 5 additions & 0 deletions src/borg/archiver/check_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
8 changes: 4 additions & 4 deletions src/borg/archiver/recreate_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Loading