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

Commit0a59976

Browse files
committed
Apply CORE-367-WAL patch
1 parent884a5d3 commit0a59976

File tree

17 files changed

+126
-91
lines changed

17 files changed

+126
-91
lines changed

‎src/backend/access/brin/brin_pageops.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,7 @@ brin_metapage_init(Page page, BlockNumber pagesPerRange, uint16 version)
497497
* revmap page to be created when the index is.
498498
*/
499499
metadata->lastRevmapPage=0;
500+
((PageHeader)page)->pd_lower+=sizeof(BrinMetaPageData);
500501
}
501502

502503
/*

‎src/backend/access/gin/ginbtree.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ ginPlaceToPage(GinBtree btree, GinBtreeStack *stack,
387387
/* It will fit, perform the insertion */
388388
START_CRIT_SECTION();
389389

390-
if (RelationNeedsWAL(btree->index))
390+
if (RelationNeedsWAL(btree->index)&& !btree->isBuild)
391391
{
392392
XLogBeginInsert();
393393
XLogRegisterBuffer(0,stack->buffer,REGBUF_STANDARD);
@@ -408,7 +408,7 @@ ginPlaceToPage(GinBtree btree, GinBtreeStack *stack,
408408
MarkBufferDirty(childbuf);
409409
}
410410

411-
if (RelationNeedsWAL(btree->index))
411+
if (RelationNeedsWAL(btree->index)&& !btree->isBuild)
412412
{
413413
XLogRecPtrrecptr;
414414
ginxlogInsertxlrec;
@@ -565,7 +565,7 @@ ginPlaceToPage(GinBtree btree, GinBtreeStack *stack,
565565
}
566566

567567
/* write WAL record */
568-
if (RelationNeedsWAL(btree->index))
568+
if (RelationNeedsWAL(btree->index)&& !btree->isBuild)
569569
{
570570
XLogRecPtrrecptr;
571571

‎src/backend/access/gin/gindatapage.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ dataBeginPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack,
591591
* Great, all the items fit on a single page. If needed, prepare data
592592
* for a WAL record describing the changes we'll make.
593593
*/
594-
if (RelationNeedsWAL(btree->index))
594+
if (RelationNeedsWAL(btree->index)&& !btree->isBuild)
595595
computeLeafRecompressWALData(leaf);
596596

597597
/*
@@ -628,6 +628,7 @@ dataBeginPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack,
628628
* subsequent insertions will probably also go to the end. This packs
629629
* the index somewhat tighter when appending to a table, which is very
630630
* common.
631+
*
631632
*/
632633
if (!btree->isBuild)
633634
{
@@ -717,7 +718,7 @@ dataExecPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack,
717718
dataPlaceToPageLeafRecompress(buf,leaf);
718719

719720
/* If needed, register WAL data built by computeLeafRecompressWALData */
720-
if (RelationNeedsWAL(btree->index))
721+
if (RelationNeedsWAL(btree->index)&& !btree->isBuild)
721722
{
722723
XLogRegisterBufData(0,leaf->walinfo,leaf->walinfolen);
723724
}
@@ -1150,7 +1151,7 @@ dataExecPlaceToPageInternal(GinBtree btree, Buffer buf, GinBtreeStack *stack,
11501151
pitem= (PostingItem*)insertdata;
11511152
GinDataPageAddPostingItem(page,pitem,off);
11521153

1153-
if (RelationNeedsWAL(btree->index))
1154+
if (RelationNeedsWAL(btree->index)&& !btree->isBuild)
11541155
{
11551156
/*
11561157
* This must be static, because it has to survive until XLogInsert,
@@ -1767,6 +1768,7 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
17671768
Pointerptr;
17681769
intnrootitems;
17691770
introotsize;
1771+
boolis_build= (buildStats!=NULL);
17701772

17711773
/* Construct the new root page in memory first. */
17721774
tmppage= (Page)palloc(BLCKSZ);
@@ -1814,7 +1816,7 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
18141816
PageRestoreTempPage(tmppage,page);
18151817
MarkBufferDirty(buffer);
18161818

1817-
if (RelationNeedsWAL(index))
1819+
if (RelationNeedsWAL(index)&& !is_build)
18181820
{
18191821
XLogRecPtrrecptr;
18201822
ginxlogCreatePostingTreedata;

‎src/backend/access/gin/ginentrypage.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ entryExecPlaceToPage(GinBtree btree, Buffer buf, GinBtreeStack *stack,
570570
elog(ERROR,"failed to add item to index page in \"%s\"",
571571
RelationGetRelationName(btree->index));
572572

573-
if (RelationNeedsWAL(btree->index))
573+
if (RelationNeedsWAL(btree->index)&& !btree->isBuild)
574574
{
575575
/*
576576
* This must be static, because it has to survive until XLogInsert,

‎src/backend/access/gin/gininsert.c

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include"access/gin_private.h"
1818
#include"access/xloginsert.h"
19+
#include"access/generic_xlog.h"
1920
#include"catalog/index.h"
2021
#include"miscadmin.h"
2122
#include"storage/bufmgr.h"
@@ -191,6 +192,7 @@ ginEntryInsert(GinState *ginstate,
191192
buildStats->nEntries++;
192193

193194
ginPrepareEntryScan(&btree,attnum,key,category,ginstate);
195+
btree.isBuild= (buildStats!=NULL);
194196

195197
stack=ginFindLeafPage(&btree, false,NULL);
196198
page=BufferGetPage(stack->buffer);
@@ -341,24 +343,6 @@ ginbuild(Relation heap, Relation index, IndexInfo *indexInfo)
341343
GinInitBuffer(RootBuffer,GIN_LEAF);
342344
MarkBufferDirty(RootBuffer);
343345

344-
if (RelationNeedsWAL(index))
345-
{
346-
XLogRecPtrrecptr;
347-
Pagepage;
348-
349-
XLogBeginInsert();
350-
XLogRegisterBuffer(0,MetaBuffer,REGBUF_WILL_INIT);
351-
XLogRegisterBuffer(1,RootBuffer,REGBUF_WILL_INIT);
352-
353-
recptr=XLogInsert(RM_GIN_ID,XLOG_GIN_CREATE_INDEX);
354-
355-
page=BufferGetPage(RootBuffer);
356-
PageSetLSN(page,recptr);
357-
358-
page=BufferGetPage(MetaBuffer);
359-
PageSetLSN(page,recptr);
360-
}
361-
362346
UnlockReleaseBuffer(MetaBuffer);
363347
UnlockReleaseBuffer(RootBuffer);
364348
END_CRIT_SECTION();
@@ -412,7 +396,10 @@ ginbuild(Relation heap, Relation index, IndexInfo *indexInfo)
412396
* Update metapage stats
413397
*/
414398
buildstate.buildStats.nTotalPages=RelationGetNumberOfBlocks(index);
415-
ginUpdateStats(index,&buildstate.buildStats);
399+
ginUpdateStats(index,&buildstate.buildStats, true);
400+
401+
if (RelationNeedsWAL(index))
402+
generate_xlog_for_rel(index);
416403

417404
/*
418405
* Return statistics

‎src/backend/access/gin/ginutil.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,8 @@ GinInitMetabuffer(Buffer b)
342342
metadata->nDataPages=0;
343343
metadata->nEntries=0;
344344
metadata->ginVersion=GIN_CURRENT_VERSION;
345+
346+
((PageHeader)page)->pd_lower+=sizeof(GinMetaPageData);
345347
}
346348

347349
/*
@@ -626,7 +628,7 @@ ginGetStats(Relation index, GinStatsData *stats)
626628
* Note: nPendingPages and ginVersion are *not* copied over
627629
*/
628630
void
629-
ginUpdateStats(Relationindex,constGinStatsData*stats)
631+
ginUpdateStats(Relationindex,constGinStatsData*stats,boolis_build)
630632
{
631633
Buffermetabuffer;
632634
Pagemetapage;
@@ -646,7 +648,7 @@ ginUpdateStats(Relation index, const GinStatsData *stats)
646648

647649
MarkBufferDirty(metabuffer);
648650

649-
if (RelationNeedsWAL(index))
651+
if (RelationNeedsWAL(index)&& !is_build)
650652
{
651653
XLogRecPtrrecptr;
652654
ginxlogUpdateMetadata;

‎src/backend/access/gin/ginvacuum.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,7 @@ ginvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
731731

732732
/* Update the metapage with accurate page and entry counts */
733733
idxStat.nTotalPages=npages;
734-
ginUpdateStats(info->index,&idxStat);
734+
ginUpdateStats(info->index,&idxStat, false);
735735

736736
/* Finally, vacuum the FSM */
737737
IndexFreeSpaceMapVacuum(info->index);

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

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ gistinsert(Relation r, Datum *values, bool *isnull,
162162
values,isnull, true/* size is currently bogus */ );
163163
itup->t_tid=*ht_ctid;
164164

165-
gistdoinsert(r,itup,0,giststate);
165+
gistdoinsert(r,itup,0,giststate, false);
166166

167167
/* cleanup */
168168
MemoryContextSwitchTo(oldCxt);
@@ -208,7 +208,8 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate,
208208
BlockNumber*newblkno,
209209
Bufferleftchildbuf,
210210
List**splitinfo,
211-
boolmarkfollowright)
211+
boolmarkfollowright,
212+
boolis_build)
212213
{
213214
BlockNumberblkno=BufferGetBlockNumber(buffer);
214215
Pagepage=BufferGetPage(buffer);
@@ -444,7 +445,7 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate,
444445
* insertion for that. NB: The number of pages and data segments
445446
* specified here must match the calculations in gistXLogSplit()!
446447
*/
447-
if (RelationNeedsWAL(rel))
448+
if (RelationNeedsWAL(rel)&& !is_build)
448449
XLogEnsureRecordSpace(npage,1+npage*2);
449450

450451
START_CRIT_SECTION();
@@ -465,18 +466,20 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate,
465466
PageRestoreTempPage(dist->page,BufferGetPage(dist->buffer));
466467
dist->page=BufferGetPage(dist->buffer);
467468

468-
/* Write the WAL record */
469-
if (RelationNeedsWAL(rel))
469+
/*
470+
* Write the WAL record.
471+
* Do not write XLog entry if the insertion is caused by
472+
* index build process.
473+
*/
474+
if (RelationNeedsWAL(rel)&& !is_build)
470475
recptr=gistXLogSplit(is_leaf,
471-
dist,oldrlink,oldnsn,leftchildbuf,
472-
markfollowright);
476+
dist,oldrlink,oldnsn,leftchildbuf,
477+
markfollowright);
473478
else
474479
recptr=gistGetFakeLSN(rel);
475480

476481
for (ptr=dist;ptr;ptr=ptr->next)
477-
{
478482
PageSetLSN(ptr->page,recptr);
479-
}
480483

481484
/*
482485
* Return the new child buffers to the caller.
@@ -512,7 +515,8 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate,
512515
if (BufferIsValid(leftchildbuf))
513516
MarkBufferDirty(leftchildbuf);
514517

515-
if (RelationNeedsWAL(rel))
518+
519+
if (RelationNeedsWAL(rel)&& !is_build)
516520
{
517521
OffsetNumberndeloffs=0,
518522
deloffs[1];
@@ -535,6 +539,7 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate,
535539
PageSetLSN(page,recptr);
536540
}
537541

542+
538543
if (newblkno)
539544
*newblkno=blkno;
540545
}
@@ -551,17 +556,28 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate,
551556
* the full page image. There's a chicken-and-egg problem: if we updated
552557
* the child pages first, we wouldn't know the recptr of the WAL record
553558
* we're about to write.
559+
*
560+
* We use fakeLSNs for inserions caused by index build. And when it is
561+
* finished, we write generic_xlog entry for each index page and update
562+
* all LSNs. In order to keep NSNs less then LSNs after this update, we
563+
* set NSN to InvalidXLogRecPtr, which is the smallest possible NSN.
554564
*/
565+
555566
if (BufferIsValid(leftchildbuf))
556567
{
557568
Pageleftpg=BufferGetPage(leftchildbuf);
569+
XLogRecPtrfakerecptr=InvalidXLogRecPtr;
558570

559-
GistPageSetNSN(leftpg,recptr);
560-
GistClearFollowRight(leftpg);
571+
if (!is_build)
572+
GistPageSetNSN(leftpg,recptr);
573+
else
574+
GistPageSetNSN(leftpg,fakerecptr);
561575

576+
GistClearFollowRight(leftpg);
562577
PageSetLSN(leftpg,recptr);
563578
}
564579

580+
565581
END_CRIT_SECTION();
566582

567583
returnis_split;
@@ -573,7 +589,8 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate,
573589
* so it does not bother releasing palloc'd allocations.
574590
*/
575591
void
576-
gistdoinsert(Relationr,IndexTupleitup,Sizefreespace,GISTSTATE*giststate)
592+
gistdoinsert(Relationr,IndexTupleitup,Sizefreespace,
593+
GISTSTATE*giststate,boolis_build)
577594
{
578595
ItemIdiid;
579596
IndexTupleidxtuple;
@@ -585,6 +602,7 @@ gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate)
585602
memset(&state,0,sizeof(GISTInsertState));
586603
state.freespace=freespace;
587604
state.r=r;
605+
state.is_build=is_build;
588606

589607
/* Start from the root */
590608
firststack.blkno=GIST_ROOT_BLKNO;
@@ -1194,7 +1212,7 @@ gistinserttuples(GISTInsertState *state, GISTInsertStack *stack,
11941212
oldoffnum,NULL,
11951213
leftchild,
11961214
&splitinfo,
1197-
true);
1215+
true,state->is_build);
11981216

11991217
/*
12001218
* Before recursing up in case the page was split, release locks on the

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

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include"access/genam.h"
2020
#include"access/gist_private.h"
2121
#include"access/xloginsert.h"
22+
#include"access/generic_xlog.h"
2223
#include"catalog/index.h"
2324
#include"miscadmin.h"
2425
#include"optimizer/cost.h"
@@ -177,18 +178,12 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo)
177178

178179
MarkBufferDirty(buffer);
179180

180-
if (RelationNeedsWAL(index))
181-
{
182-
XLogRecPtrrecptr;
183-
184-
XLogBeginInsert();
185-
XLogRegisterBuffer(0,buffer,REGBUF_WILL_INIT);
186-
187-
recptr=XLogInsert(RM_GIST_ID,XLOG_GIST_CREATE_INDEX);
188-
PageSetLSN(page,recptr);
189-
}
190-
else
191-
PageSetLSN(page,gistGetFakeLSN(heap));
181+
/*
182+
* Do not write index pages to WAL unitl index build is finished.
183+
* But we still need increasing LSNs on each page, so use FakeLSN,
184+
* even for relations which eventually need WAL.
185+
*/
186+
PageSetLSN(page,gistGetFakeLSN(heap));
192187

193188
UnlockReleaseBuffer(buffer);
194189

@@ -221,6 +216,15 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo)
221216

222217
freeGISTstate(buildstate.giststate);
223218

219+
/*
220+
* Create generic wal records for all pages of relation, if necessary.
221+
* It seems reasonable not to generate WAL, if we recieved interrupt
222+
* signal.
223+
*/
224+
CHECK_FOR_INTERRUPTS();
225+
if (RelationNeedsWAL(index))
226+
generate_xlog_for_rel(index);
227+
224228
/*
225229
* Return statistics
226230
*/
@@ -483,7 +487,7 @@ gistBuildCallback(Relation index,
483487
* locked, we call gistdoinsert directly.
484488
*/
485489
gistdoinsert(index,itup,buildstate->freespace,
486-
buildstate->giststate);
490+
buildstate->giststate, true);
487491
}
488492

489493
/* Update tuple count and total size. */
@@ -689,7 +693,7 @@ gistbufferinginserttuples(GISTBuildState *buildstate, Buffer buffer, int level,
689693
itup,ntup,oldoffnum,&placed_to_blk,
690694
InvalidBuffer,
691695
&splitinfo,
692-
false);
696+
false, true);
693697

694698
/*
695699
* If this is a root split, update the root path item kept in memory. This

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,7 @@ gistproperty(Oid index_oid, int attno,
914914
* Temporary and unlogged GiST indexes are not WAL-logged, but we need LSNs
915915
* to detect concurrent page splits anyway. This function provides a fake
916916
* sequence of LSNs for that purpose.
917+
* Persistent relations are also not WAL-logged while we build index.
917918
*/
918919
XLogRecPtr
919920
gistGetFakeLSN(Relationrel)
@@ -934,7 +935,6 @@ gistGetFakeLSN(Relation rel)
934935
* Unlogged relations are accessible from other backends, and survive
935936
* (clean) restarts. GetFakeLSNForUnloggedRel() handles that for us.
936937
*/
937-
Assert(rel->rd_rel->relpersistence==RELPERSISTENCE_UNLOGGED);
938938
returnGetFakeLSNForUnloggedRel();
939939
}
940940
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp