Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2edc5cd

Browse files
committed
The GiST scan algorithm uses LSNs to detect concurrent pages splits, but
temporary indexes are not WAL-logged. We used a constant LSN for temporaryindexes, on the assumption that we don't need to worry about concurrent pagesplits in temporary indexes because they're only visible to the currentsession. But that assumption is wrong, it's possible to insert rows andsplit pages in the same session, while a scan is in progress. For example,by opening a cursor and fetching some rows, and INSERTing new rows beforefetching some more.Fix by generating fake increasing LSNs, used in place of real LSNs intemporary GiST indexes.
1 parentadd0ea8 commit2edc5cd

File tree

4 files changed

+28
-8
lines changed

4 files changed

+28
-8
lines changed

‎src/backend/access/gist/gist.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222
#include"storage/indexfsm.h"
2323
#include"utils/memutils.h"
2424

25-
constXLogRecPtrXLogRecPtrForTemp= {1,1};
26-
2725
/* Working state for gistbuild and its callback */
2826
typedefstruct
2927
{
@@ -132,7 +130,7 @@ gistbuild(PG_FUNCTION_ARGS)
132130
PageSetTLI(page,ThisTimeLineID);
133131
}
134132
else
135-
PageSetLSN(page,XLogRecPtrForTemp);
133+
PageSetLSN(page,GetXLogRecPtrForTemp());
136134

137135
UnlockReleaseBuffer(buffer);
138136

@@ -423,7 +421,7 @@ gistplacetopage(GISTInsertState *state, GISTSTATE *giststate)
423421
{
424422
for (ptr=dist;ptr;ptr=ptr->next)
425423
{
426-
PageSetLSN(ptr->page,XLogRecPtrForTemp);
424+
PageSetLSN(ptr->page,GetXLogRecPtrForTemp());
427425
}
428426
}
429427

@@ -491,7 +489,7 @@ gistplacetopage(GISTInsertState *state, GISTSTATE *giststate)
491489
PageSetTLI(state->stack->page,ThisTimeLineID);
492490
}
493491
else
494-
PageSetLSN(state->stack->page,XLogRecPtrForTemp);
492+
PageSetLSN(state->stack->page,GetXLogRecPtrForTemp());
495493

496494
if (state->stack->blkno==GIST_ROOT_BLKNO)
497495
state->needInsertComplete= false;
@@ -1027,7 +1025,7 @@ gistnewroot(Relation r, Buffer buffer, IndexTuple *itup, int len, ItemPointer ke
10271025
PageSetTLI(page,ThisTimeLineID);
10281026
}
10291027
else
1030-
PageSetLSN(page,XLogRecPtrForTemp);
1028+
PageSetLSN(page,GetXLogRecPtrForTemp());
10311029

10321030
END_CRIT_SECTION();
10331031
}

‎src/backend/access/gist/gistutil.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,3 +677,24 @@ gistoptions(PG_FUNCTION_ARGS)
677677
PG_RETURN_BYTEA_P(result);
678678
PG_RETURN_NULL();
679679
}
680+
681+
/*
682+
* Temporary GiST indexes are not WAL-logged, but we need LSNs to detect
683+
* concurrent page splits anyway. GetXLogRecPtrForTemp() provides a fake
684+
* sequence of LSNs for that purpose. Each call generates an LSN that is
685+
* greater than any previous value returned by this function in the same
686+
* session.
687+
*/
688+
XLogRecPtr
689+
GetXLogRecPtrForTemp(void)
690+
{
691+
staticXLogRecPtrcounter= {0,1};
692+
693+
counter.xrecoff++;
694+
if (counter.xrecoff==0)
695+
{
696+
counter.xlogid++;
697+
counter.xrecoff++;
698+
}
699+
returncounter;
700+
}

‎src/backend/access/gist/gistvacuum.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ gistbulkdelete(PG_FUNCTION_ARGS)
268268
pfree(rdata);
269269
}
270270
else
271-
PageSetLSN(page,XLogRecPtrForTemp);
271+
PageSetLSN(page,GetXLogRecPtrForTemp());
272272

273273
END_CRIT_SECTION();
274274
}

‎src/include/access/gist_private.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ typedef struct GISTScanOpaqueData
8787
typedefGISTScanOpaqueData*GISTScanOpaque;
8888

8989
/* XLog stuff */
90-
externconstXLogRecPtrXLogRecPtrForTemp;
9190

9291
#defineXLOG_GIST_PAGE_UPDATE0x00
9392
#defineXLOG_GIST_NEW_ROOT0x20
@@ -326,6 +325,8 @@ extern void gistMakeUnionKey(GISTSTATE *giststate, int attno,
326325
GISTENTRY*entry2,boolisnull2,
327326
Datum*dst,bool*dstisnull);
328327

328+
externXLogRecPtrGetXLogRecPtrForTemp(void);
329+
329330
/* gistvacuum.c */
330331
externDatumgistbulkdelete(PG_FUNCTION_ARGS);
331332
externDatumgistvacuumcleanup(PG_FUNCTION_ARGS);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp