mirror of
https://github.com/borgbackup/borg.git
synced 2025-03-06 03:35:02 +00:00
Repository: compact: fix incorrect preservation of delete tags
This commit is contained in:
parent
abace16945
commit
7b1f10347a
1 changed files with 7 additions and 5 deletions
|
@ -481,8 +481,9 @@ class Repository:
|
||||||
for tag, key, offset, data in self.io.iter_objects(segment, include_data=True):
|
for tag, key, offset, data in self.io.iter_objects(segment, include_data=True):
|
||||||
if tag == TAG_COMMIT:
|
if tag == TAG_COMMIT:
|
||||||
continue
|
continue
|
||||||
in_index = self.index.get(key) == (segment, offset)
|
in_index = self.index.get(key)
|
||||||
if tag == TAG_PUT and in_index:
|
is_index_object = in_index == (segment, offset)
|
||||||
|
if tag == TAG_PUT and is_index_object:
|
||||||
try:
|
try:
|
||||||
new_segment, offset = self.io.write_put(key, data, raise_full=True)
|
new_segment, offset = self.io.write_put(key, data, raise_full=True)
|
||||||
except LoggedIO.SegmentFull:
|
except LoggedIO.SegmentFull:
|
||||||
|
@ -492,22 +493,23 @@ class Repository:
|
||||||
segments.setdefault(new_segment, 0)
|
segments.setdefault(new_segment, 0)
|
||||||
segments[new_segment] += 1
|
segments[new_segment] += 1
|
||||||
segments[segment] -= 1
|
segments[segment] -= 1
|
||||||
elif tag == TAG_PUT and not in_index:
|
elif tag == TAG_PUT and not is_index_object:
|
||||||
# If this is a PUT shadowed by a later tag, then it will be gone when this segment is deleted after
|
# If this is a PUT shadowed by a later tag, then it will be gone when this segment is deleted after
|
||||||
# this loop. Therefore it is removed from the shadow index.
|
# this loop. Therefore it is removed from the shadow index.
|
||||||
try:
|
try:
|
||||||
self.shadow_index[key].remove(segment)
|
self.shadow_index[key].remove(segment)
|
||||||
except (KeyError, ValueError):
|
except (KeyError, ValueError):
|
||||||
pass
|
pass
|
||||||
elif tag == TAG_DELETE:
|
elif tag == TAG_DELETE and not in_index:
|
||||||
# If the shadow index doesn't contain this key, then we can't say if there's a shadowed older tag,
|
# If the shadow index doesn't contain this key, then we can't say if there's a shadowed older tag,
|
||||||
# therefore we do not drop the delete, but write it to a current segment.
|
# therefore we do not drop the delete, but write it to a current segment.
|
||||||
shadowed_put_exists = key not in self.shadow_index or any(
|
shadowed_put_exists = key not in self.shadow_index or any(
|
||||||
# If the key is in the shadow index and there is any segment with an older PUT of this
|
# If the key is in the shadow index and there is any segment with an older PUT of this
|
||||||
# key, we have a shadowed put.
|
# key, we have a shadowed put.
|
||||||
shadowed < segment for shadowed in self.shadow_index[key])
|
shadowed < segment for shadowed in self.shadow_index[key])
|
||||||
|
delete_is_not_stable = index_transaction_id is None or segment > index_transaction_id
|
||||||
|
|
||||||
if shadowed_put_exists or index_transaction_id is None or segment > index_transaction_id:
|
if shadowed_put_exists or delete_is_not_stable:
|
||||||
# (introduced in 6425d16aa84be1eaaf88)
|
# (introduced in 6425d16aa84be1eaaf88)
|
||||||
# This is needed to avoid object un-deletion if we crash between the commit and the deletion
|
# This is needed to avoid object un-deletion if we crash between the commit and the deletion
|
||||||
# of old segments in complete_xfer().
|
# of old segments in complete_xfer().
|
||||||
|
|
Loading…
Add table
Reference in a new issue