Re: [COMMITTERS] pgsql: Fix traversal of half-frozen update chains - Mailing list pgsql-committers

From Alvaro Herrera
Subject Re: [COMMITTERS] pgsql: Fix traversal of half-frozen update chains
Date
Msg-id 20171017104059.sq76kgd42ld55npp@alvherre.pgsql
Whole thread Raw
In response to Re: [COMMITTERS] pgsql: Fix traversal of half-frozen update chains  (Peter Geoghegan <pg@bowt.ie>)
Responses Re: [COMMITTERS] pgsql: Fix traversal of half-frozen update chains  (Peter Geoghegan <pg@bowt.ie>)
Re: [COMMITTERS] pgsql: Fix traversal of half-frozen update chains  (Peter Geoghegan <pg@bowt.ie>)
List pgsql-committers
Peter Geoghegan wrote:

> Wouldn't this last "if" test, to cover the pg_upgrade case, be better
> targeted by comparing *raw* xmin to FrozenTransactionId? You're using
> the potentially distinct xmin value returned by
> HeapTupleHeaderGetXmin() for the test here. I think we should be
> directly targeting tuples frozen on or before 9.4 (prior to
> pg_upgrade) instead.

I also realized we can stop checking (i.e. don't compare xmin to
frozenxid) if the XMIN_FROZEN bits are set -- because in that case the
tuple cannot possibly come from 9.3 frozen.  So I think this should do
it.

/** HeapTupleUpdateXmaxMatchesXmin - verify update chain xmax/xmin lineage** Given the new version of a tuple after
someupdate, verify whether the* given Xmax (corresponding to the previous version) matches the tuple's* Xmin, taking
intoaccount that the Xmin might have been frozen after the* update.*/
 
bool
HeapTupleUpdateXmaxMatchesXmin(TransactionId xmax, HeapTupleHeader htup)
{TransactionId    rawxmin = HeapTupleHeaderGetRawXmin(htup);TransactionId    xmin = HeapTupleHeaderGetXmin(htup);
/* * If the xmax of the old tuple is identical to the xmin of the new one, * it's a match. */if
(TransactionIdEquals(xmax,xmin))    return true;
 
/* * If the HEAP_XMIN_FROZEN flag is set, then we know it can only be a match * if the Xmin before the freezing is
identicalto the Xmax -- we can skip * the fuzzy pg_upgraded check below. */if (HeapTupleHeaderXminFrozen(htup)){    if
(TransactionIdEquals(rawxmin,xmax))        return true;    else        return false;}
 
/* * When a tuple is frozen, the original Xmin is lost, but we know it's a * committed transaction.  So unless the Xmax
isInvalidXid, we don't know * for certain that there is a match, but there may be one; and we must * return true so
thata HOT chain that is half-frozen can be walked * correctly. * * We no longer freeze tuples this way, but we must
keepthis in order to * interpret pre-pg_upgrade pages correctly. */if (TransactionIdEquals(rawxmin,
FrozenTransactionId)&&    TransactionIdIsValid(xmax))    return true;
 
return false;
}

-- 
Álvaro Herrera                https://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services


-- 
Sent via pgsql-committers mailing list (pgsql-committers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-committers

pgsql-committers by date:

Previous
From: Alvaro Herrera
Date:
Subject: [COMMITTERS] pgsql: REASSIGN OWNED BY doc: s/privileges/membership/
Next
From: Tom Lane
Date:
Subject: [COMMITTERS] pgsql: Fix misparsing of non-newline-terminated pg_hba.conf files.