a21b7d5314
kudos to Alvaro Herrera See http://www.postgresql.org/message-id/CA+Tgmob8vfzYrLToqYr7uJ2moW3Gnv8rZpPtznxVXRPfTHQpCA@mail.gmail.com
47 lines
1.8 KiB
Diff
47 lines
1.8 KiB
Diff
commit 9a57858f1103b89a5674f0d50c5fe1f756411df6
|
|
Author: Alvaro Herrera <alvherre@alvh.no-ip.org>
|
|
Date: Thu Feb 27 11:13:39 2014 -0300
|
|
|
|
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.
|
|
|
|
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
|
|
index 33fc5a7..d94980b 100644
|
|
--- a/src/backend/access/heap/heapam.c
|
|
+++ b/src/backend/access/heap/heapam.c
|
|
@@ -7721,11 +7721,19 @@ heap_xlog_lock(XLogRecPtr lsn, XLogRecord *record)
|
|
|
|
fix_infomask_from_infobits(xlrec->infobits_set, &htup->t_infomask,
|
|
&htup->t_infomask2);
|
|
- HeapTupleHeaderClearHotUpdated(htup);
|
|
+
|
|
+ /*
|
|
+ * Clear relevant update flags, but only if the modified infomask says
|
|
+ * there's no update.
|
|
+ */
|
|
+ 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);
|