Make HEAP_LOCK/HEAP2_LOCK_UPDATED replay reset HEAP_XMAX_INVALID.
authorAndres Freund
Fri, 15 Jul 2016 21:37:06 +0000 (14:37 -0700)
committerAndres Freund
Fri, 15 Jul 2016 21:50:46 +0000 (14:50 -0700)
0ac5ad5 started to compress infomask bits in WAL records. Unfortunately
the replay routines for XLOG_HEAP_LOCK/XLOG_HEAP2_LOCK_UPDATED forgot to
reset the HEAP_XMAX_INVALID (and some other) hint bits.

Luckily that's not problematic in the majority of cases, because after a
crash/on a standby row locks aren't meaningful. Unfortunately that does
not hold true in the presence of prepared transactions. This means that
after a crash, or after promotion, row level locks held by a prepared,
but not yet committed, prepared transaction might not be enforced.

Discussion: 20160715192319[email protected]
Backpatch: 9.3, the oldest branch on which 0ac5ad5 is present.

src/backend/access/heap/heapam.c

index 05c1304704012c6e1636640aa7b52101bb800717..e29d4ab4fa675f03555f862db97e0079d2719cd6 100644 (file)
@@ -8381,6 +8381,8 @@ heap_xlog_lock(XLogRecPtr lsn, XLogRecord *record)
 
    htup = (HeapTupleHeader) PageGetItem(page, lp);
 
+   htup->t_infomask &= ~(HEAP_XMAX_BITS | HEAP_MOVED);
+   htup->t_infomask2 &= ~HEAP_KEYS_UPDATED;
    fix_infomask_from_infobits(xlrec->infobits_set, &htup->t_infomask,
                               &htup->t_infomask2);
 
@@ -8441,6 +8443,8 @@ heap_xlog_lock_updated(XLogRecPtr lsn, XLogRecord *record)
 
    htup = (HeapTupleHeader) PageGetItem(page, lp);
 
+   htup->t_infomask &= ~(HEAP_XMAX_BITS | HEAP_MOVED);
+   htup->t_infomask2 &= ~HEAP_KEYS_UPDATED;
    fix_infomask_from_infobits(xlrec->infobits_set, &htup->t_infomask,
                               &htup->t_infomask2);
    HeapTupleHeaderSetXmax(htup, xlrec->xmax);