On Mon, Nov 19, 2012 at 2:46 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Jeff Davis <pgsql@j-davis.com> writes:
>> As I said elsewhere in the thread, I'm not planning to introduce any
>> additional locking. There is already precedent in IndexOnlyNext.
>
> Of course, that just begs the question of whether the code in
> IndexOnlyNext is correct. And after looking at it, it seems pretty
> broken, or at least the argument for its correctness is broken.
> That comment seems to consider only the case where the target tuple has
> just been inserted --- but what of the case where the target tuple is in
> process of being deleted? The deleter will not make a new index entry
> for that. Of course, there's a pretty long code path from marking a
> tuple deleted to committing the deletion, and it seems safe to assume
> that the deleter will hit a write barrier in that path. But I don't
> believe the argument here that the reader must hit a read barrier in
> between.
Ouch. I don't know how I missed that case when writing that comment,
but I agree it should have been discussed there. The timing
requirements for updates and deletes seem to be generally less strict,
because the update or delete won't generally be visible to our
snapshot anyway, so it doesn't really matter if we think the page is
all-visible for slightly longer than it really is. However, it would
be a problem if we thought the page was still all-visible when in fact
it contained a tuple that was not visible to our snapshot. For that
to happen, the updating or deleting transaction would have to commit
before we took our snapshot, yet the visibility map update would have
to still be visible after we took our snapshot. That clearly can't
happen, since both committing and taking a snapshot require LWLock
acquire/release.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company