Skip to content

Commit

Permalink
fixup! repozo: support incremental recover
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebatyne committed Oct 22, 2024
1 parent 154c47c commit d441b83
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 18 deletions.
38 changes: 21 additions & 17 deletions src/ZODB/scripts/repozo.py
Original file line number Diff line number Diff line change
Expand Up @@ -749,9 +749,10 @@ def do_full_recover(options, repofiles):
def do_incremental_recover(options, repofiles):
datfile = os.path.splitext(repofiles[0])[0] + '.dat'
log('Recovering (incrementally) file to %s', options.output)
with open(datfile) as fp, open(options.output, 'r+b') as outfp:
with open(options.output, 'r+b') as outfp:
outfp.seek(0, 2)
initial_length = outfp.tell()
with open(datfile) as fp:
previous_chunk = None
for line in fp:
fn, startpos, endpos, _ = chunk = line.split()
Expand All @@ -760,27 +761,30 @@ def do_incremental_recover(options, repofiles):
if endpos > initial_length:
break
previous_chunk = chunk

if previous_chunk == chunk:
if endpos == initial_length:
log('Target file is same size as latest backup, '
'doing nothing.')
return
else:
if endpos == initial_length:
log('Target file is same size as latest backup, '
'doing nothing.')
return
else:
log('Target file is larger than latest backup, '
'falling back to a full recover.')
return do_full_recover(options, repofiles)
if previous_chunk is None:
log('Target file smaller than full backup, '
log('Target file is larger than latest backup, '
'falling back to a full recover.')
return do_full_recover(options, repofiles)
check_startpos = int(previous_chunk[1])
check_endpos = int(previous_chunk[2])
if previous_chunk is None:
log('Target file smaller than full backup, '
'falling back to a full recover.')
return do_full_recover(options, repofiles)
check_startpos = int(previous_chunk[1])
check_endpos = int(previous_chunk[2])
with open(options.output, 'r+b') as outfp:
outfp.seek(check_startpos)
if previous_chunk[3] != checksum(outfp, check_endpos - check_startpos):
log('Last whole common chunk checksum did not match with backup, '
'falling back to a full recover.')
return do_full_recover(options, repofiles)
check_sum = checksum(outfp, check_endpos - check_startpos)
assert outfp.tell() == startpos, (outfp.tell(), startpos)
if previous_chunk[3] != check_sum:
log('Last whole common chunk checksum did not match with backup, '
'falling back to a full recover.')
return do_full_recover(options, repofiles)

if startpos < initial_length:
log('Truncating target file %i bytes before its end',
Expand Down
2 changes: 1 addition & 1 deletion src/ZODB/scripts/tests/test_repozo.py
Original file line number Diff line number Diff line change
Expand Up @@ -1200,7 +1200,7 @@ def test_w_inc_backup_switch_auto_to_full_recover_after_pack(self):
self.assertEqual(_read_file(output), b'CCDD')
self.assertFalse(os.path.exists(output + '.part'))
self.assertIn(
'Target file is longer than latest backup, falling back to a full recover.', # noqa: E501 line too long
'Target file is larger than latest backup, falling back to a full recover.', # noqa: E501 line too long
sys.stderr.getvalue())


Expand Down

0 comments on commit d441b83

Please sign in to comment.