Remove btree page items after page unlink
authorAlexander Korotkov
Tue, 4 Aug 2020 23:15:34 +0000 (02:15 +0300)
committerAlexander Korotkov
Tue, 4 Aug 2020 23:16:13 +0000 (02:16 +0300)
Currently, page unlink leaves remaining items "as is", but replay of
corresponding WAL-record re-initializes page leaving it with no items.
For the sake of consistency, this commit makes primary delete all the items
during page unlink as well.

Thanks to this change, we now don't mask contents of deleted btree page for
WAL consistency checking.

Discussion: https://postgr.es/m/CAPpHfdt_OTyQpXaPJcWzV2N-LNeNJseNB-K_A66qG%3DL518VTFw%40mail.gmail.com
Author: Alexander Korotkov
Reviewed-by: Peter Geoghegan
contrib/amcheck/verify_nbtree.c
src/backend/access/nbtree/nbtpage.c
src/backend/access/nbtree/nbtxlog.c

index e4d501a85d1f9daa7e47853853597618b086afc4..c9f9e755dccc9cf9683397ed6bcb67afd5b3bd39 100644 (file)
@@ -2864,11 +2864,8 @@ palloc_btree_page(BtreeCheckState *state, BlockNumber blocknum)
     * As noted at the beginning of _bt_binsrch(), an internal page must have
     * children, since there must always be a negative infinity downlink
     * (there may also be a highkey).  In the case of non-rightmost leaf
-    * pages, there must be at least a highkey.  Deleted pages on replica
-    * might contain no items, because page unlink re-initializes
-    * page-to-be-deleted.  Deleted pages with no items might be on primary
-    * too due to preceding recovery, but on primary new deletions can't
-    * happen concurrently to amcheck.
+    * pages, there must be at least a highkey.  The exceptions are deleted
+    * pages, which contain no items.
     *
     * This is correct when pages are half-dead, since internal pages are
     * never half-dead, and leaf pages must have a high key when half-dead
index 53dff326808385ffd0e638c66e1ec7eec86c7ec1..d5db9aaa3a13dfe8ce96be25b696ff0a770c4b7d 100644 (file)
@@ -2058,6 +2058,7 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno,
    BTMetaPageData *metad = NULL;
    ItemId      itemid;
    Page        page;
+   PageHeader  header;
    BTPageOpaque opaque;
    bool        rightsib_is_rightmost;
    int         targetlevel;
@@ -2327,6 +2328,14 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno,
    opaque->btpo_flags |= BTP_DELETED;
    opaque->btpo.xact = ReadNewTransactionId();
 
+   /*
+    * Remove the remaining tuples on the page.  This keeps things simple for
+    * WAL consistency checking.
+    */
+   header = (PageHeader) page;
+   header->pd_lower = SizeOfPageHeaderData;
+   header->pd_upper = header->pd_special;
+
    /* And update the metapage, if needed */
    if (BufferIsValid(metabuf))
    {
index 09d1b0e3419a989e87e00b7b07f9b6b4d21bd918..be0fa450f31da09488888a4b6ffe25b53b57c760 100644 (file)
@@ -1051,15 +1051,7 @@ btree_mask(char *pagedata, BlockNumber blkno)
 
    maskopaq = (BTPageOpaque) PageGetSpecialPointer(page);
 
-   if (P_ISDELETED(maskopaq))
-   {
-       /*
-        * Mask page content on a DELETED page since it will be re-initialized
-        * during replay. See btree_xlog_unlink_page() for details.
-        */
-       mask_page_content(page);
-   }
-   else if (P_ISLEAF(maskopaq))
+   if (P_ISLEAF(maskopaq))
    {
        /*
         * In btree leaf pages, it is possible to modify the LP_FLAGS without