Commit c64339fa authored by Tom Lane's avatar Tom Lane

When updating ShmemVariableCache from a checkpoint record, be sure to set

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.
parent 711804fd
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Copyright (c) 2000-2010, PostgreSQL Global Development Group * Copyright (c) 2000-2010, PostgreSQL Global Development Group
* *
* IDENTIFICATION * 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) ...@@ -71,13 +71,9 @@ GetNewTransactionId(bool isSubXact)
* If we're past xidStopLimit, refuse to execute transactions, unless * If we're past xidStopLimit, refuse to execute transactions, unless
* we are running in a standalone backend (which gives an escape hatch * we are running in a standalone backend (which gives an escape hatch
* to the DBA who somehow got past the earlier defenses). * 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) && if (TransactionIdFollowsOrEquals(xid, ShmemVariableCache->xidVacLimit))
TransactionIdIsValid(ShmemVariableCache->xidVacLimit))
{ {
/* /*
* For safety's sake, we release XidGenLock while sending signals, * For safety's sake, we release XidGenLock while sending signals,
...@@ -340,11 +336,11 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) ...@@ -340,11 +336,11 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid)
* another iteration immediately if there are still any old databases. * another iteration immediately if there are still any old databases.
*/ */
if (TransactionIdFollowsOrEquals(curXid, xidVacLimit) && if (TransactionIdFollowsOrEquals(curXid, xidVacLimit) &&
IsUnderPostmaster) IsUnderPostmaster && !InRecovery)
SendPostmasterSignal(PMSIGNAL_START_AUTOVAC_LAUNCHER); SendPostmasterSignal(PMSIGNAL_START_AUTOVAC_LAUNCHER);
/* Give an immediate warning if past the wrap warn point */ /* 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); char *oldest_datname = get_database_name(oldest_datoid);
...@@ -399,8 +395,9 @@ ForceTransactionIdLimitUpdate(void) ...@@ -399,8 +395,9 @@ ForceTransactionIdLimitUpdate(void)
if (!TransactionIdIsNormal(oldestXid)) if (!TransactionIdIsNormal(oldestXid))
return true; /* shouldn't happen, but just in case */ return true; /* shouldn't happen, but just in case */
if (TransactionIdFollowsOrEquals(nextXid, xidVacLimit) && if (!TransactionIdIsValid(xidVacLimit))
TransactionIdIsValid(xidVacLimit)) return true; /* this shouldn't happen anymore either */
if (TransactionIdFollowsOrEquals(nextXid, xidVacLimit))
return true; /* past VacLimit, don't delay updating */ return true; /* past VacLimit, don't delay updating */
if (!SearchSysCacheExists1(DATABASEOID, ObjectIdGetDatum(oldestXidDB))) if (!SearchSysCacheExists1(DATABASEOID, ObjectIdGetDatum(oldestXidDB)))
return true; /* could happen, per comments above */ return true; /* could happen, per comments above */
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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) ...@@ -4761,8 +4761,7 @@ BootStrapXLOG(void)
ShmemVariableCache->nextOid = checkPoint.nextOid; ShmemVariableCache->nextOid = checkPoint.nextOid;
ShmemVariableCache->oidCount = 0; ShmemVariableCache->oidCount = 0;
MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset); MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
ShmemVariableCache->oldestXid = checkPoint.oldestXid; SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
ShmemVariableCache->oldestXidDB = checkPoint.oldestXidDB;
/* Set up the XLOG page header */ /* Set up the XLOG page header */
page->xlp_magic = XLOG_PAGE_MAGIC; page->xlp_magic = XLOG_PAGE_MAGIC;
...@@ -5597,8 +5596,7 @@ StartupXLOG(void) ...@@ -5597,8 +5596,7 @@ StartupXLOG(void)
ShmemVariableCache->nextOid = checkPoint.nextOid; ShmemVariableCache->nextOid = checkPoint.nextOid;
ShmemVariableCache->oidCount = 0; ShmemVariableCache->oidCount = 0;
MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset); MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset);
ShmemVariableCache->oldestXid = checkPoint.oldestXid; SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
ShmemVariableCache->oldestXidDB = checkPoint.oldestXidDB;
/* /*
* We must replay WAL entries using the same TimeLineID they were created * We must replay WAL entries using the same TimeLineID they were created
...@@ -7447,8 +7445,7 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record) ...@@ -7447,8 +7445,7 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record)
ShmemVariableCache->oidCount = 0; ShmemVariableCache->oidCount = 0;
MultiXactSetNextMXact(checkPoint.nextMulti, MultiXactSetNextMXact(checkPoint.nextMulti,
checkPoint.nextMultiOffset); checkPoint.nextMultiOffset);
ShmemVariableCache->oldestXid = checkPoint.oldestXid; SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB);
ShmemVariableCache->oldestXidDB = checkPoint.oldestXidDB;
/* Check to see if any changes to max_connections give problems */ /* Check to see if any changes to max_connections give problems */
if (standbyState != STANDBY_DISABLED) if (standbyState != STANDBY_DISABLED)
...@@ -7502,10 +7499,8 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record) ...@@ -7502,10 +7499,8 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record)
checkPoint.nextMultiOffset); checkPoint.nextMultiOffset);
if (TransactionIdPrecedes(ShmemVariableCache->oldestXid, if (TransactionIdPrecedes(ShmemVariableCache->oldestXid,
checkPoint.oldestXid)) checkPoint.oldestXid))
{ SetTransactionIdLimit(checkPoint.oldestXid,
ShmemVariableCache->oldestXid = checkPoint.oldestXid; checkPoint.oldestXidDB);
ShmemVariableCache->oldestXidDB = checkPoint.oldestXidDB;
}
/* ControlFile->checkPointCopy always tracks the latest ckpt XID */ /* ControlFile->checkPointCopy always tracks the latest ckpt XID */
ControlFile->checkPointCopy.nextXidEpoch = checkPoint.nextXidEpoch; ControlFile->checkPointCopy.nextXidEpoch = checkPoint.nextXidEpoch;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment