When updating ShmemVariableCache from a checkpoint record, be sure to set
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 17 Feb 2010 03:10:33 +0000 (03:10 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 17 Feb 2010 03:10:33 +0000 (03:10 +0000)
all the values derived from oldestXid, not just that field.  Brain fade in
one of my patches associated with flat file removal, exposed by a report
from Fujii Masao.

With this change, xidVacLimit should always be valid, so remove a couple of
bits of complexity associated with the previous assumption that sometimes
it wouldn't get set right away.

src/backend/access/transam/varsup.c
src/backend/access/transam/xlog.c

index 79bc4ba58050504fe739dcf985211aa0ca3b6928..b1852779ccfbc039d5b609ece2ac64ae33b6eeb2 100644 (file)
@@ -6,7 +6,7 @@
  * Copyright (c) 2000-2010, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/access/transam/varsup.c,v 1.88 2010/02/14 18:42:12 rhaas Exp $
+ *       $PostgreSQL: pgsql/src/backend/access/transam/varsup.c,v 1.89 2010/02/17 03:10:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -71,13 +71,9 @@ GetNewTransactionId(bool isSubXact)
         * If we're past xidStopLimit, refuse to execute transactions, unless
         * we are running in a standalone backend (which gives an escape hatch
         * to the DBA who somehow got past the earlier defenses).
-        *
-        * Test is coded to fall out as fast as possible during normal operation,
-        * ie, when the vac limit is set and we haven't violated it.
         *----------
         */
-       if (TransactionIdFollowsOrEquals(xid, ShmemVariableCache->xidVacLimit) &&
-               TransactionIdIsValid(ShmemVariableCache->xidVacLimit))
+       if (TransactionIdFollowsOrEquals(xid, ShmemVariableCache->xidVacLimit))
        {
                /*
                 * For safety's sake, we release XidGenLock while sending signals,
@@ -340,11 +336,11 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid)
         * another iteration immediately if there are still any old databases.
         */
        if (TransactionIdFollowsOrEquals(curXid, xidVacLimit) &&
-               IsUnderPostmaster)
+               IsUnderPostmaster && !InRecovery)
                SendPostmasterSignal(PMSIGNAL_START_AUTOVAC_LAUNCHER);
 
        /* Give an immediate warning if past the wrap warn point */
-       if (TransactionIdFollowsOrEquals(curXid, xidWarnLimit))
+       if (TransactionIdFollowsOrEquals(curXid, xidWarnLimit) && !InRecovery)
        {
                char   *oldest_datname = get_database_name(oldest_datoid);
 
@@ -399,8 +395,9 @@ ForceTransactionIdLimitUpdate(void)
 
        if (!TransactionIdIsNormal(oldestXid))
                return true;                    /* shouldn't happen, but just in case */
-       if (TransactionIdFollowsOrEquals(nextXid, xidVacLimit) &&
-               TransactionIdIsValid(xidVacLimit))
+       if (!TransactionIdIsValid(xidVacLimit))
+               return true;                    /* this shouldn't happen anymore either */
+       if (TransactionIdFollowsOrEquals(nextXid, xidVacLimit))
                return true;                    /* past VacLimit, don't delay updating */
        if (!SearchSysCacheExists1(DATABASEOID, ObjectIdGetDatum(oldestXidDB)))
                return true;                    /* could happen, per comments above */
index e7b4516ee94228c2746ea1052de3561909efde76..3c1b077c5afda1a5a93293aaa69588a8770b16cc 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.373 2010/02/12 09:49:08 heikki Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.374 2010/02/17 03:10:33 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -4761,8 +4761,7 @@ BootStrapXLOG(void)
        ShmemVariableCache->nextOid = checkPoint.nextOid;
        ShmemVariableCache->oidCount = 0;
        MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
-       ShmemVariableCache->oldestXid = checkPoint.oldestXid;
-       ShmemVariableCache->oldestXidDB = checkPoint.oldestXidDB;
+       SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
 
        /* Set up the XLOG page header */
        page->xlp_magic = XLOG_PAGE_MAGIC;
@@ -5597,8 +5596,7 @@ StartupXLOG(void)
        ShmemVariableCache->nextOid = checkPoint.nextOid;
        ShmemVariableCache->oidCount = 0;
        MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
-       ShmemVariableCache->oldestXid = checkPoint.oldestXid;
-       ShmemVariableCache->oldestXidDB = checkPoint.oldestXidDB;
+       SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
 
        /*
         * We must replay WAL entries using the same TimeLineID they were created
@@ -7447,8 +7445,7 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record)
                ShmemVariableCache->oidCount = 0;
                MultiXactSetNextMXact(checkPoint.nextMulti,
                                                          checkPoint.nextMultiOffset);
-               ShmemVariableCache->oldestXid = checkPoint.oldestXid;
-               ShmemVariableCache->oldestXidDB = checkPoint.oldestXidDB;
+               SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
 
                /* Check to see if any changes to max_connections give problems */
                if (standbyState != STANDBY_DISABLED)
@@ -7502,10 +7499,8 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record)
                                                                  checkPoint.nextMultiOffset);
                if (TransactionIdPrecedes(ShmemVariableCache->oldestXid,
                                                                  checkPoint.oldestXid))
-               {
-                       ShmemVariableCache->oldestXid = checkPoint.oldestXid;
-                       ShmemVariableCache->oldestXidDB = checkPoint.oldestXidDB;
-               }
+                       SetTransactionIdLimit(checkPoint.oldestXid,
+                                                                 checkPoint.oldestXidDB);
 
                /* ControlFile->checkPointCopy always tracks the latest ckpt XID */
                ControlFile->checkPointCopy.nextXidEpoch = checkPoint.nextXidEpoch;