[PATCH 1 of 1 v3] store: add names of successfully opened revlogs to fncache

Adrian Buehlmann adrian at cadifra.com
Mon Apr 23 01:48:59 CDT 2012


On 2012-04-23 02:57, Mads Kiilerich wrote:
> # HG changeset patch
> # User Mads Kiilerich <mads at kiilerich.com>
> # Date 1335141331 -7200
> # Branch stable
> # Node ID dab6871ccc38b4c1748d67fa4ecf904c3b3018a1
> # Parent  3440757d12850cfafa88a754b34f5d42e62e4c25
> store: add names of successfully opened revlogs to fncache
> 
> fncache permanently drops the names of revlogs that can't be found when the
> datastore iterator stats them, for example when verify walks over all revlogs.
> The only way to re-add a removed revlog name to fncache was to open the revlog
> for write. ...

[..]

> ... Recovery (for example after restoring revlogs from a backup) was
> thus quite hard.

Well. This isn't really true. The fncache file can be reconstructed
today already (i.e. with unpatched mercurial) by doing:

   hg clone --pull oldrepo newrepo

This operation doesn't read the fncache file in oldrepo at all and
creates a new one in newrepo by walking all manifest revisions.

> This change makes fncache more like a cache by adding entries whenever a
> missing revlog is opened.
> 
> Some operations open revlogs for reading without checking if they exist - they
> will now heal fncache. Verify will thus be able to re-create entries that it
> accidentially has removed. That will however only happen after it has
> complained that the revlog is missing. Next time verify is run the problem is
> gone.
> 
> diff --git a/mercurial/store.py b/mercurial/store.py
> --- a/mercurial/store.py
> +++ b/mercurial/store.py
> @@ -372,9 +372,10 @@
>          self.encode = encode
>  
>      def __call__(self, path, mode='r', *args, **kw):
> -        if mode not in ('r', 'rb') and path.startswith('data/'):
> +        opener = self.opener(self.encode(path), mode, *args, **kw)
> +        if path.startswith('data/'):
>              self.fncache.add(path)
> -        return self.opener(self.encode(path), mode, *args, **kw)
> +        return opener

Hmm. What happens if the repo you are reading is on a read-only volume,
like, say a CD-ROM?

What about the write lock on the store?

The fncache file is *not* facultative; operations like 'clone
--uncompressed' are not able to reconstruct a missing fncache file on
the fly like the other caches we have.

So I have some very strong doubts that this is the way to go. Most
certainly not on stable with a last minute discussion during freeze.

>  class fncachestore(basicstore):
>      def __init__(self, path, openertype, encode):
> diff --git a/tests/test-fncache.t b/tests/test-fncache.t
> --- a/tests/test-fncache.t
> +++ b/tests/test-fncache.t
> @@ -55,6 +55,12 @@
>    3 integrity errors encountered!
>    (first damaged changeset appears to be 0)
>    [1]
> +  $ hg verify
> +  checking changesets
> +  checking manifests
> +  crosschecking files in changesets and manifests
> +  checking files
> +  3 files, 3 changesets, 3 total revisions
>    $ cd ..
>  
>  Non store repo:
> diff --git a/tests/test-verify.t b/tests/test-verify.t
> --- a/tests/test-verify.t
> +++ b/tests/test-verify.t
> @@ -90,6 +90,12 @@
>    (first damaged changeset appears to be 0)
>    [1]
>    $ mv _q_u_i_c_k.txt.i .hg/store/data/
> +  $ hg verify
> +  checking changesets
> +  checking manifests
> +  crosschecking files in changesets and manifests
> +  checking files
> +  4 files, 1 changesets, 4 total revisions
>  
>  test revlog corruption
>  

As a general note, I still have problems to see what problem exactly you
are trying to solve with your attempts in this patch thread here.



More information about the Mercurial-devel mailing list