Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 5ab0ad5

Browse files
committed
VACUUM must make sure that a HEAP_MARKED_FOR_UPDATE tuple gets marked
as either HEAP_XMAX_COMMITTED or HEAP_XMAX_INVALID once the updating transaction is gone. Otherwise some other transaction may come along and try to test the commit status of t_xmax later --- which could be after VACUUM has recycled the CLOG status for that xact. Bug introduced in post-beta4 bug fix.
1 parent eb5e8ba commit 5ab0ad5

File tree

1 file changed

+16
-2
lines changed

1 file changed

+16
-2
lines changed

src/backend/utils/time/tqual.c

+16-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.45 2001/12/19 17:18:39 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.46 2002/01/11 20:07:03 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -742,7 +742,21 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin)
742742

743743
if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
744744
{
745-
/* "deleting" xact really only marked it for update */
745+
/*
746+
* "Deleting" xact really only marked it for update, so the tuple
747+
* is live in any case. However, we must make sure that either
748+
* XMAX_COMMITTED or XMAX_INVALID gets set once the xact is gone;
749+
* otherwise it is unsafe to recycle CLOG status after vacuuming.
750+
*/
751+
if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
752+
{
753+
if (TransactionIdIsInProgress(tuple->t_xmax))
754+
return HEAPTUPLE_LIVE;
755+
if (TransactionIdDidCommit(tuple->t_xmax))
756+
tuple->t_infomask |= HEAP_XMAX_COMMITTED;
757+
else /* it's either aborted or crashed */
758+
tuple->t_infomask |= HEAP_XMAX_INVALID;
759+
}
746760
return HEAPTUPLE_LIVE;
747761
}
748762

0 commit comments

Comments
 (0)