Remove btree page items after page unlink
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
This commit is contained in:
parent
0f76294260
commit
f47b5e1395
@ -2864,11 +2864,8 @@ palloc_btree_page(BtreeCheckState *state, BlockNumber blocknum)
|
|||||||
* As noted at the beginning of _bt_binsrch(), an internal page must have
|
* As noted at the beginning of _bt_binsrch(), an internal page must have
|
||||||
* children, since there must always be a negative infinity downlink
|
* children, since there must always be a negative infinity downlink
|
||||||
* (there may also be a highkey). In the case of non-rightmost leaf
|
* (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
|
* pages, there must be at least a highkey. The exceptions are deleted
|
||||||
* might contain no items, because page unlink re-initializes
|
* pages, which contain no items.
|
||||||
* 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.
|
|
||||||
*
|
*
|
||||||
* This is correct when pages are half-dead, since internal pages are
|
* 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
|
* never half-dead, and leaf pages must have a high key when half-dead
|
||||||
|
@ -2058,6 +2058,7 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno,
|
|||||||
BTMetaPageData *metad = NULL;
|
BTMetaPageData *metad = NULL;
|
||||||
ItemId itemid;
|
ItemId itemid;
|
||||||
Page page;
|
Page page;
|
||||||
|
PageHeader header;
|
||||||
BTPageOpaque opaque;
|
BTPageOpaque opaque;
|
||||||
bool rightsib_is_rightmost;
|
bool rightsib_is_rightmost;
|
||||||
int targetlevel;
|
int targetlevel;
|
||||||
@ -2327,6 +2328,14 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno,
|
|||||||
opaque->btpo_flags |= BTP_DELETED;
|
opaque->btpo_flags |= BTP_DELETED;
|
||||||
opaque->btpo.xact = ReadNewTransactionId();
|
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 */
|
/* And update the metapage, if needed */
|
||||||
if (BufferIsValid(metabuf))
|
if (BufferIsValid(metabuf))
|
||||||
{
|
{
|
||||||
|
@ -1051,15 +1051,7 @@ btree_mask(char *pagedata, BlockNumber blkno)
|
|||||||
|
|
||||||
maskopaq = (BTPageOpaque) PageGetSpecialPointer(page);
|
maskopaq = (BTPageOpaque) PageGetSpecialPointer(page);
|
||||||
|
|
||||||
if (P_ISDELETED(maskopaq))
|
if (P_ISLEAF(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))
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* In btree leaf pages, it is possible to modify the LP_FLAGS without
|
* In btree leaf pages, it is possible to modify the LP_FLAGS without
|
||||||
|
Loading…
x
Reference in New Issue
Block a user