📄 buf0buf.c
字号:
/* NOTE that the call to ibuf may have moved the ownership of the x-latch to this OS thread: do not let this confuse you in debugging! */ ut_ad(buf_pool->n_pend_reads > 0); buf_pool->n_pend_reads--; buf_pool->n_pages_read++; rw_lock_x_unlock_gen(&(block->lock), BUF_IO_READ);#ifdef UNIV_DEBUG if (buf_debug_prints) { fputs("Has read ", stderr); }#endif /* UNIV_DEBUG */ } else { ut_ad(io_type == BUF_IO_WRITE); /* Write means a flush operation: call the completion routine in the flush system */ buf_flush_write_complete(block); rw_lock_s_unlock_gen(&(block->lock), BUF_IO_WRITE); buf_pool->n_pages_written++;#ifdef UNIV_DEBUG if (buf_debug_prints) { fputs("Has written ", stderr); }#endif /* UNIV_DEBUG */ } mutex_exit(&(buf_pool->mutex));#ifdef UNIV_DEBUG if (buf_debug_prints) { fprintf(stderr, "page space %lu page no %lu\n", (ulong) block->space, (ulong) block->offset); }#endif /* UNIV_DEBUG */}/*************************************************************************Invalidates the file pages in the buffer pool when an archive recovery iscompleted. All the file pages buffered must be in a replaceable state whenthis function is called: not latched and not modified. */voidbuf_pool_invalidate(void)/*=====================*/{ ibool freed; ut_ad(buf_all_freed()); freed = TRUE; while (freed) { freed = buf_LRU_search_and_free_block(100); } mutex_enter(&(buf_pool->mutex)); ut_ad(UT_LIST_GET_LEN(buf_pool->LRU) == 0); mutex_exit(&(buf_pool->mutex));}#ifdef UNIV_DEBUG/*************************************************************************Validates the buffer buf_pool data structure. */iboolbuf_validate(void)/*==============*/{ buf_block_t* block; ulint i; ulint n_single_flush = 0; ulint n_lru_flush = 0; ulint n_list_flush = 0; ulint n_lru = 0; ulint n_flush = 0; ulint n_free = 0; ulint n_page = 0; ut_ad(buf_pool); mutex_enter(&(buf_pool->mutex)); for (i = 0; i < buf_pool->curr_size; i++) { block = buf_pool_get_nth_block(buf_pool, i); if (block->state == BUF_BLOCK_FILE_PAGE) { ut_a(buf_page_hash_get(block->space, block->offset) == block); n_page++;#ifdef UNIV_IBUF_DEBUG ut_a((block->io_fix == BUF_IO_READ) || ibuf_count_get(block->space, block->offset) == 0);#endif if (block->io_fix == BUF_IO_WRITE) { if (block->flush_type == BUF_FLUSH_LRU) { n_lru_flush++; ut_a(rw_lock_is_locked(&(block->lock), RW_LOCK_SHARED)); } else if (block->flush_type == BUF_FLUSH_LIST) { n_list_flush++; } else if (block->flush_type == BUF_FLUSH_SINGLE_PAGE) { n_single_flush++; } else { ut_error; } } else if (block->io_fix == BUF_IO_READ) { ut_a(rw_lock_is_locked(&(block->lock), RW_LOCK_EX)); } n_lru++; if (ut_dulint_cmp(block->oldest_modification, ut_dulint_zero) > 0) { n_flush++; } } else if (block->state == BUF_BLOCK_NOT_USED) { n_free++; } } if (n_lru + n_free > buf_pool->curr_size) { fprintf(stderr, "n LRU %lu, n free %lu\n", (ulong) n_lru, (ulong) n_free); ut_error; } ut_a(UT_LIST_GET_LEN(buf_pool->LRU) == n_lru); if (UT_LIST_GET_LEN(buf_pool->free) != n_free) { fprintf(stderr, "Free list len %lu, free blocks %lu\n", (ulong) UT_LIST_GET_LEN(buf_pool->free), (ulong) n_free); ut_error; } ut_a(UT_LIST_GET_LEN(buf_pool->flush_list) == n_flush); ut_a(buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE] == n_single_flush); ut_a(buf_pool->n_flush[BUF_FLUSH_LIST] == n_list_flush); ut_a(buf_pool->n_flush[BUF_FLUSH_LRU] == n_lru_flush); mutex_exit(&(buf_pool->mutex)); ut_a(buf_LRU_validate()); ut_a(buf_flush_validate()); return(TRUE);} /*************************************************************************Prints info of the buffer buf_pool data structure. */voidbuf_print(void)/*===========*/{ dulint* index_ids; ulint* counts; ulint size; ulint i; ulint j; dulint id; ulint n_found; buf_frame_t* frame; dict_index_t* index; ut_ad(buf_pool); size = buf_pool->curr_size; index_ids = mem_alloc(sizeof(dulint) * size); counts = mem_alloc(sizeof(ulint) * size); mutex_enter(&(buf_pool->mutex)); fprintf(stderr, "buf_pool size %lu\n" "database pages %lu\n" "free pages %lu\n" "modified database pages %lu\n" "n pending reads %lu\n" "n pending flush LRU %lu list %lu single page %lu\n" "pages read %lu, created %lu, written %lu\n", (ulong) size, (ulong) UT_LIST_GET_LEN(buf_pool->LRU), (ulong) UT_LIST_GET_LEN(buf_pool->free), (ulong) UT_LIST_GET_LEN(buf_pool->flush_list), (ulong) buf_pool->n_pend_reads, (ulong) buf_pool->n_flush[BUF_FLUSH_LRU], (ulong) buf_pool->n_flush[BUF_FLUSH_LIST], (ulong) buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE], (ulong) buf_pool->n_pages_read, buf_pool->n_pages_created, (ulong) buf_pool->n_pages_written); /* Count the number of blocks belonging to each index in the buffer */ n_found = 0; for (i = 0; i < size; i++) { frame = buf_pool_get_nth_block(buf_pool, i)->frame; if (fil_page_get_type(frame) == FIL_PAGE_INDEX) { id = btr_page_get_index_id(frame); /* Look for the id in the index_ids array */ j = 0; while (j < n_found) { if (ut_dulint_cmp(index_ids[j], id) == 0) { (counts[j])++; break; } j++; } if (j == n_found) { n_found++; index_ids[j] = id; counts[j] = 1; } } } mutex_exit(&(buf_pool->mutex)); for (i = 0; i < n_found; i++) { index = dict_index_get_if_in_cache(index_ids[i]); fprintf(stderr, "Block count for index %lu in buffer is about %lu", (ulong) ut_dulint_get_low(index_ids[i]), (ulong) counts[i]); if (index) { putc(' ', stderr); dict_index_name_print(stderr, NULL, index); } putc('\n', stderr); } mem_free(index_ids); mem_free(counts); ut_a(buf_validate());} #endif /* UNIV_DEBUG *//*************************************************************************Returns the number of latched pages in the buffer pool. */ulintbuf_get_latched_pages_number(void){ buf_block_t* block; ulint i; ulint fixed_pages_number = 0; mutex_enter(&(buf_pool->mutex)); for (i = 0; i < buf_pool->curr_size; i++) { block = buf_pool_get_nth_block(buf_pool, i); if (((block->buf_fix_count != 0) || (block->io_fix != 0)) && block->magic_n == BUF_BLOCK_MAGIC_N ) fixed_pages_number++; } mutex_exit(&(buf_pool->mutex)); return fixed_pages_number;}/*************************************************************************Returns the number of pending buf pool ios. */ulintbuf_get_n_pending_ios(void)/*=======================*/{ return(buf_pool->n_pend_reads + buf_pool->n_flush[BUF_FLUSH_LRU] + buf_pool->n_flush[BUF_FLUSH_LIST] + buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]);}/*************************************************************************Returns the ratio in percents of modified pages in the buffer pool /database pages in the buffer pool. */ulintbuf_get_modified_ratio_pct(void)/*============================*/{ ulint ratio; mutex_enter(&(buf_pool->mutex)); ratio = (100 * UT_LIST_GET_LEN(buf_pool->flush_list)) / (1 + UT_LIST_GET_LEN(buf_pool->LRU) + UT_LIST_GET_LEN(buf_pool->free)); /* 1 + is there to avoid division by zero */ mutex_exit(&(buf_pool->mutex)); return(ratio);}/*************************************************************************Prints info of the buffer i/o. */voidbuf_print_io(/*=========*/ FILE* file) /* in/out: buffer where to print */{ time_t current_time; double time_elapsed; ulint size; ut_ad(buf_pool); size = buf_pool->curr_size; mutex_enter(&(buf_pool->mutex)); if (srv_use_awe) { fprintf(stderr, "AWE: Buffer pool memory frames %lu\n", (ulong) buf_pool->n_frames); fprintf(stderr, "AWE: Database pages and free buffers mapped in frames %lu\n", (ulong) UT_LIST_GET_LEN(buf_pool->awe_LRU_free_mapped)); } fprintf(file, "Buffer pool size %lu\n" "Free buffers %lu\n" "Database pages %lu\n" "Modified db pages %lu\n" "Pending reads %lu\n" "Pending writes: LRU %lu, flush list %lu, single page %lu\n", (ulong) size, (ulong) UT_LIST_GET_LEN(buf_pool->free), (ulong) UT_LIST_GET_LEN(buf_pool->LRU), (ulong) UT_LIST_GET_LEN(buf_pool->flush_list), (ulong) buf_pool->n_pend_reads, (ulong) buf_pool->n_flush[BUF_FLUSH_LRU] + buf_pool->init_flush[BUF_FLUSH_LRU], (ulong) buf_pool->n_flush[BUF_FLUSH_LIST] + buf_pool->init_flush[BUF_FLUSH_LIST], (ulong) buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]); current_time = time(NULL); time_elapsed = 0.001 + difftime(current_time, buf_pool->last_printout_time); buf_pool->last_printout_time = current_time; fprintf(file, "Pages read %lu, created %lu, written %lu\n" "%.2f reads/s, %.2f creates/s, %.2f writes/s\n", (ulong) buf_pool->n_pages_read, (ulong) buf_pool->n_pages_created, (ulong) buf_pool->n_pages_written, (buf_pool->n_pages_read - buf_pool->n_pages_read_old) / time_elapsed, (buf_pool->n_pages_created - buf_pool->n_pages_created_old) / time_elapsed, (buf_pool->n_pages_written - buf_pool->n_pages_written_old) / time_elapsed); if (srv_use_awe) { fprintf(file, "AWE: %.2f page remaps/s\n", (buf_pool->n_pages_awe_remapped - buf_pool->n_pages_awe_remapped_old) / time_elapsed); } if (buf_pool->n_page_gets > buf_pool->n_page_gets_old) { fprintf(file, "Buffer pool hit rate %lu / 1000\n", (ulong) (1000 - ((1000 * (buf_pool->n_pages_read - buf_pool->n_pages_read_old)) / (buf_pool->n_page_gets - buf_pool->n_page_gets_old)))); } else { fputs("No buffer pool page gets since the last printout\n", file); } buf_pool->n_page_gets_old = buf_pool->n_page_gets; buf_pool->n_pages_read_old = buf_pool->n_pages_read; buf_pool->n_pages_created_old = buf_pool->n_pages_created; buf_pool->n_pages_written_old = buf_pool->n_pages_written; buf_pool->n_pages_awe_remapped_old = buf_pool->n_pages_awe_remapped; mutex_exit(&(buf_pool->mutex));}/**************************************************************************Refreshes the statistics used to print per-second averages. */voidbuf_refresh_io_stats(void)/*======================*/{ buf_pool->last_printout_time = time(NULL); buf_pool->n_page_gets_old = buf_pool->n_page_gets; buf_pool->n_pages_read_old = buf_pool->n_pages_read; buf_pool->n_pages_created_old = buf_pool->n_pages_created; buf_pool->n_pages_written_old = buf_pool->n_pages_written; buf_pool->n_pages_awe_remapped_old = buf_pool->n_pages_awe_remapped; }/*************************************************************************Checks that all file pages in the buffer are in a replaceable state. */iboolbuf_all_freed(void)/*===============*/{ buf_block_t* block; ulint i; ut_ad(buf_pool); mutex_enter(&(buf_pool->mutex)); for (i = 0; i < buf_pool->curr_size; i++) { block = buf_pool_get_nth_block(buf_pool, i); if (block->state == BUF_BLOCK_FILE_PAGE) { if (!buf_flush_ready_for_replace(block)) { fprintf(stderr, "Page %lu %lu still fixed or dirty\n", (ulong) block->space, (ulong) block->offset); ut_error; } } } mutex_exit(&(buf_pool->mutex)); return(TRUE);} /*************************************************************************Checks that there currently are no pending i/o-operations for the bufferpool. */iboolbuf_pool_check_no_pending_io(void)/*==============================*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -