postgres.git / summary / log / commit / refs

commit    a25c2b7c4db3b4542e05d660e55bef5c93fdc32d
Author:   Alvaro Herrera <alvherre@alvh.no-ip.org>
Date:     Fri Jan 10 21:03:18 2014 +0000

    Accept pg_upgraded tuples during multixact freezing
    
    The new MultiXact freezing routines introduced by commit 8e9a16ab8f7
    neglected to consider tuples that came from a pg_upgrade'd database; a
    vacuum run that tried to freeze such tuples would die with an error such
    as
    ERROR: MultiXactId 11415437 does no longer exist -- apparent wraparound
    
    To fix, ensure that GetMultiXactIdMembers is allowed to return empty
    multis when the infomask bits are right, as is done in other callsites.
    
    Per trouble report from F-Secure.
    
    In passing, fix a copy&paste bug reported by Andrey Karpov from VIVA64
    from their PVS-Studio static checked, that instead of setting relminmxid
    to Invalid, we were setting relfrozenxid twice.  Not an important
    mistake because that code branch is about relations for which we don't
    use the frozenxid/minmxid values at all in the first place, but seems to
    warrants a fix nonetheless.


src/backend/access/heap/heapam.c | 10 ++++++++-- src/backend/catalog/heap.c | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index b5977da8f0f..33fc5a75c6f 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -5288,6 +5288,7 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask, bool has_lockers; TransactionId update_xid; bool update_committed; + bool allow_old; *flags = 0; @@ -5349,7 +5350,9 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask, * anything. */ - nmembers = GetMultiXactIdMembers(multi, &members, false); + allow_old = !(t_infomask & HEAP_LOCK_MASK) && + HEAP_XMAX_IS_LOCKED_ONLY(t_infomask); + nmembers = GetMultiXactIdMembers(multi, &members, allow_old); if (nmembers <= 0) { /* Nothing worth keeping */ @@ -6060,10 +6063,13 @@ heap_tuple_needs_freeze(HeapTupleHeader tuple, TransactionId cutoff_xid, MultiXactMember *members; int nmembers; int i; + bool allow_old; /* need to check whether any member of the mxact is too old */ - nmembers = GetMultiXactIdMembers(multi, &members, false); + allow_old = !(tuple->t_infomask & HEAP_LOCK_MASK) && + HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask); + nmembers = GetMultiXactIdMembers(multi, &members, allow_old); for (i = 0; i < nmembers; i++) { diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 3ee302794b1..c06427711f2 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -903,7 +903,7 @@ AddNewRelationTuple(Relation pg_class_desc, * commands/sequence.c.) */ new_rel_reltup->relfrozenxid = InvalidTransactionId; - new_rel_reltup->relfrozenxid = InvalidMultiXactId; + new_rel_reltup->relminmxid = InvalidMultiXactId; } new_rel_reltup->relowner = relowner; [parent: 28fff0ef8b1f]