postgres 源码解析 45 btree分裂流程_bt_split
在PostgreSQL中,btree分裂操作是在插入新元组时,如果页面已满,需要将页面分裂成两半以便为新元组腾出空间时发生的。\_bt\_split 函数负责执行这个任务。以下是该函数的核心代码片段:
/*
* _bt_split() -- split a full page into two
*
* The original page is on the left, and the new page is created on the right.
*
* The split key is chosen among the page's current entries to keep the split
* about even. (This is called "infinity mass splitting" in the TIDBIT paper
* that described this technique.) We also ensure that the right sibling will
* be at least half full, by moving multiple items to the right if necessary.
*/
void
_bt_split(Relation rel,
Buffer lbuf, Buffer rbuf,
BTStack stack,
int newitemoff,
IndexTuple itup,
Size itemsize,
bool split_only)
{
Page lpage,
rpage;
ItemId lpid,
rpid;
ItemIdData rpiddata;
IndexTupleData *itupdata;
OffsetNumber off;
OffsetNumber separator;
OffsetNumber offright;
OffsetNumber minoff;
OffsetNumber maxoff;
bool is_leaf;
BlockNumber rblkno;
/* XXX cache overflow page */
lpage = BufferGetPage(lbuf);
rpage = BufferGetPage(rbuf);
is_leaf = P_ISLEAF(lpage);
minoff = P_FIRSTDATAKEY(lpage);
maxoff = PageGetMaxOffsetNumber(lpage);
/*
* Select the midpoint in the current page to split.
*
* The midpoint algorithm is not quite the "infinity mass" method described
* in the TIDBIT paper, as we cannot enforce that exactly. The algorithm
* here is thus:
*
* 1. Calculate the "ideal" midpoint, which is the median key value.
* 2. If the ideal midpoint is the first or last key, or is less than
* 2 keys from the first or last key, move it forward or backward
* until it has the desired number of keys on each side.
*
* Note that if there are only two items in the page, the midpoint will be
* the first or second item, and so by the time we're done moving it, it
* will have the desired keys on each side.
*/
separator = (OffsetNumber) (((int) maxoff + minoff) / 2);
if (separator == minoff || separator == maxoff)
{
/*
* At one end of the page, so move t
评论已关闭