📄 ibuf0ibuf.c
字号:
ut_ad(n_used >= 2); data->seg_size = n_used; root = buf_page_get(space, FSP_IBUF_TREE_ROOT_PAGE_NO, RW_X_LATCH, &mtr);#ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(root, SYNC_TREE_NODE);#endif /* UNIV_SYNC_DEBUG */ data->size = 0; data->n_inserts = 0; data->n_merges = 0; data->n_merged_recs = 0; ibuf_data_sizes_update(data, root, &mtr);/* if (!data->empty) { fprintf(stderr,"InnoDB: index entries found in the insert buffer\n"); } else { fprintf(stderr,"InnoDB: insert buffer empty\n"); }*/ mutex_exit(&ibuf_mutex); mtr_commit(&mtr); ibuf_exit(); sprintf(buf, "SYS_IBUF_TABLE_%lu", (ulong) space); /* use old-style record format for the insert buffer */ table = dict_mem_table_create(buf, space, 2, FALSE); dict_mem_table_add_col(table, "PAGE_NO", DATA_BINARY, 0, 0, 0); dict_mem_table_add_col(table, "TYPES", DATA_BINARY, 0, 0, 0); table->id = ut_dulint_add(DICT_IBUF_ID_MIN, space); dict_table_add_to_cache(table); index = dict_mem_index_create(buf, "CLUST_IND", space, DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,2); dict_mem_index_add_field(index, "PAGE_NO", 0, 0); dict_mem_index_add_field(index, "TYPES", 0, 0); index->id = ut_dulint_add(DICT_IBUF_ID_MIN, space); dict_index_add_to_cache(table, index, FSP_IBUF_TREE_ROOT_PAGE_NO); data->index = dict_table_get_first_index(table); mutex_enter(&ibuf_mutex); UT_LIST_ADD_LAST(data_list, ibuf->data_list, data); mutex_exit(&ibuf_mutex); return(data);}/*************************************************************************Initializes an ibuf bitmap page. */voidibuf_bitmap_page_init(/*==================*/ page_t* page, /* in: bitmap page */ mtr_t* mtr) /* in: mtr */{ ulint bit_offset; ulint byte_offset; ulint i; /* Write all zeros to the bitmap */ bit_offset = XDES_DESCRIBED_PER_PAGE * IBUF_BITS_PER_PAGE; byte_offset = bit_offset / 8 + 1; for (i = IBUF_BITMAP; i < IBUF_BITMAP + byte_offset; i++) { *(page + i) = (byte)0; } mlog_write_initial_log_record(page, MLOG_IBUF_BITMAP_INIT, mtr);}/*************************************************************************Parses a redo log record of an ibuf bitmap page init. */byte*ibuf_parse_bitmap_init(/*===================*/ /* out: end of log record or NULL */ byte* ptr, /* in: buffer */ byte* end_ptr __attribute__((unused)), /* in: buffer end */ page_t* page, /* in: page or NULL */ mtr_t* mtr) /* in: mtr or NULL */{ ut_ad(ptr && end_ptr); if (page) { ibuf_bitmap_page_init(page, mtr); } return(ptr);}/************************************************************************Gets the desired bits for a given page from a bitmap page. */UNIV_INLINEulintibuf_bitmap_page_get_bits(/*======================*/ /* out: value of bits */ page_t* page, /* in: bitmap page */ ulint page_no,/* in: page whose bits to get */ ulint bit, /* in: IBUF_BITMAP_FREE, IBUF_BITMAP_BUFFERED, ... */ mtr_t* mtr __attribute__((unused))) /* in: mtr containing an x-latch to the bitmap page */{ ulint byte_offset; ulint bit_offset; ulint map_byte; ulint value; ut_ad(bit < IBUF_BITS_PER_PAGE); ut_ad(IBUF_BITS_PER_PAGE % 2 == 0); ut_ad(mtr_memo_contains(mtr, buf_block_align(page), MTR_MEMO_PAGE_X_FIX)); bit_offset = (page_no % XDES_DESCRIBED_PER_PAGE) * IBUF_BITS_PER_PAGE + bit; byte_offset = bit_offset / 8; bit_offset = bit_offset % 8; ut_ad(byte_offset + IBUF_BITMAP < UNIV_PAGE_SIZE); map_byte = mach_read_from_1(page + IBUF_BITMAP + byte_offset); value = ut_bit_get_nth(map_byte, bit_offset); if (bit == IBUF_BITMAP_FREE) { ut_ad(bit_offset + 1 < 8); value = value * 2 + ut_bit_get_nth(map_byte, bit_offset + 1); } return(value);}/************************************************************************Sets the desired bit for a given page in a bitmap page. */staticvoidibuf_bitmap_page_set_bits(/*======================*/ page_t* page, /* in: bitmap page */ ulint page_no,/* in: page whose bits to set */ ulint bit, /* in: IBUF_BITMAP_FREE, IBUF_BITMAP_BUFFERED, ... */ ulint val, /* in: value to set */ mtr_t* mtr) /* in: mtr containing an x-latch to the bitmap page */{ ulint byte_offset; ulint bit_offset; ulint map_byte; ut_ad(bit < IBUF_BITS_PER_PAGE); ut_ad(IBUF_BITS_PER_PAGE % 2 == 0); ut_ad(mtr_memo_contains(mtr, buf_block_align(page), MTR_MEMO_PAGE_X_FIX));#ifdef UNIV_IBUF_DEBUG ut_a((bit != IBUF_BITMAP_BUFFERED) || (val != FALSE) || (0 == ibuf_count_get(buf_frame_get_space_id(page), page_no)));#endif bit_offset = (page_no % XDES_DESCRIBED_PER_PAGE) * IBUF_BITS_PER_PAGE + bit; byte_offset = bit_offset / 8; bit_offset = bit_offset % 8; ut_ad(byte_offset + IBUF_BITMAP < UNIV_PAGE_SIZE); map_byte = mach_read_from_1(page + IBUF_BITMAP + byte_offset); if (bit == IBUF_BITMAP_FREE) { ut_ad(bit_offset + 1 < 8); ut_ad(val <= 3); map_byte = ut_bit_set_nth(map_byte, bit_offset, val / 2); map_byte = ut_bit_set_nth(map_byte, bit_offset + 1, val % 2); } else { ut_ad(val <= 1); map_byte = ut_bit_set_nth(map_byte, bit_offset, val); } mlog_write_ulint(page + IBUF_BITMAP + byte_offset, map_byte, MLOG_1BYTE, mtr);}/************************************************************************Calculates the bitmap page number for a given page number. */UNIV_INLINEulintibuf_bitmap_page_no_calc(/*=====================*/ /* out: the bitmap page number where the file page is mapped */ ulint page_no) /* in: tablespace page number */{ return(FSP_IBUF_BITMAP_OFFSET + XDES_DESCRIBED_PER_PAGE * (page_no / XDES_DESCRIBED_PER_PAGE));}/************************************************************************Gets the ibuf bitmap page where the bits describing a given file page arestored. */staticpage_t*ibuf_bitmap_get_map_page(/*=====================*/ /* out: bitmap page where the file page is mapped, that is, the bitmap page containing the descriptor bits for the file page; the bitmap page is x-latched */ ulint space, /* in: space id of the file page */ ulint page_no,/* in: page number of the file page */ mtr_t* mtr) /* in: mtr */{ page_t* page; page = buf_page_get(space, ibuf_bitmap_page_no_calc(page_no), RW_X_LATCH, mtr);#ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(page, SYNC_IBUF_BITMAP);#endif /* UNIV_SYNC_DEBUG */ return(page);}/****************************************************************************Sets the free bits of the page in the ibuf bitmap. This is done in a separatemini-transaction, hence this operation does not restrict further work to onlyibuf bitmap operations, which would result if the latch to the bitmap pagewere kept. */UNIV_INLINEvoidibuf_set_free_bits_low(/*===================*/ ulint type, /* in: index type */ page_t* page, /* in: index page; free bit is set if the index is non-clustered and page level is 0 */ ulint val, /* in: value to set: < 4 */ mtr_t* mtr) /* in: mtr */{ page_t* bitmap_page; if (type & DICT_CLUSTERED) { return; } if (btr_page_get_level_low(page) != 0) { return; } bitmap_page = ibuf_bitmap_get_map_page(buf_frame_get_space_id(page), buf_frame_get_page_no(page), mtr);#ifdef UNIV_IBUF_DEBUG /* fprintf(stderr, "Setting page no %lu free bits to %lu should be %lu\n", buf_frame_get_page_no(page), val, ibuf_index_page_calc_free(page)); */ ut_a(val <= ibuf_index_page_calc_free(page));#endif ibuf_bitmap_page_set_bits(bitmap_page, buf_frame_get_page_no(page), IBUF_BITMAP_FREE, val, mtr);}/****************************************************************************Sets the free bit of the page in the ibuf bitmap. This is done in a separatemini-transaction, hence this operation does not restrict further work to onlyibuf bitmap operations, which would result if the latch to the bitmap pagewere kept. */voidibuf_set_free_bits(/*===============*/ ulint type, /* in: index type */ page_t* page, /* in: index page; free bit is set if the index is non-clustered and page level is 0 */ ulint val, /* in: value to set: < 4 */ ulint max_val)/* in: ULINT_UNDEFINED or a maximum value which the bits must have before setting; this is for debugging */{ mtr_t mtr; page_t* bitmap_page; if (type & DICT_CLUSTERED) { return; } if (btr_page_get_level_low(page) != 0) { return; } mtr_start(&mtr); bitmap_page = ibuf_bitmap_get_map_page(buf_frame_get_space_id(page), buf_frame_get_page_no(page), &mtr); if (max_val != ULINT_UNDEFINED) {#ifdef UNIV_IBUF_DEBUG ulint old_val; old_val = ibuf_bitmap_page_get_bits(bitmap_page, buf_frame_get_page_no(page), IBUF_BITMAP_FREE, &mtr); if (old_val != max_val) { /* fprintf(stderr, "Ibuf: page %lu old val %lu max val %lu\n", buf_frame_get_page_no(page), old_val, max_val); */ } ut_a(old_val <= max_val);#endif }#ifdef UNIV_IBUF_DEBUG/* fprintf(stderr, "Setting page no %lu free bits to %lu should be %lu\n", buf_frame_get_page_no(page), val, ibuf_index_page_calc_free(page)); */ ut_a(val <= ibuf_index_page_calc_free(page));#endif ibuf_bitmap_page_set_bits(bitmap_page, buf_frame_get_page_no(page), IBUF_BITMAP_FREE, val, &mtr); mtr_commit(&mtr);}/****************************************************************************Resets the free bits of the page in the ibuf bitmap. This is done in aseparate mini-transaction, hence this operation does not restrict furtherwork to only ibuf bitmap operations, which would result if the latch to thebitmap page were kept. */voidibuf_reset_free_bits_with_type(/*===========================*/ ulint type, /* in: index type */ page_t* page) /* in: index page; free bits are set to 0 if the index is non-clustered and non-unique and the page level is 0 */{ ibuf_set_free_bits(type, page, 0, ULINT_UNDEFINED);}/****************************************************************************Resets the free bits of the page in the ibuf bitmap. This is done in aseparate mini-transaction, hence this operation does not restrict furtherwork to solely ibuf bitmap operations, which would result if the latch tothe bitmap page were kept. */voidibuf_reset_free_bits(/*=================*/ dict_index_t* index, /* in: index */ page_t* page) /* in: index page; free bits are set to 0 if the index is non-clustered and non-unique and the page level is 0 */{ ibuf_set_free_bits(index->type, page, 0, ULINT_UNDEFINED);}/**************************************************************************Updates the free bits for a page to reflect the present state. Does thisin the mtr given, which means that the latching order rules virtually preventany further operations for this OS thread until mtr is committed. */voidibuf_update_free_bits_low(/*======================*/ dict_index_t* index, /* in: index */ page_t* page, /* in: index page */ ulint max_ins_size, /* in: value of maximum insert size with reorganize before the latest operation performed to the page */ mtr_t* mtr) /* in: mtr */{ ulint before; ulint after; before = ibuf_index_page_calc_free_bits(max_ins_size); after = ibuf_index_page_calc_free(page); if (before != after) { ibuf_set_free_bits_low(index->type, page, after, mtr); }}/**************************************************************************Updates the free bits for the two pages to reflect the present state. Doesthis in the mtr given, which means that the latching order rules virtuallyprevent any further operations until mtr is committed. */voidibuf_update_free_bits_for_two_pages_low(/*====================================*/ dict_index_t* index, /* in: index */ page_t* page1, /* in: index page */ page_t* page2, /* in: index page */ mtr_t* mtr) /* in: mtr */{ ulint state; /* As we have to x-latch two random bitmap pages, we have to acquire the bitmap mutex to prevent a deadlock with a similar operation performed by another OS thread. */ mutex_enter(&ibuf_bitmap_mutex); state = ibuf_index_page_calc_free(page1); ibuf_set_free_bits_low(index->type, page1, state, mtr); state = ibuf_index_page_calc_free(page2); ibuf_set_free_bits_low(index->type, page2, state, mtr); mutex_exit(&ibuf_bitmap_mutex);}/**************************************************************************Returns TRUE if the page is one of the fixed address ibuf pages. */UNIV_INLINEiboolibuf_fixed_addr_page(/*=================*/ /* out: TRUE if a fixed address ibuf i/o page */ ulint page_no)/* in: page number */{ if ((ibuf_bitmap_page(page_no)) || (page_no == IBUF_TREE_ROOT_PAGE_NO)) { return(TRUE); } return(FALSE);}/***************************************************************************Checks if a page is a level 2 or 3 page in the ibuf hierarchy of pages. */iboolibuf_page(/*======*/ /* out: TRUE if level 2 or level 3 page */ ulint space, /* in: space id */ ulint page_no)/* in: page number */{ page_t* bitmap_page; mtr_t mtr; ibool ret; if (recv_no_ibuf_operations) { /* Recovery is running: no ibuf operations should be performed */ return(FALSE); } if (ibuf_fixed_addr_page(page_no)) { return(TRUE); } if (space != 0) { /* Currently we only have an ibuf tree in space 0 */ return(FALSE); } ut_ad(fil_space_get_type(space) == FIL_TABLESPACE); mtr_start(&mtr); bitmap_page = ibuf_bitmap_get_map_page(space, page_no, &mtr); ret = ibuf_bitmap_page_get_bits(bitmap_page, page_no, IBUF_BITMAP_IBUF, &mtr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -