Hi Greg.  Thanks for reviewing.

On Tue, 2011-02-15, Greg Stein wrote:
> On Tue, Feb 15, 2011 at 10:06, Julian Foad <julian.f...@wandisco.com> wrote:
> >...
> >  * ==== Operating Procedures ====
> >  *
> >  * The steps should be carried out in the order specified.  (See rationale.)
> >  *
> >  * * To add a pristine, do the following inside an SDB txn:
> >  *      * Add the table row, and set the refcount as desired.  If a row
> >  *        already exists, add the desired refcount to its refcount, and
> >  *        preferably verify the old row matches the new metadata.
> >  *      * Create the file. Creation should be fs-atomic, e.g. by moving a
> >  *        new file into place, so as never to orphan a partial file.  If a
> >  *        file already exists, preferably leave it rather than replace it,
> >  *        and optionally verify it matches the new metadata (e.g. length).
> >  *
> >  * * To remove a pristine, do the following inside an SDB txn:
> >  *      * First, check refcount == 0, and abort if not.
> >  *      * Delete the table row.
> >  *      * Delete the file or move it away. (If not present, log a
> >  *        consistency error but, in a release build, return success.)
> >  *
> >  * * To query a pristine's existence or SDB metadata, the reader must:
> >  *      * Ensure no pristine-remove txn is in progress while querying it.
> 
> What does "pristine-remove txn" mean?

It means the SDB txn defined under "To remove a pristine" above.  The
obvious way to ensure it's not in progress would be to do this query in
an SDB txn with a suitable lock (and I think the default lock type that
you get in a txn would be sufficient).

> >  *
> >  * * To read a pristine text, the reader must:
> >  *      * Ensure no pristine-remove txn is in progress while querying and
> >  *        opening it.
> >  *      * Ensure the pristine text remains in the store continuously from
> >  *        opening it for the duration of the read. (Perhaps by ensuring
> >  *        refcount remains >= 1 and/or by cooperating with the clean-up
> >  *        code.)
> 
> Taking out a WC lock would prevent a pristine from being deleted, right?

Yes, that would work, because of the rule below that requires an
exclusive WC lock in order to purge an unreferenced text.

(Originally I didn't say that here because I'm trying to keep the spec
as two separate layers, first presenting this low-level spec for
maintaining consistency between the files and the PRISTINE table rows in
the store, and secondly under the heading "Reference Counting" a higher
level spec for maintaining the references to pristines, which layers on
top of this one.  The latter is where WC locks are involved.  However, a
cross-reference here would be helpful.)

Is a WC lock on the root of the WC an exclusive lock, in that it could
not co-exist with any other WC lock whether on the root or deeper?  I'm
unsure of the semantics of WC locks.


> >...
> >  * ==== Notes ====
> >  *
> >  * * This procedure can leave orphaned pristine files (files without a
> >  *   corresponding SDB row) if Subvsersion crashes.  The Pristine Store
> >  *   will still operate correctly.  It should be easy to teach "svn cleanup"
> >  *   to safely delete these.  ### Do we need to define the clean-up
> >  *   procedure here?
> >  *
> >  * * This specification is conceptually simple, but requires completing disk
> >  *   operations within SDB transactions, which may make it too inefficient
> >  *   in practice.  An alternative specification could use the Work Queue to
> >  *   enable more efficient processing of multiple transactions.
> 
> Note that my initial design for the pristine inserted a row which
> effectively said "we know about this pristine, but it hasn't been
> written yet". The file would be put into place, then the row would get
> tweaked to say "it is now there". That avoids the disk I/O within a
> sqlite txn.

That would indeed avoid disk I/O within any txn during "add".  The
"remove" operation would go through the same states in reverse, I
assume.  But this seems to imply an extra complexity.  How would the
whole thing work - locking for "add", "remove" and read operations;
crash recovery?  Maybe it's straightforward but I'll have to write it
out in detail if you think it's worth it.

I would suggest first we need to assess whether a file move within a txn
is in fact a problem.


> >...
> >  * === Invariants in a Valid WC DB State ===
> >  *
> >  * * No pristine text, even if refcount == 0, will be deleted from the store
> >  *   as long as any process holds any WC lock in this WC.
> >  *
> >  * The following conditions are always true outside of a SQL txn:
> >  *
> >  *   * The 'checksum' column in each NODES table row is either NULL or
> >  *     references a primary key in the 'pristine' table.
> >  *
> >  *   * The 'refcount' column in each PRISTINE table row is equal to the
> >  *     number of NODES table rows whose 'checksum' column references this
> >  *     pristine row.
> 
> ACTUAL_NODE also holds references. Shouldn't these count towards the checksum?

One day, yes, but for 1.7 no.  We don't use that column yet.

> >  *
> >  * The following conditions are always true
> >  *     outside of a SQL txn,
> >  *     when the Work Queue is empty:
> >  *     (### ?) when no WC locks are held by any process:
> >  *
> >  *   * The 'refcount' column in a PRISTINE table row equals the number of
> >  *     NODES table rows whose 'checksum' column references that pristine 
> > row.
> >  *     It may be zero.
> 
> hmm? duplicate text?

Could be... I was losing concentration at this end of the doc.

> >  *
> >  * ==== Operating Procedures ====
> >  *
> >  * The steps should be carried out in the order specified.
> >  *
> >  * * To add a pristine text reference to the WC, obtain the text and its
> >  *   checksum, and then do this while holding a WC lock:
> >  *     * Add the pristine text to the Pristine Store, setting the desired
> >  *       refcount >= 1.
> >  *     * Add the reference(s) in the NODES table.
> >  *
> >  * * To remove a pristine text reference from the WC, do this while holding
> >  *   a WC lock:
> >  *     * Remove the reference(s) in the NODES table.
> >  *     * Decrement the pristine text's 'refcount' column.
> >  *
> >  * * To purge an unreferenced pristine text, do this with an *exclusive*
> >  *   WC lock:
> >  *     * Check refcount == 0; skip if not.
> >  *     * Remove it from the pristine store.
> 
> This seems a bit duplicative of the "Operating Procedures" in the first 
> section.

This is supposed to be the higher layer of spec, defining how to add a
new pristine text to the WC ALONG WITH ADDING A REFERENCE TO IT in the
NODES table, in terms of the lower layer "add this text to the store"
operation.

- Julian



Reply via email to