commit 7709e22db542c7a453b766180003234a4931f8da
Author: Alexander Korotkov <akorotkov@postgresql.org>
Date:   Thu Oct 3 23:49:16 2019 +0300

    Fix traversing to the deleted page from downlink
    
    Reported-by:
    Bug:
    Discussion:
    Author:
    Reviewed-by:
    Tested-by:
    Backpatch-through:

diff --git a/src/backend/access/gin/ginbtree.c b/src/backend/access/gin/ginbtree.c
index 4c29261256a..b18056cf894 100644
--- a/src/backend/access/gin/ginbtree.c
+++ b/src/backend/access/gin/ginbtree.c
@@ -187,13 +187,6 @@ ginStepRight(Buffer buffer, Relation index, int lockmode)
 	if (isLeaf != GinPageIsLeaf(page) || isData != GinPageIsData(page))
 		elog(ERROR, "right sibling of GIN page is of different type");
 
-	/*
-	 * Given the proper lock sequence above, we should never land on a deleted
-	 * page.
-	 */
-	if (GinPageIsDeleted(page))
-		elog(ERROR, "right sibling of GIN page was deleted");
-
 	return nextbuffer;
 }
 
diff --git a/src/backend/access/gin/gindatapage.c b/src/backend/access/gin/gindatapage.c
index e8c34d6b1f6..e497210b4c0 100644
--- a/src/backend/access/gin/gindatapage.c
+++ b/src/backend/access/gin/gindatapage.c
@@ -238,6 +238,9 @@ dataIsMoveRight(GinBtree btree, Page page)
 	if (GinPageRightMost(page))
 		return false;
 
+	if (GinPageIsDeleted(page))
+		return true;
+
 	return (ginCompareItemPointers(&btree->itemptr, iptr) > 0) ? true : false;
 }
 
diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c
index 72169bb0bdc..11e050171ad 100644
--- a/src/backend/access/gin/ginvacuum.c
+++ b/src/backend/access/gin/ginvacuum.c
@@ -186,7 +186,7 @@ ginDeletePage(GinVacuumState *gvs, BlockNumber deleteBlkno, BlockNumber leftBlkn
 	 * we shouldn't change rightlink field to save workability of running
 	 * search scan
 	 */
-	GinPageGetOpaque(page)->flags = GIN_DELETED;
+	GinPageSetDeleted(page);
 
 	MarkBufferDirty(pBuffer);
 	MarkBufferDirty(lBuffer);
diff --git a/src/backend/access/gin/ginxlog.c b/src/backend/access/gin/ginxlog.c
index c945b282721..387102f21a1 100644
--- a/src/backend/access/gin/ginxlog.c
+++ b/src/backend/access/gin/ginxlog.c
@@ -500,7 +500,7 @@ ginRedoDeletePage(XLogReaderState *record)
 	{
 		page = BufferGetPage(dbuffer);
 		Assert(GinPageIsData(page));
-		GinPageGetOpaque(page)->flags = GIN_DELETED;
+		GinPageSetDeleted(page);
 		GinPageSetDeleteXid(page, data->deleteXid);
 		PageSetLSN(page, lsn);
 		MarkBufferDirty(dbuffer);
