Thread: pgsql: Fix WAL replay of locking an updated tuple
Fix WAL replay of locking an updated tuple We were resetting the tuple's HEAP_HOT_UPDATED flag as well as t_ctid on WAL replay of a tuple-lock operation, which is incorrect when the tuple is already updated. Back-patch to 9.3. The clearing of both header elements was there previously, but since no update could be present on a tuple that was being locked, it was harmless. Bug reported by Peter Geoghegan and Greg Stark in CAM3SWZTMQiCi5PV5OWHb+bYkUcnCk=O67w0cSswPvV7XfUcU5g@mail.gmail.com and CAM-w4HPTOeMT4KP0OJK+mGgzgcTOtLRTvFZyvD0O4aH-7dxo3Q@mail.gmail.com respectively; diagnosis by Andres Freund. Branch ------ master Details ------- http://git.postgresql.org/pg/commitdiff/6bfa88acd3df830a5f7e8677c13512b1b50ae813 Modified Files -------------- src/backend/access/heap/heapam.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
Alvaro Herrera <alvherre@alvh.no-ip.org> writes: > Fix WAL replay of locking an updated tuple The test added by this patch certainly looks like it's backwards. Shouldn't you be clearing HOT_UPDATED only if the tuple is *not* XMAX_IS_LOCKED_ONLY? If the code is actually correct as written, then I think that test macro is very unfortunately named. regards, tom lane
Tom Lane wrote: > Alvaro Herrera <alvherre@alvh.no-ip.org> writes: > > Fix WAL replay of locking an updated tuple > > The test added by this patch certainly looks like it's backwards. > Shouldn't you be clearing HOT_UPDATED only if the tuple is *not* > XMAX_IS_LOCKED_ONLY? > > If the code is actually correct as written, then I think that test > macro is very unfortunately named. I don't understand. Note that this is about replaying a tuple lock operation; if the tuple we're locking had been updated by another transaction, then during the lock operation we don't want to touch either HOT_UPDATED or t_ctid, because they contain values that are valid per the pre-existing update. We are assuming that those values are correctly set prior to this xlog routine touching it (the replay of the update must have already set them.) -- Álvaro Herrera http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services
On 2014-02-27 09:41:03 -0500, Tom Lane wrote: > Alvaro Herrera <alvherre@alvh.no-ip.org> writes: > > Fix WAL replay of locking an updated tuple > > The test added by this patch certainly looks like it's backwards. > Shouldn't you be clearing HOT_UPDATED only if the tuple is *not* > XMAX_IS_LOCKED_ONLY? If it's not XMAX_IS_LOCKED_ONLY, we're locking the last tuple in the ctid chain, so there is no need for t_ctid to point anywhere. If it's not, there are later tuples (which the locking backend can't see yet because of its snapshot) but which haven't changed the key and thus only have NO KEY UPDATE lock level. The bug exactly was that the ctid chain was destroyed when there were later tuples. Greetings, Andres Freund -- Andres Freund http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services