aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/utils/cache/relcache.c24
-rw-r--r--src/backend/utils/init/flatfiles.c29
-rw-r--r--src/include/utils/relcache.h3
3 files changed, 50 insertions, 6 deletions
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 40e71d513d2..65cd1e72907 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.249 2006/10/04 00:30:00 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.250 2006/11/05 23:40:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -3586,3 +3586,25 @@ RelationCacheInitFileInvalidate(bool beforeSend)
LWLockRelease(RelCacheInitLock);
}
}
+
+/*
+ * Remove the init file for a given database during postmaster startup.
+ *
+ * We used to keep the init file across restarts, but that is unsafe in PITR
+ * scenarios, and even in simple crash-recovery cases there are windows for
+ * the init file to become out-of-sync with the database. So now we just
+ * remove it during startup and expect the first backend launch to rebuild it.
+ * Of course, this has to happen in each database of the cluster. For
+ * simplicity this is driven by flatfiles.c, which has to scan pg_database
+ * anyway.
+ */
+void
+RelationCacheInitFileRemove(const char *dbPath)
+{
+ char initfilename[MAXPGPATH];
+
+ snprintf(initfilename, sizeof(initfilename), "%s/%s",
+ dbPath, RELCACHE_INIT_FILENAME);
+ unlink(initfilename);
+ /* ignore any error, since it might not be there at all */
+}
diff --git a/src/backend/utils/init/flatfiles.c b/src/backend/utils/init/flatfiles.c
index dc117145fc0..ec104bb52a7 100644
--- a/src/backend/utils/init/flatfiles.c
+++ b/src/backend/utils/init/flatfiles.c
@@ -23,7 +23,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/utils/init/flatfiles.c,v 1.22 2006/11/05 22:42:09 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/init/flatfiles.c,v 1.23 2006/11/05 23:40:31 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -36,6 +36,7 @@
#include "access/transam.h"
#include "access/twophase_rmgr.h"
#include "access/xact.h"
+#include "catalog/catalog.h"
#include "catalog/pg_auth_members.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_database.h"
@@ -47,6 +48,7 @@
#include "storage/pmsignal.h"
#include "utils/builtins.h"
#include "utils/flatfiles.h"
+#include "utils/relcache.h"
#include "utils/resowner.h"
@@ -165,9 +167,14 @@ name_okay(const char *str)
*
* A side effect is to determine the oldest database's datfrozenxid
* so we can set or update the XID wrap limit.
+ *
+ * Also, if "startup" is true, we tell relcache.c to clear out the relcache
+ * init file in each database. That's a bit nonmodular, but scanning
+ * pg_database twice during system startup seems too high a price for keeping
+ * things better separated.
*/
static void
-write_database_file(Relation drel)
+write_database_file(Relation drel, bool startup)
{
char *filename,
*tempname;
@@ -248,6 +255,17 @@ write_database_file(Relation drel)
fputs_quote(datname, fp);
fprintf(fp, " %u %u %u\n",
datoid, dattablespace, datfrozenxid);
+
+ /*
+ * Also clear relcache init file for each DB if starting up.
+ */
+ if (startup)
+ {
+ char *dbpath = GetDatabasePath(datoid, dattablespace);
+
+ RelationCacheInitFileRemove(dbpath);
+ pfree(dbpath);
+ }
}
heap_endscan(scan);
@@ -669,6 +687,9 @@ write_auth_file(Relation rel_authid, Relation rel_authmem)
* policy means we need not force initdb to change the format of the
* flat files.
*
+ * We also cause relcache init files to be flushed, for largely the same
+ * reasons.
+ *
* In a standalone backend we pass database_only = true to skip processing
* the auth file. We won't need it, and building it could fail if there's
* something corrupt in the authid/authmem catalogs.
@@ -699,7 +720,7 @@ BuildFlatFiles(bool database_only)
/* No locking is needed because no one else is alive yet */
rel_db = XLogOpenRelation(rnode);
- write_database_file(rel_db);
+ write_database_file(rel_db, true);
if (!database_only)
{
@@ -811,7 +832,7 @@ AtEOXact_UpdateFlatFiles(bool isCommit)
if (database_file_update_subid != InvalidSubTransactionId)
{
database_file_update_subid = InvalidSubTransactionId;
- write_database_file(drel);
+ write_database_file(drel, false);
heap_close(drel, NoLock);
}
diff --git a/src/include/utils/relcache.h b/src/include/utils/relcache.h
index aa2b1608c19..ae09f4aa82f 100644
--- a/src/include/utils/relcache.h
+++ b/src/include/utils/relcache.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/relcache.h,v 1.55 2006/07/31 20:09:10 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/relcache.h,v 1.56 2006/11/05 23:40:31 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -69,6 +69,7 @@ extern void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid,
*/
extern bool RelationIdIsInInitFile(Oid relationId);
extern void RelationCacheInitFileInvalidate(bool beforeSend);
+extern void RelationCacheInitFileRemove(const char *dbPath);
/* should be used only by relcache.c and catcache.c */
extern bool criticalRelcachesBuilt;