Andres Freund wrote:

> static void
> heap_xlog_lock(XLogRecPtr lsn, XLogRecord *record)
> {
> ...
>     HeapTupleHeaderClearHotUpdated(htup);
>     HeapTupleHeaderSetXmax(htup, xlrec->locking_xid);
>     HeapTupleHeaderSetCmax(htup, FirstCommandId, false);
>     /* Make sure there is no forward chain link in t_ctid */
>     htup->t_ctid = xlrec->target.tid;
> ...
> }

I think the fix is to reset HOT_UPDATED and t_ctid only if the infomask
says the tuple is LOCKED_ONLY, per the attached patch.  This matches
what heap_lock_tuple is doing originally:

        if (HEAP_XMAX_IS_LOCKED_ONLY(new_infomask))
                HeapTupleHeaderClearHotUpdated(tuple->t_data);
        HeapTupleHeaderSetXmax(tuple->t_data, xid);

        /*
         * Make sure there is no forward chain link in t_ctid.  Note that in the
         * cases where the tuple has been updated, we must not overwrite t_ctid,
         * because it was set by the updater.  Moreover, if the tuple has been
         * updated, we need to follow the update chain to lock the new versions 
of
         * the tuple as well.
         */
        if (HEAP_XMAX_IS_LOCKED_ONLY(new_infomask))
                tuple->t_data->t_ctid = *tid;

-- 
Álvaro Herrera                http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index a771ccb..6d1f9e0 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -8016,11 +8016,14 @@ heap_xlog_lock(XLogRecPtr lsn, XLogRecord *record)
 
 	fix_infomask_from_infobits(xlrec->infobits_set, &htup->t_infomask,
 							   &htup->t_infomask2);
-	HeapTupleHeaderClearHotUpdated(htup);
+	if (HEAP_XMAX_IS_LOCKED_ONLY(htup->t_infomask))
+	{
+		HeapTupleHeaderClearHotUpdated(htup);
+		/* Make sure there is no forward chain link in t_ctid */
+		htup->t_ctid = xlrec->target.tid;
+	}
 	HeapTupleHeaderSetXmax(htup, xlrec->locking_xid);
 	HeapTupleHeaderSetCmax(htup, FirstCommandId, false);
-	/* Make sure there is no forward chain link in t_ctid */
-	htup->t_ctid = xlrec->target.tid;
 	PageSetLSN(page, lsn);
 	MarkBufferDirty(buffer);
 	UnlockReleaseBuffer(buffer);
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to