mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-04 21:47:21 +02:00
Fix amcheck for page checks concurrent to replay of btree page deletion
amcheck expects at least hikey to always exist on leaf page even if it is deleted page. But replica reinitializes page during replay of page deletion, causing deleted page to have no items. Thus, replay of page deletion can cause an error in concurrent amcheck run. This commit relaxes amcheck expectation making it tolerate deleted page with no items. Reported-by: Konstantin Knizhnik Discussion: https://postgr.es/m/CAPpHfdt_OTyQpXaPJcWzV2N-LNeNJseNB-K_A66qG%3DL518VTFw%40mail.gmail.com Author: Alexander Korotkov Reviewed-by: Peter Geoghegan Backpatch-through: 11
This commit is contained in:
parent
891a2007e3
commit
ae1f9b0a9b
@ -2416,7 +2416,11 @@ 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.
|
* 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.
|
||||||
*
|
*
|
||||||
* 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
|
||||||
@ -2436,13 +2440,13 @@ palloc_btree_page(BtreeCheckState *state, BlockNumber blocknum)
|
|||||||
blocknum, RelationGetRelationName(state->rel),
|
blocknum, RelationGetRelationName(state->rel),
|
||||||
MaxIndexTuplesPerPage)));
|
MaxIndexTuplesPerPage)));
|
||||||
|
|
||||||
if (!P_ISLEAF(opaque) && maxoffset < P_FIRSTDATAKEY(opaque))
|
if (!P_ISLEAF(opaque) && !P_ISDELETED(opaque) && maxoffset < P_FIRSTDATAKEY(opaque))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INDEX_CORRUPTED),
|
(errcode(ERRCODE_INDEX_CORRUPTED),
|
||||||
errmsg("internal block %u in index \"%s\" lacks high key and/or at least one downlink",
|
errmsg("internal block %u in index \"%s\" lacks high key and/or at least one downlink",
|
||||||
blocknum, RelationGetRelationName(state->rel))));
|
blocknum, RelationGetRelationName(state->rel))));
|
||||||
|
|
||||||
if (P_ISLEAF(opaque) && !P_RIGHTMOST(opaque) && maxoffset < P_HIKEY)
|
if (P_ISLEAF(opaque) && !P_ISDELETED(opaque) && !P_RIGHTMOST(opaque) && maxoffset < P_HIKEY)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INDEX_CORRUPTED),
|
(errcode(ERRCODE_INDEX_CORRUPTED),
|
||||||
errmsg("non-rightmost leaf block %u in index \"%s\" lacks high key item",
|
errmsg("non-rightmost leaf block %u in index \"%s\" lacks high key item",
|
||||||
|
Loading…
Reference in New Issue
Block a user