Subject | Blocking garbage collection, read committed transactions, and blobs |
---|---|
Author | Ann W. Harrison |
Post date | 2005-06-28T22:37Z |
Earlier this month on the devel list, we exchanged a bunch of messages
about reducing the impact of read-committed transactions on garbage
collection. One outcome of that discussion was the unpleasant discovery
that our current practice of treating read-only read-committed
transactions as pre-committed and not blocking garbage collection
doesn't work for blobs.
Specifically, if a read-only read-committed transaction reads a record
then reads a blob from that record is has a small chance of getting
errors like "blob not found", or "wrong page type", or even getting data
from the wrong blob. The errors occur if the record and its blob are
garbage collected between reading the record and completing reading the
blob. Very large blobs are more subject the problem than small blobs,
but both are affected. InterBase has the same bug.
Someone clever - probably Vlad, though I didn't find the message in a
quick search - suggested that we keep a separate "oldest active blob"
number. I've been thinking about that since and think there is a
solution there that will limit the effect of read-committed transactions
on garbage collection and still get right answers.
No record is ever garbage collected until the transaction that wrote the
version that replaced it commits. Therefore, no read-committed
transaction ever needs any record version that can possibly be garbage
collected, and in the absence of blobs, a read-committed transaction
should have no impact on garbage collection, regardless of whether it is
read-only or read-write.
However, garbage collecting any blob which was superseded by a
transaction that was active when a read-committed transaction started
can cause incorrect results. So a read-committed transaction has the
same impact as a concurrency/snapshot/real transaction on records that
contain blobs.
With one additional caveat. When normal data in a record is updated,
the blob carries forward, unchanged, unless the blob data itself was
changed. So old record versions with blobs can be garbage collected, as
long as a newer version of the record references the same blob.
If we were to keep two thresholds for garbage collection, one the oldest
active and the other the oldest blob, we could greatly reduce the impact
of read-committed transactions on garbage collection.
But how? More tomorrow.
Regards,
Ann
about reducing the impact of read-committed transactions on garbage
collection. One outcome of that discussion was the unpleasant discovery
that our current practice of treating read-only read-committed
transactions as pre-committed and not blocking garbage collection
doesn't work for blobs.
Specifically, if a read-only read-committed transaction reads a record
then reads a blob from that record is has a small chance of getting
errors like "blob not found", or "wrong page type", or even getting data
from the wrong blob. The errors occur if the record and its blob are
garbage collected between reading the record and completing reading the
blob. Very large blobs are more subject the problem than small blobs,
but both are affected. InterBase has the same bug.
Someone clever - probably Vlad, though I didn't find the message in a
quick search - suggested that we keep a separate "oldest active blob"
number. I've been thinking about that since and think there is a
solution there that will limit the effect of read-committed transactions
on garbage collection and still get right answers.
No record is ever garbage collected until the transaction that wrote the
version that replaced it commits. Therefore, no read-committed
transaction ever needs any record version that can possibly be garbage
collected, and in the absence of blobs, a read-committed transaction
should have no impact on garbage collection, regardless of whether it is
read-only or read-write.
However, garbage collecting any blob which was superseded by a
transaction that was active when a read-committed transaction started
can cause incorrect results. So a read-committed transaction has the
same impact as a concurrency/snapshot/real transaction on records that
contain blobs.
With one additional caveat. When normal data in a record is updated,
the blob carries forward, unchanged, unless the blob data itself was
changed. So old record versions with blobs can be garbage collected, as
long as a newer version of the record references the same blob.
If we were to keep two thresholds for garbage collection, one the oldest
active and the other the oldest blob, we could greatly reduce the impact
of read-committed transactions on garbage collection.
But how? More tomorrow.
Regards,
Ann