Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix "put updates shadow index" #5636

Merged
Merged
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
14 changes: 7 additions & 7 deletions src/borg/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -1191,13 +1191,9 @@ def put(self, id, data, wait=True):
except KeyError:
pass
else:
self.segments[segment] -= 1
size = self.io.read(segment, offset, id, read_data=False)
self.storage_quota_use -= size
self.compact[segment] += size
segment, size = self.io.write_delete(id)
self.compact[segment] += size
self.segments.setdefault(segment, 0)
# note: doing a delete first will do some bookkeeping,
# like updating the shadow_index, quota, ...
self._delete(id, segment, offset)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth including a comment here indicating that the shadow_index will not get updated without performing an explicit delete here.

I'm not sure what to make of how borg's repository layer allows a PUT to shadow another PUT, but currently never does that (instead using DELETE + PUT). I'm not sure if PUT A, PUT A should be considered a sequence in need of repair.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added a comment.

seems like put del put is also needed for other bookkeeping.
e.g. imagine borg recreate with recompress - data size will usually change here, but chunkid will stay same.

segment, offset = self.io.write_put(id, data)
self.storage_quota_use += len(data) + self.io.put_header_fmt.size
self.segments.setdefault(segment, 0)
Expand All @@ -1220,6 +1216,10 @@ def delete(self, id, wait=True):
segment, offset = self.index.pop(id)
except KeyError:
raise self.ObjectNotFound(id, self.path) from None
self._delete(id, segment, offset)

def _delete(self, id, segment, offset):
# common code used by put and delete
self.shadow_index.setdefault(id, []).append(segment)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^ this line was missing in original put code.

self.segments[segment] -= 1
size = self.io.read(segment, offset, id, read_data=False)
Expand Down