From 62401db45c4feff9be296fa78a8bb7b9947d69de Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Mon, 11 Feb 2013 22:50:15 +0200 Subject: Support unlogged GiST index. The reason this wasn't supported before was that GiST indexes need an increasing sequence to detect concurrent page-splits. In a regular WAL- logged GiST index, the LSN of the page-split record is used for that purpose, and in a temporary index, we can get away with a backend-local counter. Neither of those methods works for an unlogged relation. To provide such an increasing sequence of numbers, create a "fake LSN" counter that is saved and restored across shutdowns. On recovery, unlogged relations are blown away, so the counter doesn't need to survive that either. Jeevan Chalke, based on discussions with Robert Haas, Tom Lane and me. --- src/backend/access/gist/gist.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'src/backend/access/gist/gist.c') diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c index e2d3390300e..eba95f18664 100644 --- a/src/backend/access/gist/gist.c +++ b/src/backend/access/gist/gist.c @@ -16,6 +16,7 @@ #include "access/genam.h" #include "access/gist_private.h" +#include "access/heapam_xlog.h" #include "catalog/index.h" #include "catalog/pg_collation.h" #include "miscadmin.h" @@ -71,9 +72,22 @@ createTempGistContext(void) Datum gistbuildempty(PG_FUNCTION_ARGS) { - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("unlogged GiST indexes are not supported"))); + Relation index = (Relation) PG_GETARG_POINTER(0); + Buffer buffer; + + /* Initialize the root page */ + buffer = ReadBufferExtended(index, INIT_FORKNUM, P_NEW, RBM_NORMAL, NULL); + LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); + + /* Initialize and xlog buffer */ + START_CRIT_SECTION(); + GISTInitBuffer(buffer, F_LEAF); + MarkBufferDirty(buffer); + log_newpage_buffer(buffer); + END_CRIT_SECTION(); + + /* Unlock and release the buffer */ + UnlockReleaseBuffer(buffer); PG_RETURN_VOID(); } @@ -391,7 +405,7 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate, dist, oldrlink, oldnsn, leftchildbuf, markfollowright); else - recptr = GetXLogRecPtrForTemp(); + recptr = gistGetFakeLSN(rel); for (ptr = dist; ptr; ptr = ptr->next) { @@ -448,7 +462,7 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate, } else { - recptr = GetXLogRecPtrForTemp(); + recptr = gistGetFakeLSN(rel); PageSetLSN(page, recptr); } -- cgit v1.2.3