From 87d95ca04d0b794c2ba49f40f6a2ee1d94835cac Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sat, 1 May 1999 19:09:46 +0000
Subject: [PATCH] Arrange for VACUUM to delete the init file that relcache.c
 uses to save a little bit of backend startup time.  This way, the first
 backend started after a VACUUM will rebuild the init file with up-to-date
 statistics for the critical system indexes.

---
 src/backend/commands/vacuum.c      | 18 +++++++++++++--
 src/backend/utils/cache/relcache.c | 35 +++++++++++++++---------------
 src/include/utils/relcache.h       |  8 ++++++-
 3 files changed, 41 insertions(+), 20 deletions(-)

diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index dcb3365a7ba..757580ccbe8 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.99 1999/04/12 16:56:36 vadim Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.100 1999/05/01 19:09:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -46,6 +46,7 @@
 #include "utils/inval.h"
 #include "utils/mcxt.h"
 #include "utils/portal.h"
+#include "utils/relcache.h"
 #include "utils/syscache.h"
 
 #ifndef HAVE_GETRUSAGE
@@ -219,7 +220,20 @@ vc_init()
 static void
 vc_shutdown()
 {
-	/* on entry, not in a transaction */
+	/* on entry, we are not in a transaction */
+
+	/* Flush the init file that relcache.c uses to save startup time.
+	 * The next backend startup will rebuild the init file with up-to-date
+	 * information from pg_class.  This lets the optimizer see the stats that
+	 * we've collected for certain critical system indexes.  See relcache.c
+	 * for more details.
+	 *
+	 * Ignore any failure to unlink the file, since it might not be there
+	 * if no backend has been started since the last vacuum...
+	 */
+	unlink(RELCACHE_INIT_FILENAME);
+
+	/* remove the vacuum cleaner lock file */
 	if (unlink("pg_vlock") < 0)
 		elog(ERROR, "vacuum: can't destroy lock file!");
 
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 464d94021a6..38edc3a790a 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.59 1999/02/21 03:49:36 scrappy Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.60 1999/05/01 19:09:44 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -77,7 +77,6 @@
 #include "utils/memutils.h"
 #include "utils/rel.h"
 #include "utils/relcache.h"
-#include "utils/relcache.h"
 #include "utils/syscache.h"
 
 
@@ -87,13 +86,6 @@ static Relation RelationNameCacheGetRelation(char *relationName);
 static void init_irels(void);
 static void write_irels(void);
 
-/* ----------------
- *		defines
- * ----------------
- */
-#define private static
-#define INIT_FILENAME	"pg_internal.init"
-
 /* ----------------
  *		externs
  * ----------------
@@ -1826,11 +1818,20 @@ RelCheckFetch(Relation relation)
  *			  from an initialization file in the data/base/... directory.
  *
  *		   +  If the initialization file isn't there, then we create the
- *			  relation descriptor using sequential scans and write it to
+ *			  relation descriptors using sequential scans and write 'em to
  *			  the initialization file for use by subsequent backends.
  *
- *		This is complicated and interferes with system changes, but
- *		performance is so bad that we're willing to pay the tax.
+ *		We could dispense with the initialization file and just build the
+ *		critical reldescs the hard way on every backend startup, but that
+ *		slows down backend startup noticeably if pg_class is large.
+ *
+ *		As of v6.5, vacuum.c deletes the initialization file at completion
+ *		of a VACUUM, so that it will be rebuilt at the next backend startup.
+ *		This ensures that vacuum-collected stats for the system indexes
+ *		will eventually get used by the optimizer --- otherwise the relcache
+ *		entries for these indexes will show zero sizes forever, since the
+ *		relcache entries are pinned in memory and will never be reloaded
+ *		from pg_class.
  */
 
 /* pg_attnumind, pg_classnameind, pg_classoidind */
@@ -1852,9 +1853,9 @@ init_irels(void)
 	int			relno;
 
 #ifndef __CYGWIN32__
-	if ((fd = FileNameOpenFile(INIT_FILENAME, O_RDONLY, 0600)) < 0)
+	if ((fd = FileNameOpenFile(RELCACHE_INIT_FILENAME, O_RDONLY, 0600)) < 0)
 #else
-	if ((fd = FileNameOpenFile(INIT_FILENAME, O_RDONLY | O_BINARY, 0600)) < 0)
+	if ((fd = FileNameOpenFile(RELCACHE_INIT_FILENAME, O_RDONLY | O_BINARY, 0600)) < 0)
 #endif
 	{
 		write_irels();
@@ -2017,12 +2018,12 @@ write_irels(void)
 	RelationBuildDescInfo bi;
 
 #ifndef __CYGWIN32__
-	fd = FileNameOpenFile(INIT_FILENAME, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+	fd = FileNameOpenFile(RELCACHE_INIT_FILENAME, O_WRONLY | O_CREAT | O_TRUNC, 0600);
 #else
-	fd = FileNameOpenFile(INIT_FILENAME, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0600);
+	fd = FileNameOpenFile(RELCACHE_INIT_FILENAME, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0600);
 #endif
 	if (fd < 0)
-		elog(FATAL, "cannot create init file %s", INIT_FILENAME);
+		elog(FATAL, "cannot create init file %s", RELCACHE_INIT_FILENAME);
 
 	FileSeek(fd, 0L, SEEK_SET);
 
diff --git a/src/include/utils/relcache.h b/src/include/utils/relcache.h
index d5f63f3af31..d95a9a27fe3 100644
--- a/src/include/utils/relcache.h
+++ b/src/include/utils/relcache.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: relcache.h,v 1.11 1999/02/13 23:22:31 momjian Exp $
+ * $Id: relcache.h,v 1.12 1999/05/01 19:09:43 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -34,4 +34,10 @@ extern void RelationRegisterRelation(Relation relation);
 extern void RelationPurgeLocalRelation(bool xactComitted);
 extern void RelationInitialize(void);
 
+/*
+ * both vacuum.c and relcache.c need to know the name of the relcache init file
+ */
+
+#define RELCACHE_INIT_FILENAME	"pg_internal.init"
+
 #endif	 /* RELCACHE_H */
-- 
GitLab