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