Enclose a patch for new WAL records for relcache invalidation.

Not conclusively tested, but seems to work fine, so please regard this
as a prototype-needs-review.

We definitely need a regr test framework to support this type of patch.

-- 
  Simon Riggs             
  EnterpriseDB   http://www.enterprisedb.com

Index: src/backend/access/transam/rmgr.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/access/transam/rmgr.c,v
retrieving revision 1.24
diff -c -r1.24 rmgr.c
*** src/backend/access/transam/rmgr.c	7 Aug 2006 16:57:56 -0000	1.24
--- src/backend/access/transam/rmgr.c	27 Oct 2006 20:36:09 -0000
***************
*** 20,25 ****
--- 20,26 ----
  #include "commands/sequence.h"
  #include "commands/tablespace.h"
  #include "storage/smgr.h"
+ #include "utils/relcache.h"
  
  
  const RmgrData RmgrTable[RM_MAX_ID + 1] = {
***************
*** 30,36 ****
  	{"Database", dbase_redo, dbase_desc, NULL, NULL, NULL},
  	{"Tablespace", tblspc_redo, tblspc_desc, NULL, NULL, NULL},
  	{"MultiXact", multixact_redo, multixact_desc, NULL, NULL, NULL},
! 	{"Reserved 7", NULL, NULL, NULL, NULL, NULL},
  	{"Reserved 8", NULL, NULL, NULL, NULL, NULL},
  	{"Reserved 9", NULL, NULL, NULL, NULL, NULL},
  	{"Heap", heap_redo, heap_desc, NULL, NULL, NULL},
--- 31,37 ----
  	{"Database", dbase_redo, dbase_desc, NULL, NULL, NULL},
  	{"Tablespace", tblspc_redo, tblspc_desc, NULL, NULL, NULL},
  	{"MultiXact", multixact_redo, multixact_desc, NULL, NULL, NULL},
! 	{"Cache", cache_redo, cache_desc, NULL, NULL, NULL},
  	{"Reserved 8", NULL, NULL, NULL, NULL, NULL},
  	{"Reserved 9", NULL, NULL, NULL, NULL, NULL},
  	{"Heap", heap_redo, heap_desc, NULL, NULL, NULL},
Index: src/backend/access/transam/xlog.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/access/transam/xlog.c,v
retrieving revision 1.252
diff -c -r1.252 xlog.c
*** src/backend/access/transam/xlog.c	18 Oct 2006 22:44:11 -0000	1.252
--- src/backend/access/transam/xlog.c	27 Oct 2006 20:36:19 -0000
***************
*** 46,51 ****
--- 46,52 ----
  #include "utils/builtins.h"
  #include "utils/nabstime.h"
  #include "utils/pg_locale.h"
+ #include "utils/relcache.h"
  
  
  /*
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	27 Oct 2006 20:36:24 -0000
***************
*** 3568,3575 ****
  
  	if (beforeSend)
  	{
  		/* no interlock needed here */
! 		unlink(initfilename);
  	}
  	else
  	{
--- 3568,3599 ----
  
  	if (beforeSend)
  	{
+ 		/*
+ 		 * Make a non-transactional XLOG entry showing the file removal
+ 		 * It's non-transactional because we should replay it whether the
+ 		 * transaction commits or not; the underlying file change is certainly
+ 		 * not reversible. We do this *once* because we don't need to process
+          * invalidation messages during WAL reply, so even though the file
+          * is unlinked twice during normal invalidation sequence we need only
+          * do this once during WAL replay and so need only write WAL once.
+ 		 */
+ 		XLogRecPtr	lsn;
+ 		XLogRecData rdata;
+ 		xl_cache_init_file_inval xlrec;
+ 
+         xlrec.dbOid = MyDatabaseId;
+         xlrec.dbTableSpaceOid = MyDatabaseTableSpace;
+ 
+ 		rdata.data = (char *) &xlrec;
+ 		rdata.len = sizeof(xlrec);
+ 		rdata.buffer = InvalidBuffer;
+ 		rdata.next = NULL;
+ 
+ 		lsn = XLogInsert(RM_CACHE_ID, XLOG_CACHE_INIT_FILE_INVAL | XLOG_NO_TRAN,
+ 						 &rdata);
+ 
  		/* no interlock needed here */
!         unlink(initfilename);
  	}
  	else
  	{
***************
*** 3582,3588 ****
  		 * that we will execute second and successfully unlink the file.
  		 */
  		LWLockAcquire(RelCacheInitLock, LW_EXCLUSIVE);
! 		unlink(initfilename);
  		LWLockRelease(RelCacheInitLock);
  	}
  }
--- 3606,3651 ----
  		 * that we will execute second and successfully unlink the file.
  		 */
  		LWLockAcquire(RelCacheInitLock, LW_EXCLUSIVE);
!         unlink(initfilename);
  		LWLockRelease(RelCacheInitLock);
  	}
+
+ }
+ 
+ void
+ cache_redo(XLogRecPtr lsn, XLogRecord *record)
+ {
+ 	uint8		info = record->xl_info & ~XLR_INFO_MASK;
+ 
+     if (info == XLOG_CACHE_INIT_FILE_INVAL)
+     {
+ 		xl_cache_init_file_inval *xlrec = (xl_cache_init_file_inval *) XLogRecGetData(record);
+ 		char *dbpath = GetDatabasePath((int) &xlrec->dbOid, (int) &xlrec->dbTableSpaceOid);
+     	char initfilename[MAXPGPATH];
+ 
+     	snprintf(initfilename, sizeof(initfilename), "%s/%s",
+     			 dbpath, RELCACHE_INIT_FILENAME);
+ 
+         unlink(initfilename);
+ 		pfree(dbpath);
+     }
+ 	else
+ 		elog(PANIC, "cache_redo: unknown op code %u", info);
+ }
+ 
+ void
+ cache_desc(StringInfo buf, uint8 xl_info, char *rec)
+ {
+ 	uint8		info = xl_info & ~XLR_INFO_MASK;
+ 
+ 	if (info == XLOG_CACHE_INIT_FILE_INVAL)
+ 	{
+ 		xl_cache_init_file_inval *xlrec = (xl_cache_init_file_inval *) rec;
+ 
+ 		appendStringInfo(buf, "cache: relcache init file invalidation; ");
+ 		appendStringInfo(buf, "database %u; tablespace %u",
+                             (int) &xlrec->dbOid, (int) &xlrec->dbTableSpaceOid);
+     }
+ 	else
+ 		appendStringInfo(buf, "UNKNOWN");
  }
Index: src/include/access/rmgr.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/access/rmgr.h,v
retrieving revision 1.16
diff -c -r1.16 rmgr.h
*** src/include/access/rmgr.h	2 May 2006 11:28:55 -0000	1.16
--- src/include/access/rmgr.h	27 Oct 2006 20:36:25 -0000
***************
*** 20,25 ****
--- 20,26 ----
  #define RM_DBASE_ID				4
  #define RM_TBLSPC_ID			5
  #define RM_MULTIXACT_ID			6
+ #define RM_CACHE_ID             7
  #define RM_HEAP_ID				10
  #define RM_BTREE_ID				11
  #define RM_HASH_ID				12
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	27 Oct 2006 20:36:26 -0000
***************
*** 64,69 ****
--- 64,84 ----
  extern void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid,
  						  SubTransactionId parentSubid);
  
+ /* 
+  * xlog support for cache invalidation
+  */
+ extern void cache_redo(XLogRecPtr lsn, XLogRecord *record);
+ extern void cache_desc(StringInfo buf, uint8 xl_info, char *rec);
+ 
+ typedef struct xl_cache_init_file_inval
+ {
+     Oid         dbOid;
+     Oid         dbTableSpaceOid;
+ } xl_cache_init_file_inval;
+ 
+ #define XLOG_CACHE_INIT_FILE_INVAL  0x00
+ 
+ 
  /*
   * Routines to help manage rebuilding of relcache init file
   */
---------------------------(end of broadcast)---------------------------
TIP 5: don't forget to increase your free space map settings

Reply via email to