On Mon, 2009-07-06 at 12:28 +0100, Greg Stark wrote:
> He only needs to handle inserts for the period they're actively being
> inserted into the index. Once they're in the index he'll find them
> using the index scan. In other words this is all a proxy for the way
> btree locks index pages while it looks for a unique key violation.
Exactly, that was my design:
/** We have to find all tuples, even those not visible* yet. Other transactions may have inserted many tuples (or* the
transactionmight be a prepared transaction), so there* may be some tuples that are not in the shared memory* structure
andnot visible.*/
> I'm a bit concerned about the use of tid. You might have to look at a
> lot of heap pages to check for conflicts. I suppose they're almost
> certainly all in shared memory though.
That was my hope.
The 8.4 bulk insert code might defeat that to some degree, however.
Maybe that could be disabled when inserting into an index with
constraints? I didn't think about it before, but the bulk insert buffer
ring would affect unique btrees, too, right?
> Also, it sounds like you're
> anticipating the possibility of dead entries in the array but if you
> do then you need to store the xmin also to protect against a tuple
> that's been vacuumed and had its line pointer reused since. But I
> don't see the necessity for that anyways since you can just clean up
> the entry on abort.
Can you tell me a little more specifically the problem you're worried
about? If the tuple has been VACUUMed and removed, then the TID search
will either find a tuple, and do a spurious constraint check against it;
or not find a tuple, and just move on.
I could have the commit and abort paths clear the entry, which might
optimize away some of the TransactionIdIsInProgress() calls for
transactions that ended normally. But that didn't strike me as a big
cost compared to the index scan.
Regards,Jeff Davis