[PATCH] debug: automate the process of truncating a damaged obsstore

Simon Farnsworth simonfar at fb.com
Mon Jul 4 11:20:04 EDT 2016


On 03/07/2016 04:59, Yuya Nishihara wrote:
> On Thu, 30 Jun 2016 07:04:09 -0700, Simon Farnsworth wrote:
>> # HG changeset patch
>> # User Simon Farnsworth <simonfar at fb.com>
>> # Date 1467295436 25200
>> #      Thu Jun 30 07:03:56 2016 -0700
>> # Node ID 252cefa0326063bd664f47e3628942df30d08ccf
>> # Parent  c42a3fd5c1fc5193e5f45887bfddaf05ca977fa4
>> debug: automate the process of truncating a damaged obsstore
>
> (issue5265)
>
Added to end of line.

>> + at command('debugtruncatestore',
>> +    [('', 'obsolete', None, _('truncate bad markers in obsstore'))],
>> +    _('[OPTION]'))
>> +def debugtruncatestore(ui, repo, **opts):
>> +    """Fix up repository corruption by truncating damaged files
>> +
>> +    Most on-disk data structures are designed to be append-only. A failed write
>> +    (e.g. due to an unexpected power failure) can leave the file corrupted.
>> +
>> +    This command attempts to recover from that situation by replacing the
>> +    corrupted file with a version that only contains the valid records from the
>> +    broken file.
>> +
>> +    You should normally use :hg:`recover` before resorting to this command.
>> +    """
>> +
>> +    if 'obsolete' in opts:
>> +        data = repo.svfs.tryread('obsstore')
>> +        if data:
>> +            # Slow algorithm - but this is an emergency debug operation
>> +            version = None
>> +            corrupt = False
>> +            while version is None:
>> +                try:
>> +                    (version, markers) = obsolete._readmarkers(data)
>> +                except ValueError:
>> +                    corrupt = True
>> +                    version = None
>> +                    data = data[:-1]
>> +                    continue
>> +                break
>> +            if corrupt:
>> +                repo.svfs.write('obsstore', data)
>> +                ui.write(_('truncated obsstore\n'))
>> +            else:
>> +                ui.write(_('no corruption\n'))
>
> It should be covered by a lock. I'm not sure if a transaction is necessary.
>

I've added a lock - instead of a transaction, I've renamed the corrupt 
file, and written out the new data. Not perfect,

> And can you add a test? I want to run it with/without --pure to see both
> cases are handled well.
>
Sure; I've also fixed it up to handle the different behaviour between C 
and pure Python implementations. v2 inbound.
-- 
Simon Farnsworth


More information about the Mercurial-devel mailing list