Reimplement rebuild-index and remove /internal/index#3006
Conversation
We should also keep the option to rebuild the index from scratch. |
108eb91 to
537a336
Compare
I just implemented the improved algorithm to take existing index entries into account. I named the new option |
|
What about calling the option I still have to think about whether a full or a partial rebuild should be the default. Right now I slightly prefer the former. That way we wouldn't change the current behavior and after all it's the safer option when a repository was damaged. Apropos, under which conditions would it be safe to use the faster variant? That is probably the case when a pack file (or multiple ones) is for some reason missing from the index. When a pack file does not match the size it should have according to the index, then I'd be very careful, after all that pack file is probably damaged. If you already know which pack file is damaged, then the fast path is definitely useful as it allows quickly removing the damaged file from the index. |
I would say the faster variant will give the identical result as the "full rebuild" iff all pack files that are omitted are completely and correctly contained in the index. So, for the faster variant to be unsafe, we basically need to have a pack file with name and size of a correctly indexed pack file, but with different contents; i.e. a modified pack file due to manipulation or bit rot. But actually I remember, that I wanted to work on the error handling when reading a pack file. The
When a pack file does not match the size it should have, it will be treated identically for both variants: Its header will be read and if this succeeds, the contents are added to the newly generated index. |
There's one special case here: For backends which charge for traffic it's far less expensive to let
That depends on what you intend to do: Such a damaged pack file should not at all be used in a backup, but it may still be valuable when restoring files. When rebuild-index notices such a damaged pack header, it could keep the old data for that pack file, finish the rebuild otherwise and then at the end return an error. The exact steps to recover from a error would be slightly different than currently, but that should still be manageable.
Ideally recovery from repository damages works automatically in large parts (at least in the future). It's not really ideal to require users to manually delete this or that file from the repository. How would aborting the index rebuild on a damaged pack file fit in with that? It's also quite common to have one or another incomplete pack file stored (at least for some backends). |
|
So the faster variant wouldn't detect inaccessible pack files or corrupted pack file headers. And it wouldn't recover from bit flips in the index. ( The full rebuild would recover bit flips and remove damaged/inaccessible packs from the index. That latter step has the benefit that it simplifies recovery: after the damaged pack files are removed from the index, then its safe again to run backups using the repository. It would also allow prune to work again. |
Right. Of course, as the faster variant doesn't read as much, there are error cases which can't be detected.
I agree. The faster variant will just not be able to detect a damaged pack header, the "full rebuild" will be, of course.
Well, it wouldn't detect pack files that are listed in the backend but are not accessible. About bit flips in the index: Or did you mean bit flips in the pack header here?
You are right - actually we should add that check to
I would say the use cases of the fast variant are basically all cases where the user wants to rebuild the index as index or pack files have changed in a not by restic intended way. That might be due to an aborted
Note that the "full rebuild" is not able to remove all kind of damaged packs from the index! As it only reads the header, it is not able to checksum the whole pack file. It is not even able to remove a pack from the index if
To be really safe, I would say you must run
Can you give an example where the "full rebuild" will allow prune to work after whereas the fast variant won't? |
I had bitflips in mind which happened before the index was hashed and written to the backend. For these indexes there would only be some flipped bits in the index entries such that the blob size (easy to detect), offset (not that simple) or hash (the blob you just appear as missing) would differ. But these are probably very, very rare (even though we've had a few reports about bitflips in packfiles). Just printing a warning when an index can't be loaded should be fine. It won't break backups and prune checks beforehand that it finds all necessary blobs.
It depends on the exact behavior of the fast variant when a pack file suddenly is shorter than expected and has now a damaged pack header. If the fast repack keeps the old blob list for that pack, then prune will also detect the discrepancy and abort. If it doesn't, then prune will work. Your earlier comments sounded like this PR uses the former variant, I haven't looked at the implementation itself yet. |
537a336 to
61a1bf5
Compare
The faster variant will remove all contents of the current index for packs that are either read or exist in the index but not in the repository and add all contents of the pack headers which are read. |
MichaelEischer
left a comment
There was a problem hiding this comment.
The code looks fine mostly, there are just a few very subtle things happening, see my comments.
61a1bf5 to
64aadb0
Compare
|
I rebased this. As #2842 now counts pack files when building the new index, I now determine the number of packs. This simplified the code a bit. |
65367ae to
76d34b7
Compare
|
After the discussion about calling |
76d34b7 to
fae4be8
Compare
|
rebased after #2718 has been merged. |
SHA1: fae4be8424186659fafba32c64b0cb5b0e2e376c From restic/restic#3006
fae4be8 to
7ca9308
Compare
|
rebased after #2842 has been merged |
|
For this PR, only documentation is open. I just noticed that there yet exists no documentation for the |
7ca9308 to
a77109d
Compare
|
Rebased this after #3058 has been merged. Also made index saving parallel (see added commit). |
|
@MichaelEischer Were your concerns about which variant should be the default resolved? |
5318d2c to
b9ac292
Compare
b9ac292 to
9607cad
Compare
MichaelEischer
left a comment
There was a problem hiding this comment.
LGTM. Nice to once again only have a single index implementation :-) .
What does this PR change? What problem does it solve?
After #2842 we can as well reimplement rebuild-index to use the same functionality.
This allows to get rid of
internal/indexwhich is now no longer used.Moreover, now existing index entries are used to reduce the number of packs that need to be read.
This improves speed a lot.
The newly added option
--read-all-packsimplements the previous behavior.This PR depends on #2842; only the last 6 commits are relevant for this PR.
Was the change discussed in an issue or in the forum before?
closes #2547
Checklist
changelog/unreleased/that describes the changes for our users (template here)gofmton the code in all commits