1. 程式人生 > >mysql常用資料結構介紹(1)

mysql常用資料結構介紹(1)

mem_root

mysql層通過mem_root管理記憶體分配,防止頻繁分配和釋放小記憶體。

mem_root的定義見include/my_alloc.h:

typedef struct st_mem_root
{
  USED_MEM *free;              空閒連結串列,分配空間時先檢查該連結串列有沒有剩餘空間,如果沒有,再分配新空間
  USED_MEM *used;             已經分配完成的連結串列空間,該連結串列中的資料空間幾乎沒有剩餘可用空間
  USED_MEM *pre_alloc;      預先分配的塊
  size_t min_malloc;              如果一個USED_MEM塊中可用空間left小於該值,這個塊放入used連結串列中
  size_t block_size;               初始塊的大小
  unsigned int block_num;      塊的數目
  unsigned int first_block_usage; 空閒連結串列中第一個塊檢查的次數,如果超過MAX_BLOCK_USAGE_BEFORE_DROP,該塊會被放入used連結串列中

  void (*error_handler)(void);
} MEM_ROOT;

typedef struct st_used_mem
{                   /* struct for once_alloc (block) */
  struct st_used_mem *next;       /* Next block in use */
  unsigned int    left;           /* memory left in block  */
  unsigned int    size;           /* size of block */
} USED_MEM;

該結構主要有兩個連結串列: free和used。 每個連結串列使用USED_MEM作為資料節點,資料節點中存有空間總大小和未使用的空間大小。新建一個數據節點時,先新增到free連結串列中,隨著空間的分配,資料節點中未使用空間大小left小於閾值min_malloc,該資料節點新增到used連結串列中。分配空間時,先從free連結串列中檢查有沒有可用的空間,如果沒有,再分配新的塊。

相關的函式:

init_alloc_root: 初始化mem_root物件。如果pre_alloc_size不為0,預先建立一個數據塊,free和pre_alloc指向這個資料塊。

alloc_root

:從mem_root物件中分配指定大小length的記憶體。 

                   該函式先檢查free連結串列的首個數據塊,如果該資料塊連續ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP(10)次不滿足分配條件,並且該塊小於ALLOC_MAX_BLOCK_TO_DROP(4K),將該塊移動到used連結串列中。

                  依次檢查free連結串列中剩餘空間大於length的資料塊。如果不存在這樣的資料塊,新建一個數據塊。注意新建資料塊的大小如下,可以看到分配的空間大小會趨向于越來越大:

 block_size= mem_root->block_size * (mem_root->block_num >> 2);    預設大小,block_num每增加4,分配的記憶體大小增加block_size
    get_size= length+ALIGN_SIZE(sizeof(USED_MEM));    分配請求的空間大小
    get_size= MY_MAX(get_size, block_size);  取最大值

                 修改該資料塊的left剩餘空間,如果left剩餘空間小於min_malloc,加入到used連結串列的表頭。

reset_root_defaults

            該函式設定block_size和pre_alloc塊。如果沒有符合要求的pre_alloc塊,遍歷free連結串列,查詢符合要求的資料塊,如果發現完全沒有使用的資料塊,free該塊的空間。如果最後沒有找到,新建一個符合要求的塊。

             

free_root: 清空分配的資料塊

      MY_MARK_BLOCKS_FREE: used連結串列中的資料庫合併到free連結串列中,並且所有資料塊中資料清空(left設定為初始塊大小)。最終結果:free連結串列指向所有的資料塊,used連結串列中空。沒有向作業系統釋放空間

    MY_KEEP_PREALLOC:只保留pre_alloc塊,其他塊的空間都釋放給作業系統。

 

參考:https://www.cnblogs.com/justfortaste/p/3198406.html