On Wed, 2006-11-01 at 12:05 -0500, Tom Lane wrote: > I think we're probably better off to just forcibly remove the init file > during post-recovery cleanup. The easiest place to do this might be > BuildFlatFiles, which has to scan pg_database anyway ...
Patch enclosed. Clean apply to HEAD, make check OK, plus restart check. No specific PITR test, since same code path. -- Simon Riggs EnterpriseDB http://www.enterprisedb.com
Index: src/backend/utils/cache/inval.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/utils/cache/inval.c,v retrieving revision 1.78 diff -c -r1.78 inval.c *** src/backend/utils/cache/inval.c 4 Oct 2006 00:30:00 -0000 1.78 --- src/backend/utils/cache/inval.c 5 Nov 2006 22:00:03 -0000 *************** *** 767,776 **** SendSharedInvalidMessage(msg); break; case TWOPHASE_INFO_FILE_BEFORE: ! RelationCacheInitFileInvalidate(true); break; case TWOPHASE_INFO_FILE_AFTER: ! RelationCacheInitFileInvalidate(false); break; default: Assert(false); --- 767,776 ---- SendSharedInvalidMessage(msg); break; case TWOPHASE_INFO_FILE_BEFORE: ! RelationCacheInitFileInvalidate(true, DatabasePath); break; case TWOPHASE_INFO_FILE_AFTER: ! RelationCacheInitFileInvalidate(false, DatabasePath); break; default: Assert(false); *************** *** 817,823 **** * unless we committed. */ if (transInvalInfo->RelcacheInitFileInval) ! RelationCacheInitFileInvalidate(true); AppendInvalidationMessages(&transInvalInfo->PriorCmdInvalidMsgs, &transInvalInfo->CurrentCmdInvalidMsgs); --- 817,823 ---- * unless we committed. */ if (transInvalInfo->RelcacheInitFileInval) ! RelationCacheInitFileInvalidate(true, DatabasePath); AppendInvalidationMessages(&transInvalInfo->PriorCmdInvalidMsgs, &transInvalInfo->CurrentCmdInvalidMsgs); *************** *** 826,832 **** SendSharedInvalidMessage); if (transInvalInfo->RelcacheInitFileInval) ! RelationCacheInitFileInvalidate(false); } else if (transInvalInfo != NULL) { --- 826,832 ---- SendSharedInvalidMessage); if (transInvalInfo->RelcacheInitFileInval) ! RelationCacheInitFileInvalidate(false, DatabasePath); } else if (transInvalInfo != NULL) { Index: src/backend/utils/cache/relcache.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/utils/cache/relcache.c,v retrieving revision 1.249 diff -c -r1.249 relcache.c *** src/backend/utils/cache/relcache.c 4 Oct 2006 00:30:00 -0000 1.249 --- src/backend/utils/cache/relcache.c 5 Nov 2006 22:00:06 -0000 *************** *** 3559,3570 **** * no backend has been started since the last removal. */ void ! RelationCacheInitFileInvalidate(bool beforeSend) { char initfilename[MAXPGPATH]; snprintf(initfilename, sizeof(initfilename), "%s/%s", ! DatabasePath, RELCACHE_INIT_FILENAME); if (beforeSend) { --- 3559,3570 ---- * no backend has been started since the last removal. */ void ! RelationCacheInitFileInvalidate(bool beforeSend, char *ForDatabasePath) { char initfilename[MAXPGPATH]; snprintf(initfilename, sizeof(initfilename), "%s/%s", ! ForDatabasePath, RELCACHE_INIT_FILENAME); if (beforeSend) { Index: src/backend/utils/init/flatfiles.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/utils/init/flatfiles.c,v retrieving revision 1.21 diff -c -r1.21 flatfiles.c *** src/backend/utils/init/flatfiles.c 14 Jul 2006 14:52:25 -0000 1.21 --- src/backend/utils/init/flatfiles.c 5 Nov 2006 22:00:07 -0000 *************** *** 36,41 **** --- 36,42 ---- #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,52 **** --- 48,54 ---- #include "storage/pmsignal.h" #include "utils/builtins.h" #include "utils/flatfiles.h" + #include "utils/relcache.h" #include "utils/resowner.h" *************** *** 165,173 **** * * A side effect is to determine the oldest database's datminxid * so we can set or update the XID wrap limit. */ static void ! write_database_file(Relation drel) { char *filename, *tempname; --- 167,178 ---- * * A side effect is to determine the oldest database's datminxid * so we can set or update the XID wrap limit. + * + * removeDBRelInitFile is true only at startup, to allow us to + * remove the relcache init file as we read each database */ static void ! write_database_file(Relation drel, bool removeDBRelInitFile) { char *filename, *tempname; *************** *** 252,257 **** --- 257,278 ---- fputs_quote(datname, fp); fprintf(fp, " %u %u %u %u\n", datoid, dattablespace, datminxid, datvacuumxid); + + /* + * We call this at startup to remove the relcache init file + */ + if (removeDBRelInitFile) + { + char *dbpath = GetDatabasePath(datoid, dattablespace); + + ereport(DEBUG3, + (errmsg("removing pg_internal.init for database \%s\ ", + dbpath))); + + /* We call this once only, without interlock */ + RelationCacheInitFileInvalidate(true, dbpath); + pfree(dbpath); + } } heap_endscan(scan); *************** *** 703,709 **** /* No locking is needed because no one else is alive yet */ rel_db = XLogOpenRelation(rnode); ! write_database_file(rel_db); if (!database_only) { --- 724,734 ---- /* No locking is needed because no one else is alive yet */ rel_db = XLogOpenRelation(rnode); ! ! /* ! * Write database_file, plus unlink any rel cache init files ! */ ! write_database_file(rel_db, true); if (!database_only) { *************** *** 815,821 **** if (database_file_update_subid != InvalidSubTransactionId) { database_file_update_subid = InvalidSubTransactionId; ! write_database_file(drel); heap_close(drel, NoLock); } --- 840,846 ---- if (database_file_update_subid != InvalidSubTransactionId) { database_file_update_subid = InvalidSubTransactionId; ! write_database_file(drel, false); heap_close(drel, NoLock); } Index: src/include/utils/relcache.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/utils/relcache.h,v retrieving revision 1.55 diff -c -r1.55 relcache.h *** src/include/utils/relcache.h 31 Jul 2006 20:09:10 -0000 1.55 --- src/include/utils/relcache.h 5 Nov 2006 22:00:09 -0000 *************** *** 68,74 **** * Routines to help manage rebuilding of relcache init file */ extern bool RelationIdIsInInitFile(Oid relationId); ! extern void RelationCacheInitFileInvalidate(bool beforeSend); /* should be used only by relcache.c and catcache.c */ extern bool criticalRelcachesBuilt; --- 68,74 ---- * Routines to help manage rebuilding of relcache init file */ extern bool RelationIdIsInInitFile(Oid relationId); ! extern void RelationCacheInitFileInvalidate(bool beforeSend, char *ForDatabasePath); /* should be used only by relcache.c and catcache.c */ extern bool criticalRelcachesBuilt;
---------------------------(end of broadcast)--------------------------- TIP 9: In versions below 8.0, the planner will ignore your desire to choose an index scan if your joining column's datatypes do not match