Bruce Momjian <[EMAIL PROTECTED]> writes:
> This is an optimization so I was thinking of something simpler, like
> incrementing/decrementing a counter every time we allocate/free a
> snapshot (like in the patch), and updating MyProc->xmin only if there
> are no open snapshots. I don't think it is worth tracking anything more
> complicated than that. Is that now possible to do cleanly? I am having
> trouble getting this to work in the attached patch.
Even if you get it to pass the regression tests, it'll be a constant
source of bugs. IMHO the *only* way to do this reliably is to have
a centralized reference-count management module.
I've been thinking more about the avoid-copy idea and I think it will
indeed work, and be simpler than what we have now, to boot. Ideas:
* There is only one (pair of) statically allocated, max-size XID arrays
for GetSnapshotData to read into. When we want to acquire a new snap
from GetSnapshotData, we palloc a new SnapshotData struct (and no more),
make it point at the statically allocated arrays, fill and return it.
* There can be at most one SnapshotData struct using the statically
allocated arrays. We remember its address in a static variable (which
goes NULL when there is no such struct). If we have to acquire a new
snapshot before the old one's refcount has gone to zero, then at that
time we palloc arrays just big enough for the old one, copy the static
data to there, insert the palloc'd array pointers into the old one,
and clear the static variable (or more likely, immediately set it to
point to the new one).
* All the current CopySnapshot operations are replaced by refcount
increments. We need explicit refcount-decrement calls added, and
ResourceOwner support to make sure they happen. (I'm imagining that
snapshots will now live in a dedicated context, so they don't go away
implicitly but need explicit release operations. The ResourceOwner
infrastructure will help us find any missed releases.)
* Decrementing the refcount on a SnapshotData pfree's it if the refcount
has gone to zero, and also clears the aforementioned static pointer
variable if it happens to point at that selfsame struct. Note that for
a serializable transaction, or a "simple" read-committed transaction
that doesn't use more than one snap at a time, this will always happen
and so there will be zero copying cost.
* In this scheme the distinction between SerializableSnapshot and
LatestSnapshot vanishes, at least at the level of memory management.
Probably SerializableSnapshot would translate into a refcount held by
xact.c or some other upper-level module.
* We keep all the live MVCC snapshots in a linked list managed by
a "snapshot cache" module. We can traverse this list to determine
the minimum xmin at any instant. Freeing a snap whose xmin equals
the current MyProc->xmin causes us to traverse the list, determine
the new backend-wide xmin, and update MyProc->xmin. Freeing the
last snap causes us to reset MyProc->xmin to 0. (I'm not completely
sure, but I think that we can just set MyProc->xmin in these cases,
without bothering to lock the ProcArray --- any comments on that?)
* GetSnapshotData no longer cares about serializable vs nonserializable
snaps, either. Its rule is just "if MyProc->xmin is 0, then set it".
This can happen only when creating the first snap in a transaction that
currently has no live snaps.
* The above two rules clearly suffice to maintain the invariant
"MyProc->xmin is the minimum of the xmins of the live snapshots in the
transaction, or zero when there are none". Which is what we want.
On the whole though I think we should let this idea go till 8.4; we have
a lot to deal with for 8.3 and a definite shortage of evidence that
advancing xmin will buy much. Mu gut feeling is that the above design
would save about enough in snapshot-copying costs to pay for its extra
management logic, but we won't come out ahead unless advancing xmin
intra-transaction really helps, and I'm not sure I believe that (except
in the special case of VACUUM, and we already have a solution for that,
which would be independent of this).
regards, tom lane
---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend