btree index (21)
_bt_delitems
btree indexのリーフページからアイテムを削除する。一度に複数のアイテムを削除できる。ページの更新はPageIndexMultiDeleteで実行する。ページを更新したらログレコードを出力している。
PageIndexMultiDelete
インデックスのページから複数のインデックスアイテムを削除する。
削除するアイテムが2つ以下だったら、PageIndexTupleDeleteをアイテムの数だけ実行する。
if (nitems <= 2) { while (--nitems >= 0) PageIndexTupleDelete(page, itemnos[nitems]); return; }
3つ以上の場合、itemIdSort配列に削除しないアイテムのリストを登録してから、以下のコードでItemIDの配列とIndexTupleのデータを整理する。
for (i = 0, itemidptr = itemidbase; i < nused; i++, itemidptr++) { lp = PageGetItemId(page, itemidptr->offsetindex + 1); upper -= itemidptr->alignedlen; memmove((char *) page + upper, (char *) page + itemidptr->itemoff, itemidptr->alignedlen); *lp = itemidptr->olditemid; lp->lp_off = upper; }
memmoveで削除されたIndexTupleのデータ領域を埋めている。その次の行で、ItemIDを設定している。
PageIndexTupleDelete
インデックスページからアイテムを1つ削除する。
(1)削除するアイテムのItemIDの場所を詰める。
if (nbytes > 0) memmove((char *) &(phdr->pd_linp[offidx]), (char *) &(phdr->pd_linp[offidx + 1]), nbytes);
(2)削除するアイテムのIndexTupleDataの場所を詰める。
if (offset > phdr->pd_upper) memmove(addr + size, addr, (int) (offset - phdr->pd_upper));
(3)pd_upper/pd_lowerの位置を調節する。
phdr->pd_upper += size; phdr->pd_lower -= sizeof(ItemIdData);
(4)memmoveによってIndexTupleDataの位置が変わったItemについて、lp_offの位置を調節する。
if (ii->lp_off <= offset) ii->lp_off += size;
_bt_page_recyclable
btree indexのページが再利用できるか調べる。ページが削除されていて、opaque->btpo.xact(ページが削除されたときに設定されるトランザクションID)がRecentXmin以下だったら、現在実行中のトランザクションから利用されていないので、再利用可能と判定する。
memo
Each sample counts as 0.01 seconds. % cumulative self time seconds seconds name 6.12 0.36 0.36 heapgettup (heapam.c:302 @ 8091273) 2.84 0.52 0.17 TransactionIdFollowsOrEquals (transam.c:386 @ 80aac51) 2.59 0.67 0.15 TransactionIdFollowsOrEquals (transam.c:390 @ 80aac7b) 2.50 0.82 0.15 heapgettup (heapam.c:297 @ 8091249) 2.33 0.95 0.14 tas (s_lock.h:124 @ 81f1bff) 1.64 1.05 0.10 heapgettup (heapam.c:266 @ 809119c) 1.55 1.14 0.09 TransactionIdFollows (transam.c:376 @ 80aac41) 1.47 1.22 0.09 heapgettup (heapam.c:296 @ 8091238) 1.38 1.30 0.08 HeapTupleSatisfiesSnapshot (tqual.c:855 @ 82a9a54)