aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/cache/relcache.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2006-11-05 23:40:31 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2006-11-05 23:40:31 +0000
commit76d5667ba853092e31cc258c5b45d5bd04e59298 (patch)
treee9d4873f8fe09835fbab39b40a08b909021adce1 /src/backend/utils/cache/relcache.c
parent48188e1621bb6711e7d092bee48523b18cd80177 (diff)
downloadpostgresql-76d5667ba853092e31cc258c5b45d5bd04e59298.tar.gz
postgresql-76d5667ba853092e31cc258c5b45d5bd04e59298.zip
Fix recently-identified PITR recovery hazard: the base backup could contain
stale relcache init files (pg_internal.init), and there is no mechanism for updating them during WAL replay. Easiest solution is just to delete the init files at conclusion of startup, and let the first backend started in each database take care of rebuilding the init file. Simon Riggs and Tom Lane. Back-patched to 8.1. Arguably this should be fixed in 8.0 too, but it would require significantly more code since 8.0 has no handy startup-time scan of pg_database to piggyback on. Manual solution of the problem is possible in 8.0 (just delete the pg_internal.init files before starting WAL replay), so that may be a sufficient answer.
Diffstat (limited to 'src/backend/utils/cache/relcache.c')
-rw-r--r--src/backend/utils/cache/relcache.c24
1 files changed, 23 insertions, 1 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 */
+}