Alvaro Herrera <> wrote:
He means that the tuple that heap_update moves to page 1 (which will no
longer be processed by vacuum) will contain a multixact that's older
than relminmxid -- because it is copied unchanged by heap_update instead
of properly checking against age limit.

I see. The problem is more or less with this heap_update() code:

    * And also prepare an Xmax value for the new copy of the tuple.  If there
    * was no xmax previously, or there was one but all lockers are now gone,
    * then use InvalidXid; otherwise, get the xmax from the old tuple.  (In
    * rare cases that might also be InvalidXid and yet not have the
    * HEAP_XMAX_INVALID bit set; that's fine.)
   if ((oldtup.t_data->t_infomask & HEAP_XMAX_INVALID) ||
       HEAP_LOCKED_UPGRADED(oldtup.t_data->t_infomask) ||
       (checked_lockers && !locker_remains))
       xmax_new_tuple = InvalidTransactionId;
       xmax_new_tuple = HeapTupleHeaderGetRawXmax(oldtup.t_data);

My naive guess is that we have to create a new MultiXactId here in at
least some cases, just like FreezeMultiXactId() sometimes does.

Peter Geoghegan

Sent via pgsql-hackers mailing list (
To make changes to your subscription:

Reply via email to