diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c index 00b1620ab00..fbc828e7832 100644 --- a/src/backend/access/gist/gist.c +++ b/src/backend/access/gist/gist.c @@ -23,8 +23,6 @@ #include "miscadmin.h" #include "utils/memutils.h" -const XLogRecPtr XLogRecPtrForTemp = {1, 1}; - /* Working state for gistbuild and its callback */ typedef struct { @@ -127,7 +125,7 @@ gistbuild(PG_FUNCTION_ARGS) END_CRIT_SECTION(); } else - PageSetLSN(BufferGetPage(buffer), XLogRecPtrForTemp); + PageSetLSN(BufferGetPage(buffer), GetXLogRecPtrForTemp()); LockBuffer(buffer, GIST_UNLOCK); WriteBuffer(buffer); @@ -356,7 +354,7 @@ gistplacetopage(GISTInsertState *state, GISTSTATE *giststate) ptr = dist; while (ptr) { - PageSetLSN(BufferGetPage(ptr->buffer), XLogRecPtrForTemp); + PageSetLSN(BufferGetPage(ptr->buffer), GetXLogRecPtrForTemp()); ptr = ptr->next; } } @@ -475,7 +473,7 @@ gistplacetopage(GISTInsertState *state, GISTSTATE *giststate) END_CRIT_SECTION(); } else - PageSetLSN(state->stack->page, XLogRecPtrForTemp); + PageSetLSN(state->stack->page, GetXLogRecPtrForTemp()); if (state->stack->blkno == GIST_ROOT_BLKNO) state->needInsertComplete = false; @@ -1206,7 +1204,7 @@ gistnewroot(Relation r, Buffer buffer, IndexTuple *itup, int len, ItemPointer ke END_CRIT_SECTION(); } else - PageSetLSN(page, XLogRecPtrForTemp); + PageSetLSN(page, GetXLogRecPtrForTemp()); } void diff --git a/src/backend/access/gist/gistutil.c b/src/backend/access/gist/gistutil.c index c0d904c35a4..9f43b4520c9 100644 --- a/src/backend/access/gist/gistutil.c +++ b/src/backend/access/gist/gistutil.c @@ -977,3 +977,24 @@ gistNewBuffer(Relation r) return buffer; } + +/* + * Temporary GiST indexes are not WAL-logged, but we need LSNs to detect + * concurrent page splits anyway. GetXLogRecPtrForTemp() provides a fake + * sequence of LSNs for that purpose. Each call generates an LSN that is + * greater than any previous value returned by this function in the same + * session. + */ +XLogRecPtr +GetXLogRecPtrForTemp(void) +{ + static XLogRecPtr counter = {0, 1}; + + counter.xrecoff++; + if (counter.xrecoff == 0) + { + counter.xlogid++; + counter.xrecoff++; + } + return counter; +} diff --git a/src/backend/access/gist/gistvacuum.c b/src/backend/access/gist/gistvacuum.c index 9d02ea7b46f..fa545f74683 100644 --- a/src/backend/access/gist/gistvacuum.c +++ b/src/backend/access/gist/gistvacuum.c @@ -201,7 +201,7 @@ gistVacuumUpdate(GistVacuum *gv, BlockNumber blkno, bool needunion) ptr = dist; while (ptr) { - PageSetLSN(BufferGetPage(ptr->buffer), XLogRecPtrForTemp); + PageSetLSN(BufferGetPage(ptr->buffer), GetXLogRecPtrForTemp()); ptr = ptr->next; } } @@ -306,7 +306,7 @@ gistVacuumUpdate(GistVacuum *gv, BlockNumber blkno, bool needunion) pfree(rdata); } else - PageSetLSN(page, XLogRecPtrForTemp); + PageSetLSN(page, GetXLogRecPtrForTemp()); WriteBuffer(buffer); } else @@ -589,7 +589,7 @@ gistbulkdelete(PG_FUNCTION_ARGS) pfree(rdata); } else - PageSetLSN(page, XLogRecPtrForTemp); + PageSetLSN(page, GetXLogRecPtrForTemp()); WriteNoReleaseBuffer(buffer); } } diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h index 1668f80a9c9..18c766c7891 100644 --- a/src/include/access/gist_private.h +++ b/src/include/access/gist_private.h @@ -91,7 +91,6 @@ typedef struct GISTScanOpaqueData typedef GISTScanOpaqueData *GISTScanOpaque; /* XLog stuff */ -extern const XLogRecPtr XLogRecPtrForTemp; #define XLOG_GIST_ENTRY_UPDATE 0x00 #define XLOG_GIST_ENTRY_DELETE 0x10 @@ -318,6 +317,8 @@ extern void gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e, void gistUserPicksplit(Relation r, GistEntryVector *entryvec, GIST_SPLITVEC *v, IndexTuple *itup, int len, GISTSTATE *giststate); +extern XLogRecPtr GetXLogRecPtrForTemp(void); + /* gistvacuum.c */ extern Datum gistbulkdelete(PG_FUNCTION_ARGS); extern Datum gistvacuumcleanup(PG_FUNCTION_ARGS);