Thread: pgsql: Fix WAL replay of locking an updated tuple

pgsql: Fix WAL replay of locking an updated tuple

From
Alvaro Herrera
Date:
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(-)


Re: pgsql: Fix WAL replay of locking an updated tuple

From
Tom Lane
Date:
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


Re: pgsql: Fix WAL replay of locking an updated tuple

From
Alvaro Herrera
Date:
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


Re: pgsql: Fix WAL replay of locking an updated tuple

From
Andres Freund
Date:
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