From c64339face6e9abd041ab58ade2aceb48a9f4956 Mon Sep 17 00:00:00 2001 From: Tom Lane <tgl@sss.pgh.pa.us> Date: Wed, 17 Feb 2010 03:10:33 +0000 Subject: [PATCH] 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. --- src/backend/access/transam/varsup.c | 17 +++++++---------- src/backend/access/transam/xlog.c | 17 ++++++----------- 2 files changed, 13 insertions(+), 21 deletions(-) diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 79bc4ba5805..b1852779ccf 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -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 */ diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index e7b4516ee94..3c1b077c5af 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -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; -- GitLab