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