When updating ShmemVariableCache from a checkpoint record, be sure to set
authorTom Lane
Wed, 17 Feb 2010 03:10:33 +0000 (03:10 +0000)
committerTom Lane
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;