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

Reply via email to