diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index dcb3365a7b..757580ccbe 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 464d94021a..38edc3a790 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 d5f63f3af3..d95a9a27fe 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 */