From 669c7d20e6374850593cb430d332e11a3992bbcf Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Thu, 30 Apr 2015 13:55:06 -0300 Subject: [PATCH] Fix pg_upgrade's multixact handling (again) We need to create the pg_multixact/offsets file deleted by pg_upgrade much earlier than we originally were: it was in TrimMultiXact(), which runs after we exit recovery, but it actually needs to run earlier than the first call to SetMultiXactIdLimit (before recovery), because that routine already wants to read the first offset segment. Per pg_upgrade trouble report from Jeff Janes. While at it, silence a compiler warning about a pointless assert that an unsigned variable was being tested non-negative. This was a signed constant in Thomas Munro's patch which I changed to unsigned before commit. Pointed out by Andres Freund. --- src/backend/access/transam/multixact.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index c8faa17703..928f9fe5d6 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1970,14 +1970,6 @@ TrimMultiXact(void) int entryno; int flagsoff; - /* - * During a binary upgrade, make sure that the offsets SLRU is large - * enough to contain the next value that would be created. It's fine to do - * this here and not in StartupMultiXact() since binary upgrades should - * never need crash recovery. - */ - if (IsBinaryUpgrade) - MaybeExtendOffsetSlru(); /* Clean up offsets state */ LWLockAcquire(MultiXactOffsetControlLock, LW_EXCLUSIVE); @@ -2118,6 +2110,20 @@ MultiXactSetNextMXact(MultiXactId nextMulti, MultiXactState->nextMXact = nextMulti; MultiXactState->nextOffset = nextMultiOffset; LWLockRelease(MultiXactGenLock); + + /* + * During a binary upgrade, make sure that the offsets SLRU is large + * enough to contain the next value that would be created. + * + * We need to do this pretty early during the first startup in binary + * upgrade mode: before StartupMultiXact() in fact, because this routine is + * called even before that by StartupXLOG(). And we can't do it earlier + * than at this point, because during that first call of this routine we + * determine the MultiXactState->nextMXact value that MaybeExtendOffsetSlru + * needs. + */ + if (IsBinaryUpgrade) + MaybeExtendOffsetSlru(); } /* @@ -2513,8 +2519,6 @@ MultiXactOffsetWouldWrap(MultiXactOffset boundary, MultiXactOffset start, { MultiXactOffset finish; - Assert(distance >= 0); - /* * Note that offset number 0 is not used (see GetMultiXactIdMembers), so * if the addition wraps around the UINT_MAX boundary, skip that value.