Re: [HACKERS] UNDO and in-place update - Mailing list pgsql-hackers
From | Robert Haas |
---|---|
Subject | Re: [HACKERS] UNDO and in-place update |
Date | |
Msg-id | CA+TgmoZdTft3zog8P7NRnTwknaOm4YheSZhT+G+iswba21iHQg@mail.gmail.com Whole thread Raw |
In response to | Re: [HACKERS] UNDO and in-place update (Amit Kapila <amit.kapila16@gmail.com>) |
Responses |
Re: [HACKERS] UNDO and in-place update
|
List | pgsql-hackers |
On Fri, Jan 6, 2017 at 6:28 AM, Amit Kapila <amit.kapila16@gmail.com> wrote: >> Also, I'm thinking the bit could be stored in the line pointer rather >> than the tuple, because with this design we don't need >> LP_UNUSED/LP_NORMAL/LP_REDIRECT/LP_DEAD any more. We could use one >> bit to indicate dead or not-dead and the second bit to indicate >> recently-modified or not-recently-modified. With that approach, >> clearing the bits only requires iterating over the line pointer array, >> not the tuples themselves. > > I think this can help in mitigating the overhead. However, now > another question is if we just unset it when there is no other active > transaction operating on the current page except for current > transaction, then will that tuple be considered all-visible? I think > no transaction operating on a page can't be taken as a guarantee for > tuple to be marked as all-visible. If that is true, then what is > advantage of clearing the bit? That's kind of a strange question. The mission of this proposed bit is to tell you whether the transaction(s) referenced in the page's UNDO pointer have modified that tuple. If you didn't clear it when you reset the UNDO pointer to a new transaction, then the bit would always be set for every tuple on the page and it would be completely useless. (I mean, the tuples had to be inserted originally, right? So the bit was set then. And if you never clear it, it will just stay set.) As to your other questions: If the page's UNDO pointer isn't valid, then the whole page is all-visible. If the page's UNDO pointer is valid, then any tuple for which the bit is not set is all-visible. > Okay, I think we could clean undo and heap without caring for the > index. Basically, the idea works on the premise that we won't allow > same value rows in the index for same TID and using rechecks we can > identify the deleted tuple. Right, seems we are on the same page now. Just to be clear, I'm not saying there aren't other possible designs, and one of those designs might be better. But at least now we both seem to have the same understanding of what I proposed, which seems like progress. > On rethinking about the working of vacuum > in this system, it seems we can clean the heap independently and then > for index we crosscheck each of the entry in the heap that is marked > as deleted. Right. > Now this has the advantage that we don't need to do two > passes of the heap, but for the index, we might need to re-fetch heap > pages randomly to detect if the delete marked row is actually deleted. Yes. There are some performance trade-offs here no matter what decision you make. If you decide to try to remove delete-marked index entries during UNDO, then (1) you have to somehow make sure that those index entries aren't still needed by some previous transaction that isn't yet all-visible (e.g. imagine key is updated 1->2->1, first update commits but second one rolls back before first is all-visible) which might be expensive and (2) if those index pages have been evicted from cache you will incur additional I/O to bring them back into cache, which might be more expensive than just cleaning them later. On the other hand, if you don't try to remove index pointers during UNDO, then you're leaving bloat in your index. We might want to consider some combination of these things - e.g. if the page has only one recent transaction (no TPD) and the index pages are still in memory, have UNDO try to remove them, otherwise clean them later. Or some other rule. -- Robert Haas EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company
pgsql-hackers by date: