]> 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 21:05:21 +0000 (00:05 +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 78213dcb4ef24b581c67b82910061dc36b2be509..ca49d795a012303b3a49116e293a96411042e795 100644 (file)
@@ -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;
 }
 
index 54d6890912566131f21af883aad06459a82d3e8a..23751d538018557025cf95262832cca4621ae991 100644 (file)
@@ -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;
 }
 
index f36f1a824231d4ebe514af5b5374cbc8336f19c3..120e75a71f25f7e42b78cc9e1e0a07fce6da7c7f 100644 (file)
@@ -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);
index f3c82ac836cdbcaf6d53376041c8783f4fe15979..55e0c442cbb5af4d31610b91c4e710948bde92ea 100644 (file)
@@ -530,7 +530,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.