diff --git a/src/backend/access/nbtree/nbtpage.c b/src/backend/access/nbtree/nbtpage.c index 93d2b70663..75628e0eb9 100644 --- a/src/backend/access/nbtree/nbtpage.c +++ b/src/backend/access/nbtree/nbtpage.c @@ -1599,8 +1599,6 @@ _bt_pagedel(Relation rel, Buffer leafbuf, TransactionId *oldestBtpoXact) itup_key->pivotsearch = true; stack = _bt_search(rel, itup_key, &sleafbuf, BT_READ, NULL); /* won't need a second lock or pin on leafbuf */ - Assert(leafblkno == BufferGetBlockNumber(sleafbuf) || - !itup_key->heapkeyspace); _bt_relbuf(rel, sleafbuf); /* @@ -1608,6 +1606,15 @@ _bt_pagedel(Relation rel, Buffer leafbuf, TransactionId *oldestBtpoXact) * within _bt_mark_page_halfdead. We must do it that way * because it's possible that leafbuf can no longer be * deleted. We need to recheck. + * + * Note: We can't simply hold on to the sleafbuf lock instead, + * because it's barely possible that sleafbuf is not the same + * page as leafbuf. This happens when leafbuf split after our + * original lock was dropped, but before _bt_search finished + * its descent. We rely on the assumption that we'll find + * leafbuf isn't safe to delete anymore in this scenario. + * (Page deletion can cope with the stack being to the left of + * leafbuf, but not to the right of leafbuf.) */ LockBuffer(leafbuf, BT_WRITE); continue; @@ -1735,9 +1742,8 @@ _bt_mark_page_halfdead(Relation rel, Buffer leafbuf, BTStack stack) * Before attempting to lock the parent page, check that the right sibling * is not in half-dead state. A half-dead right sibling would have no * downlink in the parent, which would be highly confusing later when we - * delete the downlink that follows the leafbuf page's downlink. It would - * fail the "right sibling of target page is also the next child in parent - * page" cross-check below. + * delete the downlink. It would fail the "right sibling of target page + * is also the next child in parent page" cross-check below. */ if (_bt_rightsib_halfdeadflag(rel, leafrightsib)) {