innodb动态内存管理

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); }

 

posted @ 2015-07-14 10:57  一个万能盒子叫数据库  阅读(687)  评论(0编辑  收藏  举报