commit 53938b423ec19a88e470b7b9552de13de5e2634a
Author: Anastasia <a.lubennikova@postgrespro.ru>
Date:   Tue Apr 9 18:58:00 2019 +0300

    fix for gist create index WAL optimization. Track splits correctly

diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c
index 2db790c..ff98d13 100644
--- a/src/backend/access/gist/gist.c
+++ b/src/backend/access/gist/gist.c
@@ -639,6 +639,7 @@ gistdoinsert(Relation r, IndexTuple itup, Size freespace,
 	/* Start from the root */
 	firststack.blkno = GIST_ROOT_BLKNO;
 	firststack.lsn = 0;
+	firststack.retry_from_parent = false;
 	firststack.parent = NULL;
 	firststack.downlinkoffnum = InvalidOffsetNumber;
 	state.stack = stack = &firststack;
@@ -693,8 +694,15 @@ gistdoinsert(Relation r, IndexTuple itup, Size freespace,
 			continue;
 		}
 
+		/*
+		 * During gistbuild we cannot rely on lsn-nsn comparison,
+		 * since all pages have the same GistBuildLSN value in these fields.
+		 * So use special flag stack->retry_from_parent to detect the fact that
+		 * we need to go back to parent and rechoose the child.
+		 */
 		if (stack->blkno != GIST_ROOT_BLKNO &&
-			stack->parent->lsn < GistPageGetNSN(stack->page))
+			((stack->parent->lsn < GistPageGetNSN(stack->page)) ||
+			 stack->retry_from_parent == true))
 		{
 			/*
 			 * Concurrent split detected. There's no guarantee that the
@@ -786,6 +794,7 @@ gistdoinsert(Relation r, IndexTuple itup, Size freespace,
 						UnlockReleaseBuffer(stack->buffer);
 						xlocked = false;
 						state.stack = stack = stack->parent;
+						stack->retry_from_parent = true;
 					}
 					continue;
 				}
diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h
index 78e2e3f..361a7a8 100644
--- a/src/include/access/gist_private.h
+++ b/src/include/access/gist_private.h
@@ -215,6 +215,12 @@ typedef struct GISTInsertStack
 	 */
 	GistNSN		lsn;
 
+	/*
+	 * flag to use during gistbuild to recognize page split
+	 * (instead of lsn-nsn comparison)
+	 */
+	bool retry_from_parent;
+
 	/* offset of the downlink in the parent page, that points to this page */
 	OffsetNumber downlinkoffnum;
 
