您的位置:首页 > 其它

[置顶]innodb动态内存管理

2016-05-03 09:46 363 查看
1.InnoDB内存管理分配采用内存堆方式,从内存池申请和innodb buffer pool申请,按照不同的内存类型采用不同内存分配。
在innodb内存管理中有三种内存类型:
(1)动态内存,该内存是从内存池中进行申请.
(2)缓冲内存,该内存是从buffer pool中进行分配
(3)自适应哈希索引。
如下定义了三种内存类型:

#define MEM_HEAP_DYNAMIC    0    /* the most common type */
#define MEM_HEAP_BUFFER        1
#define MEM_HEAP_BTR_SEARCH    2

typedef struct mem_block_info_t    mem_block_t;

/* A memory heap is a nonempty linear list of memory blocks */
typedef mem_block_t        mem_heap_t;

代码:
if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) {
assert(type == MEM_HEAP_DYNAMIC || n <= MEM_MAX_ALLOC_IN_BUF);
block = static_cast<mem_block_t*>(mem_area_alloc(&len, mem_comm_pool));
}
else
{
buf_block = buf_block_alloc(NULL);//申请内存从缓冲池进行申请(Allocates a buffer block.)
block = (mem_block_t*) buf_block->frame;// 每个页在缓冲池中对应的数据结构。
}
UNIV_INTERN mem_pool_t*    mem_comm_pool    = NULL;
以上是mem_block_t是从内存池进行分配的。

2.InnoDB内存池的相关结构,该内存池主要是InnoDB引擎内存数据结构对象(数据字典以及自适应哈希),并非是InnoDB内存页哦。
该内存池是用于小块内存的分配。内存池内存主要为如下结构分配内存:
(1)数据字典。
(2)自适应哈希索引。
"Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures."

3.该内存池调用的函数关系如下:
(1)innobase_init(void    *p)[ha_innodb.cc]->innobase_start_or_create_for_mysql(void)
/*********************************************************************//**
Opens an InnoDB database.
@return    0 on success, error code on failure */
static int innobase_init

(2)innobase_start_or_create_for_mysql(void)[srv0start.cc]->srv_boot();
/********************************************************************
Starts InnoDB and creates a new database if database files
are not found and the user wants.
@return    DB_SUCCESS or error code */
UNIV_INTERN dberr_t innobase_start_or_create_for_mysql(void)

(3)srv_boot(void)[srv0srv.cc]->srv_general_init()
/*********************************************************************//**
Boots the InnoDB server. */
UNIV_INTERN    void srv_boot(void)

(4)srv_general_init(void)[srv0srv.cc]->mem_init(srv_mem_pool_size);
/*********************************************************************//**
Initializes the synchronization primitives, memory system, and the thread
local storage. */
UNIV_INTERN void srv_general_init(void)

srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
srv_mem_pool_size定义在ha_innodb.cc中

(5)    mem_init(ulint    size)[memdbg.cc]->mem_pool_create(size);
/******************************************************************//**
Initializes the memory system. */

(6) mem_pool_create(ulint    size)[mem0pool.cc]
/********************************************************************//**
Creates a memory pool.
@return    memory pool */
从以上的关系来讲,该内存池就是管理额外缓冲池的,而额外缓冲池是管理数据结构是用的。

(1)如下为内存堆得相关数据结构:

/** The info structure stored at the beginning of a heap block */
struct mem_block_info_t {
ulint    magic_n;/* magic number for debugging */
#ifdef UNIV_DEBUG
char    file_name[8];/* file name where the mem heap was created */
ulint    line;    /*!< line number where the mem heap was created */
#endif /* UNIV_DEBUG */
UT_LIST_BASE_NODE_T(mem_block_t) base; /* In the first block in the
the list this is the base node of the list of blocks;
in subsequent blocks this is undefined */
UT_LIST_NODE_T(mem_block_t) list; /* This contains pointers to next
and prev in the list. The first block allocated
to the heap is also the first block in this list,
though it also contains the base node of the list. */
ulint    len;    /*!< physical length of this block in bytes */
ulint    total_size; /*!< physical length in bytes of all blocks
in the heap. This is defined only in the base
node and is set to ULINT_UNDEFINED in others. */
ulint    type;    /*!< type of heap: MEM_HEAP_DYNAMIC, or
MEM_HEAP_BUF possibly ORed to MEM_HEAP_BTR_SEARCH */
ulint    free;    /*!< offset in bytes of the first free position for
user data in the block */
ulint    start;    /*!< the value of the struct field 'free' at the
creation of the block */
#ifndef UNIV_HOTBACKUP
void*    free_block;
/* if the MEM_HEAP_BTR_SEARCH bit is set in type,
and this is the heap root, this can contain an
allocated buffer frame, which can be appended as a
free block to the heap, if we need more space;
otherwise, this is NULL */
void*    buf_block;
/* if this block has been allocated from the buffer
pool, this contains the buf_block_t handle;
otherwise, this is NULL */
#endif /* !UNIV_HOTBACKUP */
#ifdef MEM_PERIODIC_CHECK
UT_LIST_NODE_T(mem_block_t) mem_block_list;
/* List of all mem blocks allocated; protected
by the mem_comm_pool mutex */
#endif
};

(2)如下为内存池相关的结构或者函数的定义
#define UT_LIST_BASE_NODE_T(TYPE)                    \
struct {                                \
int   count;  /*!< 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 */\
}                                    \

/** Memory area header */
struct mem_area_t{
ulint        size_and_free;    /*!< memory area size is obtained by
anding with ~MEM_AREA_FREE; area in
a free list if ANDing with
MEM_AREA_FREE results in nonzero */
UT_LIST_NODE_T(mem_area_t)
free_list;    /*!< free list node */
};
/** Data structure for a memory pool. The space is allocated using the buddy
algorithm, where free list i contains areas of size 2 to power i. */
struct mem_pool_t{
byte*        buf;        /*!< memory pool */
ulint        size;        /*!< memory common pool size */
ulint        reserved;    /*!< amount of currently allocated
memory */
ib_mutex_t        mutex;        /*!< mutex protecting this struct */
UT_LIST_BASE_NODE_T(mem_area_t)
free_list[64];    /*!< lists of free memory areas: an
area is put to the list whose number
is the 2-logarithm of the area size */
};

/********************************************************************//**
Creates a memory pool.
@return    memory pool */
UNIV_INTERN mem_pool_t* mem_pool_create(
/*============*/
ulint    size)    /*!< in: pool size in bytes */
{
mem_pool_t*    pool;
mem_area_t*    area;
ulint        i;
ulint        used;

pool = static_cast<mem_pool_t*>(ut_malloc(sizeof(mem_pool_t))); //内存池的信息

pool->buf = static_cast<byte*>(ut_malloc_low(size, TRUE)); //申请大小为size的内存池,该Size是由innodb_additional_mem_pool_size提供
pool->size = size;

mutex_create(mem_pool_mutex_key, &pool->mutex, SYNC_MEM_POOL); //添加互斥量

/* Initialize the free lists */

for (i = 0; i < 64; i++) {

UT_LIST_INIT(pool->free_list[i]);
}

used = 0;

while (size - used >= MEM_AREA_MIN_SIZE) {

i = ut_2_log(size - used); //ut_2_log(N):X=0;for(){N=N/2;if(N==0)break;}

if (ut_2_exp(i) > size - used) { //ut_2_exp是2的i次幂

/* ut_2_log rounds upward */

i--;
}

area = (mem_area_t*)(pool->buf + used);

mem_area_set_size(area, ut_2_exp(i));
mem_area_set_free(area, TRUE);
UNIV_MEM_FREE(MEM_AREA_EXTRA_SIZE + (byte*) area,
ut_2_exp(i) - MEM_AREA_EXTRA_SIZE);

UT_LIST_ADD_FIRST(free_list, pool->free_list[i], area);

used = used + ut_2_exp(i);
}

ut_ad(size >= used);

pool->reserved = 0;

return(pool);
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: