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 - 1.24
--- src/backend/access/transam/rmgr.c 27 Oct 2006 20:36:09 -
***
*** 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 - 1.252
--- src/backend/access/transam/xlog.c 27 Oct 2006 20:36:19 -
***
*** 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 - 1.249
--- src/backend/utils/cache/relcache.c 27 Oct 2006 20:36:24 -
***
*** 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;
+