return ndeleted;
}
+/*
+ * First stage of page deletion. Remove the downlink to the top of the
+ * branch being deleted, and mark the leaf page as half-dead.
+ */
static bool
_bt_mark_page_halfdead(Relation rel, Buffer leafbuf, BTStack stack)
{
OffsetNumber topoff;
OffsetNumber nextoffset;
IndexTuple itup;
+ IndexTupleData trunctuple;
page = BufferGetPage(leafbuf);
opaque = (BTPageOpaque) PageGetSpecialPointer(page);
opaque = (BTPageOpaque) PageGetSpecialPointer(page);
opaque->btpo_flags |= BTP_HALF_DEAD;
- itemid = PageGetItemId(page, P_HIKEY);
- itup = (IndexTuple) PageGetItem(page, itemid);
- if (target == leafblkno)
- ItemPointerSetInvalid(&(itup->t_tid));
+ PageIndexTupleDelete(page, P_HIKEY);
+ Assert(PageGetMaxOffsetNumber(page) == 0);
+ MemSet(&trunctuple, 0, sizeof(IndexTupleData));
+ trunctuple.t_info = sizeof(IndexTupleData);
+ if (target != leafblkno)
+ ItemPointerSet(&trunctuple.t_tid, target, P_HIKEY);
else
- ItemPointerSet(&(itup->t_tid), target, P_HIKEY);
+ ItemPointerSetInvalid(&trunctuple.t_tid);
+ if (PageAddItem(page, (Item) &trunctuple, sizeof(IndexTupleData), P_HIKEY,
+ false, false) == InvalidOffsetNumber)
+ elog(ERROR, "could not add dummy high key to half-dead page");
/* Must mark buffers dirty before XLogInsert */
MarkBufferDirty(topparent);
xlrec.target.node = rel->rd_node;
ItemPointerSet(&(xlrec.target.tid), BufferGetBlockNumber(topparent), topoff);
xlrec.leafblk = leafblkno;
- xlrec.downlink = target;
+ if (target != leafblkno)
+ xlrec.topparent = target;
+ else
+ xlrec.topparent = InvalidBlockNumber;
page = BufferGetPage(leafbuf);
opaque = (BTPageOpaque) PageGetSpecialPointer(page);
xlrec.leafblk = leafblkno;
xlrec.leafleftsib = leafleftsib;
xlrec.leafrightsib = leafrightsib;
- xlrec.downlink = nextchild;
+ xlrec.topparent = nextchild;
rdata[0].data = (char *) &xlrec;
rdata[0].len = SizeOfBtreeUnlinkPage;
*/
MemSet(&trunctuple, 0, sizeof(IndexTupleData));
trunctuple.t_info = sizeof(IndexTupleData);
- if (xlrec->downlink != InvalidBlockNumber)
- ItemPointerSet(&trunctuple.t_tid, xlrec->downlink, P_HIKEY);
+ if (xlrec->topparent != InvalidBlockNumber)
+ ItemPointerSet(&trunctuple.t_tid, xlrec->topparent, P_HIKEY);
else
ItemPointerSetInvalid(&trunctuple.t_tid);
if (PageAddItem(page, (Item) &trunctuple, sizeof(IndexTupleData), P_HIKEY,
/* Add a dummy hikey item */
MemSet(&trunctuple, 0, sizeof(IndexTupleData));
trunctuple.t_info = sizeof(IndexTupleData);
- if (xlrec->downlink != InvalidBlockNumber)
- ItemPointerSet(&trunctuple.t_tid, xlrec->downlink, P_HIKEY);
+ if (xlrec->topparent != InvalidBlockNumber)
+ ItemPointerSet(&trunctuple.t_tid, xlrec->topparent, P_HIKEY);
else
ItemPointerSetInvalid(&trunctuple.t_tid);
if (PageAddItem(page, (Item) &trunctuple, sizeof(IndexTupleData), P_HIKEY,
appendStringInfoString(buf, "mark_page_halfdead: ");
out_target(buf, &(xlrec->target));
- appendStringInfo(buf, "; downlink %u; leaf %u; left %u; right %u",
- xlrec->downlink, xlrec->leafblk, xlrec->leftblk, xlrec->rightblk);
+ appendStringInfo(buf, "; topparent %u; leaf %u; left %u; right %u",
+ xlrec->topparent, xlrec->leafblk, xlrec->leftblk, xlrec->rightblk);
break;
}
case XLOG_BTREE_UNLINK_PAGE_META:
xlrec->node.spcNode, xlrec->node.dbNode, xlrec->node.relNode);
appendStringInfo(buf, "dead %u; left %u; right %u; btpo_xact %u; ",
xlrec->deadblk, xlrec->leftsib, xlrec->rightsib, xlrec->btpo_xact);
- appendStringInfo(buf, "leaf %u; leafleft %u; leafright %u; downlink %u",
- xlrec->leafblk, xlrec->leafleftsib, xlrec->leafrightsib, xlrec->downlink);
+ appendStringInfo(buf, "leaf %u; leafleft %u; leafright %u; topparent %u",
+ xlrec->leafblk, xlrec->leafleftsib, xlrec->leafrightsib, xlrec->topparent);
break;
}
case XLOG_BTREE_NEWROOT:
typedef struct xl_btree_mark_page_halfdead
{
xl_btreetid target; /* deleted tuple id in parent page */
+
+ /* information needed to recreate the leaf page: */
BlockNumber leafblk; /* leaf block ultimately being deleted */
BlockNumber leftblk; /* leaf block's left sibling, if any */
BlockNumber rightblk; /* leaf block's right sibling */
- BlockNumber downlink; /* next child down in the branch */
+ BlockNumber topparent; /* topmost internal page in the branch */
} xl_btree_mark_page_halfdead;
-#define SizeOfBtreeMarkPageHalfDead (offsetof(xl_btree_mark_page_halfdead, downlink) + sizeof(BlockNumber))
+#define SizeOfBtreeMarkPageHalfDead (offsetof(xl_btree_mark_page_halfdead, topparent) + sizeof(BlockNumber))
/*
* This is what we need to know about deletion of a btree page. Note we do
BlockNumber leafblk;
BlockNumber leafleftsib;
BlockNumber leafrightsib;
- BlockNumber downlink; /* next child down in the branch */
+ BlockNumber topparent; /* next child down in the branch */
TransactionId btpo_xact; /* value of btpo.xact for use in recovery */
/* xl_btree_metadata FOLLOWS IF XLOG_BTREE_UNLINK_PAGE_META */