I'll take a look tomorrow.

Interesting, contrib/amcheck doesn't find any error in index. Seems, it's subject for further improvement.

Nevertheless, seems, I found. In _bt_mark_page_halfdead() we use truncated high key IndexTuple as a storage of blocknumber of top parent to remove. And sets BTreeTupleSetNAtts(&trunctuple, 0) - it's stored in ip_posid.

But some later, in _bt_unlink_halfdead_page() we check ItemPointer high key with ItemPointerIsValid macro - and it returns false, because offset is actually InvalidOffsetNumber - i.e. 0 which was set by BTreeTupleSetNAtts. And some wrong decisions are follows, I didn't look at that.

Trivial and naive fix is attached, but for me it looks a bit annoing that we store pointer (leafhikey) somewhere inside unlocked page.



--
Teodor Sigaev                                   E-mail: teo...@sigaev.ru
                                                   WWW: http://www.sigaev.ru/
diff --git a/src/backend/access/nbtree/nbtpage.c b/src/backend/access/nbtree/nbtpage.c
index beef089ba8..e6fe4ba90e 100644
--- a/src/backend/access/nbtree/nbtpage.c
+++ b/src/backend/access/nbtree/nbtpage.c
@@ -1714,7 +1714,7 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, bool *rightsib_empty)
 	 * parent in the branch.  Set 'target' and 'buf' to reference the page
 	 * actually being unlinked.
 	 */
-	if (ItemPointerIsValid(leafhikey))
+	if (ItemPointerGetBlockNumberNoCheck(leafhikey) != InvalidBlockNumber)
 	{
 		target = ItemPointerGetBlockNumberNoCheck(leafhikey);
 		Assert(target != leafblkno);

Reply via email to