動態數組涉及的檔案是innodb儲存引擎的三個檔案:dyn0dyn.h、dyn0dyn.ic以及dyn0dyn.c。
這是一個基本的組件功能,是作為一個動態虛擬線性數組。數組的基本元素是byte。動態數組dyn主要用來存放mtr的鎖定資訊以及log。Dyn在實現上,如果block需要分裂節點,則會使用一個記憶體堆。每個blokBlock Storage資料的資料欄位的長度是固定的(預設值是512),但是不一定會完全用完。假設需要儲存的資料項目的尺寸大於資料區塊時,該資料項目被分拆,這種情況主要用於log的緩衝。
2. 資料結構
typedef struct dyn_block_struct dyn_block_t;
typedef dyn_block_t dyn_array_t;
#defineDYN_ARRAY_DATA_SIZE 512
struct dyn_block_struct{
mem_heap_t* heap;
ulint used;
byte data[DYN_ARRAY_DATA_SIZE];
UT_LIST_BASE_NODE_T(dyn_block_t) base;
UT_LIST_NODE_T(dyn_block_t) list;
#ifdef UNIV_DEBUG
ulint buf_end;
ulint magic_n;
#endif
};
//下面兩個是公用宏定義,見ut0lst.h
#define UT_LIST_BASE_NODE_T(TYPE)
struct {
ulintcount;/* count of nodes in list */
TYPE *start;/* pointer to list start, NULL if empty */
TYPE *end;/* pointer to list end, NULL if empty */
}
#define UT_LIST_NODE_T(TYPE)
struct {
TYPE *prev;/* pointer to the previous node,
NULL if start of list */
TYPE *next;/* pointer to next node, NULL if end of list */
}
欄位解釋:
1) heap
從字面上理解,heap是記憶體堆的意思。從上面的結構體中,我們可以看出,dyn_array_t就是dyn_block_struct。這個結構體裡面的欄位date用來存放資料,used顯示已經使用的位元組數量,假設這時候還要儲存一個大小為長度為x的資料,這時候data裡面已經儲存不了,所以就需要再分配一個新的block節點。那麼分配結構所需要的記憶體從哪裡來了,就從第一個節點裡面的heap裡面分配。
這裡面,我們還需要主意一點。雖然資料結構用的是同一個dyn_block_struct,但是我們稱第一個節點為arr,表明這個是動態資料的前端節點。其它的節點,我們稱為block節點。
我們這裡面先來看看,剛開始創立dyn的函數是怎麼實現的:
UNIV_INLINE
dyn_array_t*
dyn_array_create(
/*=============*/
/* out: initialized dyn array */
dyn_array_t*arr)/* in: pointer to a memory buffer of
size sizeof(dyn_array_t) */
{
ut_ad(arr);
ut_ad(DYN_ARRAY_DATA_SIZE < DYN_BLOCK_FULL_FLAG);
arr->heap = NULL;
arr->used = 0;
#ifdef UNIV_DEBUG
arr->buf_end = 0;
arr->magic_n = DYN_BLOCK_MAGIC_N;
#endif
return(arr);
}
其中的ud_ad是屬於紅判斷,相當於assert。這個我們暫時不表。這個函數是在mtr建立的時候來調用的,在調用的時候已經分配了arr指標。
在dyn_array_create函數中,系統將heap欄位設定為NULL,Used設定為0。Buf_end和magic_n是調試的時候使用的,每個結構體定義都會唯一的對應一個magic_n值。這樣在調試的時候,就可以快速進行問題的跟蹤。