From 16974ee9103ef7908e81869687b3fc3719e64a4e Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Thu, 27 May 2004 17:12:57 +0000
Subject: [PATCH] Get rid of the former rather baroque mechanism for
 propagating the values of ThisStartUpID and RedoRecPtr into new backends. 
 It's a lot easier just to make them all grab the values out of shared memory
 during startup. This helps to decouple the postmaster from checkpoint
 execution, which I need since I'm intending to let the bgwriter do it
 instead, and it also fixes a bug in the Win32 port: ThisStartUpID wasn't
 getting propagated at all AFAICS.  (Doesn't give me a lot of faith in the
 amount of testing that port has gotten.)

---
 src/backend/access/heap/heapam.c    |  4 +--
 src/backend/access/transam/xlog.c   | 51 ++++++++++-------------------
 src/backend/bootstrap/bootstrap.c   |  7 ++--
 src/backend/postmaster/postmaster.c | 20 +++--------
 src/backend/utils/init/postinit.c   |  9 ++++-
 src/include/access/xlog.h           |  6 ++--
 6 files changed, 38 insertions(+), 59 deletions(-)

diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 44b472d7e3b..cb1e6893053 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.167 2004/05/20 15:07:30 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.168 2004/05/27 17:12:37 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -1902,7 +1902,7 @@ l3:
 	 * XLOG stuff: no logging is required as long as we have no
 	 * savepoints. For savepoints private log could be used...
 	 */
-	((PageHeader) BufferGetPage(*buffer))->pd_sui = ThisStartUpID;
+	PageSetSUI(BufferGetPage(*buffer), ThisStartUpID);
 
 	/* store transaction information of xact marking the tuple */
 	tuple->t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED |
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 1e593a9c823..0af9d2910d4 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.142 2004/05/21 16:08:46 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.143 2004/05/27 17:12:42 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -166,9 +166,10 @@ XLogRecPtr	ProcLastRecEnd = {0, 0};
  * XLogCtl->Insert.RedoRecPtr, whenever we can safely do so (ie, when we
  * hold the Insert lock).  See XLogInsert for details.	We are also allowed
  * to update from XLogCtl->Insert.RedoRecPtr if we hold the info_lck;
- * see GetRedoRecPtr.
+ * see GetRedoRecPtr.  A freshly spawned backend obtains the value during
+ * InitXLOGAccess.
  */
-NON_EXEC_STATIC XLogRecPtr RedoRecPtr;
+static XLogRecPtr RedoRecPtr;
 
 /*----------
  * Shared-memory data structures for XLOG control
@@ -280,10 +281,6 @@ typedef struct XLogCtlData
 	uint32		XLogCacheBlck;	/* highest allocated xlog buffer index */
 	StartUpID	ThisStartUpID;
 
-	/* This value is not protected by *any* lock... */
-	/* see SetSavedRedoRecPtr/GetSavedRedoRecPtr */
-	XLogRecPtr	SavedRedoRecPtr;
-
 	slock_t		info_lck;		/* locks shared LogwrtRqst/LogwrtResult */
 } XLogCtlData;
 
@@ -2893,8 +2890,7 @@ StartupXLOG(void)
 	else
 		ThisStartUpID = checkPoint.ThisStartUpID;
 
-	RedoRecPtr = XLogCtl->Insert.RedoRecPtr =
-		XLogCtl->SavedRedoRecPtr = checkPoint.redo;
+	RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo;
 
 	if (XLByteLT(RecPtr, checkPoint.redo))
 		ereport(PANIC,
@@ -3251,35 +3247,22 @@ ReadCheckpointRecord(XLogRecPtr RecPtr,
 }
 
 /*
- * Postmaster uses this to initialize ThisStartUpID & RedoRecPtr from
- * XLogCtlData located in shmem after successful startup.
+ * This must be called during startup of a backend process, except that
+ * it need not be called in a standalone backend (which does StartupXLOG
+ * instead).  We need to initialize the local copies of ThisStartUpID and
+ * RedoRecPtr.
+ *
+ * Note: before Postgres 7.5, we went to some effort to keep the postmaster
+ * process's copies of ThisStartUpID and RedoRecPtr valid too.  This was
+ * unnecessary however, since the postmaster itself never touches XLOG anyway.
  */
 void
-SetThisStartUpID(void)
+InitXLOGAccess(void)
 {
+	/* ThisStartUpID doesn't change so we need no lock to copy it */
 	ThisStartUpID = XLogCtl->ThisStartUpID;
-	RedoRecPtr = XLogCtl->SavedRedoRecPtr;
-}
-
-/*
- * CheckPoint process called by postmaster saves copy of new RedoRecPtr
- * in shmem (using SetSavedRedoRecPtr).  When checkpointer completes,
- * postmaster calls GetSavedRedoRecPtr to update its own copy of RedoRecPtr,
- * so that subsequently-spawned backends will start out with a reasonably
- * up-to-date local RedoRecPtr.  Since these operations are not protected by
- * any lock and copying an XLogRecPtr isn't atomic, it's unsafe to use either
- * of these routines at other times!
- */
-void
-SetSavedRedoRecPtr(void)
-{
-	XLogCtl->SavedRedoRecPtr = RedoRecPtr;
-}
-
-void
-GetSavedRedoRecPtr(void)
-{
-	RedoRecPtr = XLogCtl->SavedRedoRecPtr;
+	/* Use GetRedoRecPtr to copy the RedoRecPtr safely */
+	(void) GetRedoRecPtr();
 }
 
 /*
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 3aca65e845c..315c17e526a 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.179 2004/05/21 05:07:56 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.180 2004/05/27 17:12:49 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -489,12 +489,12 @@ BootstrapMain(int argc, char *argv[])
 			break;
 
 		case BS_XLOG_CHECKPOINT:
+			InitXLOGAccess();
 			CreateCheckPoint(false, false);
-			SetSavedRedoRecPtr();		/* pass redo ptr back to
-										 * postmaster */
 			proc_exit(0);		/* done */
 
 		case BS_XLOG_BGWRITER:
+			InitXLOGAccess();
 			BufferBackgroundWriter();
 			proc_exit(0);		/* done */
 
@@ -504,6 +504,7 @@ BootstrapMain(int argc, char *argv[])
 			proc_exit(0);		/* done */
 
 		case BS_XLOG_SHUTDOWN:
+			InitXLOGAccess();
 			ShutdownXLOG(0, 0);
 			DumpFreeSpaceMap(0, 0);
 			proc_exit(0);		/* done */
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 3926408d7c9..2679ea6bf9b 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.396 2004/05/27 15:07:41 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.397 2004/05/27 17:12:52 tgl Exp $
  *
  * NOTES
  *
@@ -1909,8 +1909,8 @@ reaper(SIGNAL_ARGS)
 		 * trouble...
 		 */
 		win32_RemoveChild(pid);
-#endif
-#endif
+#endif /* WIN32 */
+#endif /* HAVE_WAITPID */
 
 		/*
 		 * Check if this child was the statistics collector. If so, try to
@@ -1953,14 +1953,9 @@ reaper(SIGNAL_ARGS)
 			StartupPID = 0;
 
 			/*
-			 * Startup succeeded - remember its ID and RedoRecPtr.
-			 *
-			 * NB: this MUST happen before we fork a checkpoint or shutdown
-			 * subprocess, else they will have wrong local ThisStartUpId.
+			 * Startup succeeded - we are done with system startup or recovery.
 			 */
-			SetThisStartUpID();
-
-			FatalError = false; /* done with recovery */
+			FatalError = false;
 
 			/*
 			 * Arrange for first checkpoint to occur after standard delay.
@@ -2073,8 +2068,6 @@ CleanupProc(int pid,
 			if (!FatalError)
 			{
 				checkpointed = time(NULL);
-				/* Update RedoRecPtr for future child backends */
-				GetSavedRedoRecPtr();
 			}
 		}
 		else if (pid == BgWriterPID)
@@ -3287,7 +3280,6 @@ postmaster_error(const char *fmt,...)
  * functions
  */
 #include "storage/spin.h"
-extern XLogRecPtr RedoRecPtr;
 extern XLogwrtResult LogwrtResult;
 extern slock_t *ShmemLock;
 extern slock_t *ShmemIndexLock;
@@ -3351,7 +3343,6 @@ write_backend_variables(Port *port)
 	}
 	write_var(MyCancelKey, fp);
 
-	write_var(RedoRecPtr, fp);
 	write_var(LogwrtResult, fp);
 
 	write_var(UsedShmemSegID, fp);
@@ -3416,7 +3407,6 @@ read_backend_variables(unsigned long id, Port *port)
 	}
 	read_var(MyCancelKey, fp);
 
-	read_var(RedoRecPtr, fp);
 	read_var(LogwrtResult, fp);
 
 	read_var(UsedShmemSegID, fp);
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index ba446310530..69d4d974099 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.131 2003/12/12 18:45:09 petere Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.132 2004/05/27 17:12:54 tgl Exp $
  *
  *
  *-------------------------------------------------------------------------
@@ -325,6 +325,13 @@ InitPostgres(const char *dbname, const char *username)
 	 */
 	AmiTransactionOverride(bootstrap);
 
+	/*
+	 * Initialize local process's access to XLOG.  In bootstrap case
+	 * we may skip this since StartupXLOG() was run instead.
+	 */
+	if (!bootstrap)
+		InitXLOGAccess();
+
 	/*
 	 * Initialize the relation descriptor cache.  This must create at
 	 * least the minimum set of "nailed-in" cache entries.	No catalog
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index 8f9d97adad3..b0ebedcf329 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.49 2004/02/11 22:55:25 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/access/xlog.h,v 1.50 2004/05/27 17:12:57 tgl Exp $
  */
 #ifndef XLOG_H
 #define XLOG_H
@@ -230,11 +230,9 @@ extern void XLOGPathInit(void);
 extern void BootStrapXLOG(void);
 extern void StartupXLOG(void);
 extern void ShutdownXLOG(int code, Datum arg);
+extern void InitXLOGAccess(void);
 extern void CreateCheckPoint(bool shutdown, bool force);
-extern void SetThisStartUpID(void);
 extern void XLogPutNextOid(Oid nextOid);
-extern void SetSavedRedoRecPtr(void);
-extern void GetSavedRedoRecPtr(void);
 extern XLogRecPtr GetRedoRecPtr(void);
 
 /* in storage/ipc/sinval.c, but don't want to declare in sinval.h because
-- 
GitLab