Fix pg_upgrade's multixact handling (again)
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Thu, 30 Apr 2015 16:55:06 +0000 (13:55 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Thu, 30 Apr 2015 16:55:06 +0000 (13:55 -0300)
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

index c8faa17703065eddf334584ef10596b6d05f9fcb..928f9fe5d6cc9847b2c7c01ddfded292a3e9135c 100644 (file)
@@ -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.