起動プロセス(5) buf_pool_init関数
innobase_start_or_create_for_mysql関数の中で呼び出される。バッファプールがどうなっているのかは、この関数を読めば分かる。
buf0buf.cにて。buf_poolを初期化する。
max_size、curr_size、n_framesの値はinnodb_buffer_pool_sizeをPageサイズで割った値と同じのようだ。block=frame=Pageという図式で捉えてよい(?)
534行目にて、buf_pool構造体のメモリ割り当て。
buf_pool = mem_alloc(sizeof(buf_pool_t));
その後、buf_pool->mutexの初期化を行ってから、mutex_enterして、571行目。
buf_pool->frame_mem = os_mem_alloc_large( UNIV_PAGE_SIZE * (n_frames + 1), TRUE, FALSE);
ここで、innodb_buffer_pool_sizeで指定したサイズのメモリを割り当て。先頭アドレスをbuf_pool- >frame_memに格納。第3引数TRUEにより、割り当てた領域はゼロクリアされる。第4引数は割り当てに失敗したときにmysqldを終了すべきか否かの指示。
割り当てサイズ実際には以下のようになっている。
innodb_buffer_pool_size + 1page分 + ut_mem_block_tのサイズ(16バイト)
呼び出し先のut_malloc_low関数にてmallocが行われる。
ret = malloc(n + sizeof(ut_mem_block_t)); ((ut_mem_block_t*)ret)->size = n + sizeof(ut_mem_block_t); ((ut_mem_block_t*)ret)->magic_n = UT_MEM_MAGIC_N; return((void*)((byte*)ret + sizeof(ut_mem_block_t)));
mallocされた領域の先頭にはut_mem_block_t構造体があるが、返されるアドレスはこのサイズ分進めたものが返される。
581行目にて、ブロックのためのメモリ割り当て。
buf_pool->blocks = ut_malloc(sizeof(buf_block_t) * max_size);
これで「ブロック=各Pageに割り当てられる制御用の構造体」ということが確定的に。
ちなみにbuf_pool_tのサイズは304バイト、buf_block_tのサイズは344バイト。
595行目。innodb_buffer_poolの先頭アドレスをUNIV_PAGE_SIZEで割り切れる値に切り上げている。
frame = ut_align(buf_pool->frame_mem, UNIV_PAGE_SIZE);
os_mem_alloc_large関数に引数を渡すときに+1をしていたのはこのためか。
frame_zeroは1番目のフレームの先頭アドレス。high_endは最後のフレームの終端アドレス+1。
buf_pool->frame_zero = frame; buf_pool->high_end = frame + UNIV_PAGE_SIZE * n_frames;
612行目。blocks_of_framesはbuf_block_tへのポインタのポインタ。
buf_pool->blocks_of_frames = ut_malloc(sizeof(void*) * n_frames);
624行目。全てのページを初期化。
for (i = 0; i < max_size; i++) { block = buf_pool_get_nth_block(buf_pool, i); if (i < n_frames) { frame = buf_pool->frame_zero + i * UNIV_PAGE_SIZE; *(buf_pool->blocks_of_frames + i) = block; } else { frame = NULL; } buf_block_init(block, frame); ... }
buf_pool_get_nth_block関数は、第一引数のbuf_poolから第2引数で指定された番目のblockを返す関数。
645行目。
buf_pool->page_hash = hash_create(2 * max_size);
page_hashは各ページへのハッシュ値?
hash_table_t* page_hash; /* hash table of the file pages */
687行目。初期処理なので全てのブロックをフリーリストに追加。
/* Add control blocks to the free list */ UT_LIST_INIT(buf_pool->free); for (i = 0; i < curr_size; i++) { block = buf_pool_get_nth_block(buf_pool, i); ... UT_LIST_ADD_LAST(free, buf_pool->free, block); block->in_free_list = TRUE; }
716行目。最後に検索用のbtreeらしきものを作成している。デフォルト(buffer pool=8MB)の時、この関数の引数は32768になっている。
btr_search_sys_create(curr_size * UNIV_PAGE_SIZE / sizeof(void*) / 64);