下面羅列了openGauss數(shù)據(jù)庫中有關(guān)B+樹操作的主要函數(shù),并且對其進行一一分析。
BTSpool *_bt_spoolinit(Relation index, bool isunique, bool isdead, void *meminfo)
Datum btbuild(PG_FUNCTION_ARGS)
static inline double tableam_index_build_scan(Relation heapRelation, Relation indexRelation, IndexInfo* indexInfo, bool allow_sync, IndexBuildCallback callback, void* callback_state)
double IndexBuildHeapScan(Relation heapRelation, Relation indexRelation, IndexInfo* indexInfo, bool allow_sync,IndexBuildCallback callback, void* callback_state)
static void btbuildCallback(Relation index, HeapTuple htup, Datum *values, const bool *isnull, bool tupleIsAlive,void *state);
void _bt_spool(BTSpool *btspool, ItemPointer self, Datum *values, const bool *isnull)
void tuplesort_putindextuplevalues(Tuplesortstate* state, Relation rel, ItemPointer self, Datum* values, const bool* isnull)
static void puttuple_common(Tuplesortstate* state, SortTuple* tuple)
void _bt_leafbuild(BTSpool *btspool, BTSpool *btspool2)
void tuplesort_performsort(Tuplesortstate* state)
static void _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2)
void _bt_buildadd(BTWriteState *wstate, BTPageState *state, IndexTuple itup)
static void _bt_sortaddtup(Page page, Size itemsize, IndexTuple itup, OffsetNumber itup_off)
void _bt_spooldestroy(BTSpool *btspool)
aminsert (Relation indexRelation,
Datum *values,
bool *isnull,
ItemPointer heap_tid,
Relation heapRelation,
IndexUniqueCheck checkUnique);
Datum btinsert(PG_FUNCTION_ARGS)
static void _bt_findinsertloc(Relation rel, Buffer *bufptr, OffsetNumber *offsetptr, int keysz, ScanKey scankey,IndexTuple newtup, BTStack stack, Relation heapRel)
static void _bt_insertonpg(Relation rel, Buffer buf, Buffer cbuf, BTStack stack, IndexTuple itup,OffsetNumber newitemoff, bool split_only_page)
static OffsetNumber _bt_findsplitloc(Relation rel, Page page, OffsetNumber newitemoff, Size newitemsz,bool *newitemonleft)
static void _bt_checksplitloc(FindSplitData *state, OffsetNumber firstoldonright, bool newitemonleft,int olddataitemstoleft, Size firstoldonrightsz)
static Buffer _bt_split(Relation rel, Buffer buf, Buffer cbuf, OffsetNumber firstright, OffsetNumber newitemoff,Size newitemsz, IndexTuple newitem, bool newitemonleft)
void _bt_insert_parent(Relation rel, Buffer buf, Buffer rbuf, BTStack stack, bool is_root, bool is_only)
_bt_spoolinit函數(shù)
作用:建立以及初始化一個spool 結(jié)構(gòu)
參數(shù):(Relation index, bool isunique, bool isdead, void *meminfo)
btbuild函數(shù)
作用:建立一個新的b+樹索引
參數(shù):(PG_FUNCTION_ARGS)
1.構(gòu)建一個BTBuildState對象,BTBuildState中包含兩個BTSpool對象指針,用于將heap tuple加載到內(nèi)存中,調(diào)用_bt_spoolinit函數(shù),初始化BTSpool。
2.調(diào)用GlobalIndexBuildHeapScan函數(shù)或者 tableam_index_build_scan函數(shù)獲得需要所有的元組數(shù)量,返回函數(shù)指針buildstate。
3.調(diào)用_bt_leafbuild函數(shù),將buildstate中得到的索引元組構(gòu)建為索引結(jié)構(gòu)
tableam_index_build_scan函數(shù)
這個函數(shù)實際上調(diào)用的是IndexBuildHeapScan函數(shù)
IndexBuildHeapScan函數(shù)
作用:掃描堆表結(jié)構(gòu),尋找需要建立索引的元組
參數(shù):(Relation heapRelation, Relation indexRelation, IndexInfo* indexInfo, bool allow_sync,
IndexBuildCallback callback, void* callback_state)
1.參數(shù)檢查
2.需要讀取所有heap tuple(SNAPSHOT_ANY),然后判斷heap tuple是否需要被索引。如果是create index concurrently 基于MVCC snapshot讀取heaptuple(SNAPSHOT_MVCC),每個讀取出來的heap tuple抽取出索引需要的列信息
3.通過heap_beginscan_strat建立掃描描述符,然后while(heap_getnext),對堆表上的元組循環(huán)掃描,判斷元組的狀態(tài)、是否需要建立索引,然后調(diào)用callback函數(shù)(b+樹使用的是btbuildCallback函數(shù)),對需要索引的元組進行處理。
4.結(jié)束掃描,返回需要索引的元組個數(shù)。
HeapTupleSatisfiesVacuum函數(shù)
作用:根據(jù)一系列規(guī)則,判斷元組的狀態(tài)(在astore文件中有提起過)
參數(shù):(HeapTuple htup, TransactionId OldestXmin, Buffer buffer, bool isAnalyzing)
btbuildCallback函數(shù)
作用:處理需要索引的元組,建立IndexTuple結(jié)構(gòu)
參數(shù):(Relation index, HeapTuple htup, Datum *values, const bool *isnull, bool tupleIsAlive,void *state)
調(diào)用_bt_spool函數(shù)進行實現(xiàn)
_bt_spool函數(shù)
作用:將SortTuple存入到Spool結(jié)構(gòu)中
參數(shù):(BTSpool *btspool, ItemPointer self, Datum *values, const bool *isnull)
tuplesort_putindextuplevalues函數(shù)
作用:將SortTuple存入到Spool結(jié)構(gòu)中
參數(shù):(Tuplesortstate* state, Relation rel, ItemPointer self, Datum* values, const bool* isnull)
1.調(diào)用MemoryContextSwitchTo切換內(nèi)存上下文,防止產(chǎn)生內(nèi)存泄漏
2.新建SortTuple類型變量,調(diào)用index_form_tuple函數(shù),獲取IndexTuple變量,將IndexTuple的t_tid指針指向需要索引的堆表元組。設(shè)置SortTuple->tuple = IndexTuple,同時設(shè)置第一列的值(datum1),(猜測是用來排序的鍵值)。
3.調(diào)用puttuple_common函數(shù),將SortTuple存入state中。
4.調(diào)用MemoryContextSwitchTo切換內(nèi)存上下文
puttuple_common函數(shù)
作用:根據(jù)Tuplesortstate的狀態(tài),將SortTuple存入state->memtuples數(shù)組中
參數(shù):(Tuplesortstate* state, SortTuple* tuple)
1.根據(jù)Tuplesortstate的狀態(tài)。
typedef enum {
//裝載元組,在內(nèi)存限制之內(nèi)
TSS_INITIAL, /* Loading tuples; still within memory limit */
//裝載元組到有界堆中
TSS_BOUNDED, /* Loading tuples into bounded-size heap */
//裝載元組,寫入到tape中
TSS_BUILDRUNS, /* Loading tuples; writing to tape */
//完全在內(nèi)存中完成排序
TSS_SORTEDINMEM, /* Sort completed entirely in memory */
//完成排序,最后在tape上執(zhí)行排序
TSS_SORTEDONTAPE, /* Sort completed, final run is on tape */
//不落地執(zhí)行最后的歸并
TSS_FINALMERGE /* Performing final merge on-the-fly */
} TupSortStatus;
2.TSS_INITIAL狀態(tài)時,將SortTuple存入state->memtuples數(shù)組中,并且判斷尋找狀態(tài)是否需要變成TSS_BOUNDED狀態(tài),調(diào)用make_bounded_heap函數(shù)進行調(diào)整,進行排序,生成大頂堆的結(jié)構(gòu)。
3.TSS_BOUNDED狀態(tài),如果新元組<=堆頂元素,那么就不考慮這個新元組,否則的話將堆頂元素pop出來, 插入新元組。
4.TSS_BUILDRUNS:狀態(tài),直接存入新元組(此時未排序),調(diào)用dumptuples函數(shù),如果我們超過了內(nèi)存限制,轉(zhuǎn)儲元組直到低于內(nèi)存限制