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

Commitacbffaa

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 parent0e27a73 commitacbffaa

File tree

4 files changed

+30
-10
lines changed

4 files changed

+30
-10
lines changed

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

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

26-
constXLogRecPtrXLogRecPtrForTemp= {1,1};
27-
2826
/* Working state for gistbuild and its callback */
2927
typedefstruct
3028
{
@@ -127,7 +125,7 @@ gistbuild(PG_FUNCTION_ARGS)
127125
END_CRIT_SECTION();
128126
}
129127
else
130-
PageSetLSN(BufferGetPage(buffer),XLogRecPtrForTemp);
128+
PageSetLSN(BufferGetPage(buffer),GetXLogRecPtrForTemp());
131129
LockBuffer(buffer,GIST_UNLOCK);
132130
WriteBuffer(buffer);
133131

@@ -356,7 +354,7 @@ gistplacetopage(GISTInsertState *state, GISTSTATE *giststate)
356354
ptr=dist;
357355
while (ptr)
358356
{
359-
PageSetLSN(BufferGetPage(ptr->buffer),XLogRecPtrForTemp);
357+
PageSetLSN(BufferGetPage(ptr->buffer),GetXLogRecPtrForTemp());
360358
ptr=ptr->next;
361359
}
362360
}
@@ -475,7 +473,7 @@ gistplacetopage(GISTInsertState *state, GISTSTATE *giststate)
475473
END_CRIT_SECTION();
476474
}
477475
else
478-
PageSetLSN(state->stack->page,XLogRecPtrForTemp);
476+
PageSetLSN(state->stack->page,GetXLogRecPtrForTemp());
479477

480478
if (state->stack->blkno==GIST_ROOT_BLKNO)
481479
state->needInsertComplete= false;
@@ -1206,7 +1204,7 @@ gistnewroot(Relation r, Buffer buffer, IndexTuple *itup, int len, ItemPointer ke
12061204
END_CRIT_SECTION();
12071205
}
12081206
else
1209-
PageSetLSN(page,XLogRecPtrForTemp);
1207+
PageSetLSN(page,GetXLogRecPtrForTemp());
12101208
}
12111209

12121210
void

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -977,3 +977,24 @@ gistNewBuffer(Relation r)
977977

978978
returnbuffer;
979979
}
980+
981+
/*
982+
* Temporary GiST indexes are not WAL-logged, but we need LSNs to detect
983+
* concurrent page splits anyway. GetXLogRecPtrForTemp() provides a fake
984+
* sequence of LSNs for that purpose. Each call generates an LSN that is
985+
* greater than any previous value returned by this function in the same
986+
* session.
987+
*/
988+
XLogRecPtr
989+
GetXLogRecPtrForTemp(void)
990+
{
991+
staticXLogRecPtrcounter= {0,1};
992+
993+
counter.xrecoff++;
994+
if (counter.xrecoff==0)
995+
{
996+
counter.xlogid++;
997+
counter.xrecoff++;
998+
}
999+
returncounter;
1000+
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ gistVacuumUpdate(GistVacuum *gv, BlockNumber blkno, bool needunion)
201201
ptr=dist;
202202
while (ptr)
203203
{
204-
PageSetLSN(BufferGetPage(ptr->buffer),XLogRecPtrForTemp);
204+
PageSetLSN(BufferGetPage(ptr->buffer),GetXLogRecPtrForTemp());
205205
ptr=ptr->next;
206206
}
207207
}
@@ -306,7 +306,7 @@ gistVacuumUpdate(GistVacuum *gv, BlockNumber blkno, bool needunion)
306306
pfree(rdata);
307307
}
308308
else
309-
PageSetLSN(page,XLogRecPtrForTemp);
309+
PageSetLSN(page,GetXLogRecPtrForTemp());
310310
WriteBuffer(buffer);
311311
}
312312
else
@@ -589,7 +589,7 @@ gistbulkdelete(PG_FUNCTION_ARGS)
589589
pfree(rdata);
590590
}
591591
else
592-
PageSetLSN(page,XLogRecPtrForTemp);
592+
PageSetLSN(page,GetXLogRecPtrForTemp());
593593
WriteNoReleaseBuffer(buffer);
594594
}
595595
}

‎src/include/access/gist_private.h

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

9393
/* XLog stuff */
94-
externconstXLogRecPtrXLogRecPtrForTemp;
9594

9695
#defineXLOG_GIST_ENTRY_UPDATE0x00
9796
#defineXLOG_GIST_ENTRY_DELETE0x10
@@ -318,6 +317,8 @@ extern void gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e,
318317
voidgistUserPicksplit(Relationr,GistEntryVector*entryvec,GIST_SPLITVEC*v,
319318
IndexTuple*itup,intlen,GISTSTATE*giststate);
320319

320+
externXLogRecPtrGetXLogRecPtrForTemp(void);
321+
321322
/* gistvacuum.c */
322323
externDatumgistbulkdelete(PG_FUNCTION_ARGS);
323324
externDatumgistvacuumcleanup(PG_FUNCTION_ARGS);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp