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