@@ -162,7 +162,7 @@ gistinsert(Relation r, Datum *values, bool *isnull,
162162values ,isnull , true/* size is currently bogus */ );
163163itup -> t_tid = * ht_ctid ;
164164
165- gistdoinsert (r ,itup ,0 ,giststate );
165+ gistdoinsert (r ,itup ,0 ,giststate , false );
166166
167167/* cleanup */
168168MemoryContextSwitchTo (oldCxt );
@@ -208,7 +208,8 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate,
208208BlockNumber * newblkno ,
209209Buffer leftchildbuf ,
210210List * * splitinfo ,
211- bool markfollowright )
211+ bool markfollowright ,
212+ bool is_build )
212213{
213214BlockNumber blkno = BufferGetBlockNumber (buffer );
214215Page page = 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 )
448449XLogEnsureRecordSpace (npage ,1 + npage * 2 );
449450
450451START_CRIT_SECTION ();
@@ -465,18 +466,20 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate,
465466PageRestoreTempPage (dist -> page ,BufferGetPage (dist -> buffer ));
466467dist -> 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 )
470475recptr = gistXLogSplit (is_leaf ,
471- dist ,oldrlink ,oldnsn ,leftchildbuf ,
472- markfollowright );
476+ dist ,oldrlink ,oldnsn ,leftchildbuf ,
477+ markfollowright );
473478else
474479recptr = gistGetFakeLSN (rel );
475480
476481for (ptr = dist ;ptr ;ptr = ptr -> next )
477- {
478482PageSetLSN (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,
512515if (BufferIsValid (leftchildbuf ))
513516MarkBufferDirty (leftchildbuf );
514517
515- if (RelationNeedsWAL (rel ))
518+
519+ if (RelationNeedsWAL (rel )&& !is_build )
516520{
517521OffsetNumber ndeloffs = 0 ,
518522deloffs [1 ];
@@ -535,6 +539,7 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate,
535539PageSetLSN (page ,recptr );
536540}
537541
542+
538543if (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+
555566if (BufferIsValid (leftchildbuf ))
556567{
557568Page leftpg = BufferGetPage (leftchildbuf );
569+ XLogRecPtr fakerecptr = 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 );
562577PageSetLSN (leftpg ,recptr );
563578}
564579
580+
565581END_CRIT_SECTION ();
566582
567583return is_split ;
@@ -573,7 +589,8 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate,
573589 * so it does not bother releasing palloc'd allocations.
574590 */
575591void
576- gistdoinsert (Relation r ,IndexTuple itup ,Size freespace ,GISTSTATE * giststate )
592+ gistdoinsert (Relation r ,IndexTuple itup ,Size freespace ,
593+ GISTSTATE * giststate ,bool is_build )
577594{
578595ItemId iid ;
579596IndexTuple idxtuple ;
@@ -585,6 +602,7 @@ gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate)
585602memset (& state ,0 ,sizeof (GISTInsertState ));
586603state .freespace = freespace ;
587604state .r = r ;
605+ state .is_build = is_build ;
588606
589607/* Start from the root */
590608firststack .blkno = GIST_ROOT_BLKNO ;
@@ -1194,7 +1212,7 @@ gistinserttuples(GISTInsertState *state, GISTInsertStack *stack,
11941212oldoffnum ,NULL ,
11951213leftchild ,
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