Fix page modification outside of critical section in GIN
authorAlexander Korotkov
Tue, 19 Nov 2019 21:12:33 +0000 (00:12 +0300)
committerAlexander Korotkov
Tue, 19 Nov 2019 21:18:02 +0000 (00:18 +0300)
By oversight 52ac6cd2d0 makes ginDeletePage() sets pd_prune_xid of page to be
deleted before entering the critical section.  It appears that only versions 11
and later were affected by this oversight.

Backpatch-through: 11

src/backend/access/gin/ginvacuum.c

index 120e75a71f25f7e42b78cc9e1e0a07fce6da7c7f..5a2a9038cbddb20d646b42daa96124e9f69ee483 100644 (file)
@@ -153,9 +153,6 @@ ginDeletePage(GinVacuumState *gvs, BlockNumber deleteBlkno, BlockNumber leftBlkn
    page = BufferGetPage(dBuffer);
    rightlink = GinPageGetOpaque(page)->rightlink;
 
-   /* For deleted page remember last xid which could knew its address */
-   GinPageSetDeleteXid(page, ReadNewTransactionId());
-
    /*
     * Any insert which would have gone on the leaf block will now go to its
     * right sibling.
@@ -168,6 +165,9 @@ ginDeletePage(GinVacuumState *gvs, BlockNumber deleteBlkno, BlockNumber leftBlkn
    page = BufferGetPage(lBuffer);
    GinPageGetOpaque(page)->rightlink = rightlink;
 
+   /* For deleted page remember last xid which could knew its address */
+   GinPageSetDeleteXid(page, ReadNewTransactionId());
+
    /* Delete downlink from parent */
    parentPage = BufferGetPage(pBuffer);
 #ifdef USE_ASSERT_CHECKING