]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix traversing to the deleted GIN page via downlink
authorAlexander Korotkov <akorotkov@postgresql.org>
Tue, 19 Nov 2019 20:08:14 +0000 (23:08 +0300)
committerAlexander Korotkov <akorotkov@postgresql.org>
Tue, 19 Nov 2019 20:47:29 +0000 (23:47 +0300)
Current GIN code appears to don't handle traversing to the deleted page via
downlink.  This commit fixes that by stepping right from the delete page like
we do in nbtree.

This commit also fixes setting 'deleted' flag to the GIN pages.  Now other page
flags are not erased once page is deleted.  That helps to keep our assertions
true if we arrive deleted page via downlink.

Discussion: https://postgr.es/m/CAPpHfdvMvsw-NcE5bRS7R1BbvA4BxoDnVVjkXC5W0Czvy9LVrg%40mail.gmail.com
Author: Alexander Korotkov
Reviewed-by: Peter Geoghegan
Backpatch-through: 9.4

src/backend/access/gin/ginbtree.c
src/backend/access/gin/gindatapage.c
src/backend/access/gin/ginvacuum.c
src/backend/access/gin/ginxlog.c

index a0afec4f3c0bb826f7587abbee98a3707a6ece4d..f5c41bac5c59cb893f39c6dba8fc8c5158f887d6 100644 (file)
@@ -178,13 +178,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;
 }
 
index cd3b9dfb784b084dd27a37146a4909fa1109ee81..87cbd08189c95822b9c3b5d980e35b73bbe37af7 100644 (file)
@@ -236,6 +236,9 @@ dataIsMoveRight(GinBtree btree, Page page)
        if (GinPageRightMost(page))
                return FALSE;
 
+       if (GinPageIsDeleted(page))
+               return TRUE;
+
        return (ginCompareItemPointers(&btree->itemptr, iptr) > 0) ? TRUE : FALSE;
 }
 
index 58f0d03fd1e88b9f15acd5fa0a1adf2fde7d5e96..0722a0cbbac1cdb13f030d2e1a7f7c213885cc57 100644 (file)
@@ -239,7 +239,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);
index 3b503d52caa0f16fd3440b1581d4367424a0e22b..2356a1643d57218bf10c0096f8ddd9f85698a204 100644 (file)
@@ -528,7 +528,7 @@ ginRedoDeletePage(XLogReaderState *record)
        {
                page = BufferGetPage(dbuffer);
                Assert(GinPageIsData(page));
-               GinPageGetOpaque(page)->flags = GIN_DELETED;
+               GinPageSetDeleted(page);
 
                /*
                 * deleteXid field of ginxlogDeletePage was added during backpatching.