28 #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
29 UNIV_INTERN my_bool srv_ibuf_disable_background_merge;
33 #define IBUF_BITS_PER_PAGE 4
34 #if IBUF_BITS_PER_PAGE % 2
35 # error "IBUF_BITS_PER_PAGE must be an even number!"
38 #define IBUF_BITMAP PAGE_DATA
41 #include "ibuf0ibuf.ic"
44 #ifndef UNIV_HOTBACKUP
193 #define IBUF_TABLE_NAME "SYS_IBUF_TABLE"
198 #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
200 UNIV_INTERN uint ibuf_debug;
204 UNIV_INTERN ibuf_t*
ibuf = NULL;
206 #ifdef UNIV_PFS_MUTEX
207 UNIV_INTERN mysql_pfs_key_t ibuf_pessimistic_insert_mutex_key;
208 UNIV_INTERN mysql_pfs_key_t ibuf_mutex_key;
209 UNIV_INTERN mysql_pfs_key_t ibuf_bitmap_mutex_key;
212 #ifdef UNIV_IBUF_COUNT_DEBUG
214 #define IBUF_COUNT_N_SPACES 4
216 #define IBUF_COUNT_N_PAGES 130000
219 static ulint ibuf_counts[IBUF_COUNT_N_SPACES][IBUF_COUNT_N_PAGES];
230 if (space_id < IBUF_COUNT_N_SPACES && page_no < IBUF_COUNT_N_PAGES) {
235 "InnoDB: UNIV_IBUF_COUNT_DEBUG limits space_id and page_no\n"
236 "InnoDB: and breaks crash recovery.\n"
237 "InnoDB: space_id=%lu, should be 0<=space_id<%lu\n"
238 "InnoDB: page_no=%lu, should be 0<=page_no<%lu\n",
239 (ulint) space_id, (ulint) IBUF_COUNT_N_SPACES,
240 (ulint) page_no, (ulint) IBUF_COUNT_N_PAGES);
247 #define IBUF_BITMAP_FREE 0
249 #define IBUF_BITMAP_BUFFERED 2
251 #define IBUF_BITMAP_IBUF 3
257 #define IBUF_REC_FIELD_SPACE 0
259 #define IBUF_REC_FIELD_MARKER 1
261 #define IBUF_REC_FIELD_PAGE 2
263 #define IBUF_REC_FIELD_METADATA 3
264 #define IBUF_REC_FIELD_USER 4
274 #define IBUF_REC_INFO_SIZE 4
276 #if IBUF_REC_INFO_SIZE >= DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
277 # error "IBUF_REC_INFO_SIZE >= DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE"
281 #define IBUF_REC_OFFSET_COUNTER 0
282 #define IBUF_REC_OFFSET_TYPE 2
283 #define IBUF_REC_OFFSET_FLAGS 3
286 #define IBUF_REC_COMPACT 0x1
293 static ib_mutex_t ibuf_pessimistic_insert_mutex;
302 #define IBUF_MERGE_AREA 8UL
307 #define IBUF_MERGE_THRESHOLD 4
311 #define IBUF_MAX_N_PAGES_MERGED IBUF_MERGE_AREA
316 #define IBUF_CONTRACT_ON_INSERT_NON_SYNC 0
321 #define IBUF_CONTRACT_ON_INSERT_SYNC 5
326 #define IBUF_CONTRACT_DO_NOT_INSERT 10
379 ibuf_header_page_get(
388 IBUF_SPACE_ID, 0, FSP_IBUF_HEADER_PAGE_NO, RW_X_LATCH, mtr);
389 buf_block_dbg_add_level(block, SYNC_IBUF_HEADER);
391 return(buf_block_get_frame(block));
407 ut_ad(mutex_own(&ibuf_mutex));
412 IBUF_SPACE_ID, 0, FSP_IBUF_TREE_ROOT_PAGE_NO, RW_X_LATCH, mtr);
414 buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW);
416 root = buf_block_get_frame(block);
425 #ifdef UNIV_IBUF_COUNT_DEBUG
437 ibuf_count_check(space, page_no);
439 return(ibuf_counts[space][page_no]);
452 ibuf_count_check(space, page_no);
453 ut_a(val < UNIV_PAGE_SIZE);
455 ibuf_counts[
space][page_no] = val;
466 mutex_free(&ibuf_pessimistic_insert_mutex);
467 memset(&ibuf_pessimistic_insert_mutex,
468 0x0,
sizeof(ibuf_pessimistic_insert_mutex));
470 mutex_free(&ibuf_mutex);
471 memset(&ibuf_mutex, 0x0,
sizeof(ibuf_mutex));
473 mutex_free(&ibuf_bitmap_mutex);
474 memset(&ibuf_bitmap_mutex, 0x0,
sizeof(ibuf_mutex));
490 ut_ad(mutex_own(&ibuf_mutex));
493 + PAGE_BTR_IBUF_FREE_LIST, mtr);
495 ibuf->height = 1 + btr_page_get_level(root, mtr);
498 ibuf->size =
ibuf->seg_size - (1 +
ibuf->free_list_len);
528 mutex_create(ibuf_pessimistic_insert_mutex_key,
529 &ibuf_pessimistic_insert_mutex,
530 SYNC_IBUF_PESS_INSERT_MUTEX);
532 mutex_create(ibuf_mutex_key,
533 &ibuf_mutex, SYNC_IBUF_MUTEX);
535 mutex_create(ibuf_bitmap_mutex_key,
536 &ibuf_bitmap_mutex, SYNC_IBUF_BITMAP_MUTEX);
540 mutex_enter(&ibuf_mutex);
544 header_page = ibuf_header_page_get(&mtr);
552 ibuf->seg_size = n_used;
558 IBUF_SPACE_ID, 0, FSP_IBUF_TREE_ROOT_PAGE_NO,
560 buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
562 root = buf_block_get_frame(block);
565 ibuf_size_update(root, &mtr);
566 mutex_exit(&ibuf_mutex);
578 table->
id = DICT_IBUF_ID_MIN + IBUF_SPACE_ID;
589 index->
id = DICT_IBUF_ID_MIN + IBUF_SPACE_ID;
592 FSP_IBUF_TREE_ROOT_PAGE_NO, FALSE);
593 ut_a(error == DB_SUCCESS);
595 ibuf->index = dict_table_get_first_index(table);
609 mutex_enter(&ibuf_mutex);
610 ibuf->max_size = new_size;
611 mutex_exit(&ibuf_mutex);
631 page = buf_block_get_frame(block);
647 #ifndef UNIV_HOTBACKUP
660 byte* end_ptr __attribute__((unused)),
664 ut_ad(ptr && end_ptr);
672 #ifndef UNIV_HOTBACKUP
681 # define ibuf_bitmap_page_get_bits(page, offset, zs, bit, mtr) \
682 ibuf_bitmap_page_get_bits_low(page, offset, zs, \
683 MTR_MEMO_PAGE_X_FIX, mtr, bit)
692 # define ibuf_bitmap_page_get_bits(page, offset, zs, bit, mtr) \
693 ibuf_bitmap_page_get_bits_low(page, offset, zs, bit)
723 #if IBUF_BITS_PER_PAGE % 2
724 # error "IBUF_BITS_PER_PAGE % 2 != 0"
727 ut_ad(mtr_memo_contains_page(mtr, page, latch_type));
737 byte_offset = bit_offset / 8;
738 bit_offset = bit_offset % 8;
747 ut_ad(bit_offset + 1 < 8);
759 ibuf_bitmap_page_set_bits(
774 #if IBUF_BITS_PER_PAGE % 2
775 # error "IBUF_BITS_PER_PAGE % 2 != 0"
778 ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX));
779 #ifdef UNIV_IBUF_COUNT_DEBUG
792 byte_offset = bit_offset / 8;
793 bit_offset = bit_offset % 8;
800 ut_ad(bit_offset + 1 < 8);
828 return(FSP_IBUF_BITMAP_OFFSET
829 + (page_no & ~(UNIV_PAGE_SIZE - 1)));
831 return(FSP_IBUF_BITMAP_OFFSET
832 + (page_no & ~(zip_size - 1)));
844 ibuf_bitmap_get_map_page_func(
860 buf_block_dbg_add_level(block, SYNC_IBUF_BITMAP);
862 return(buf_block_get_frame(block));
875 #define ibuf_bitmap_get_map_page(space, page_no, zip_size, mtr) \
876 ibuf_bitmap_get_map_page_func(space, page_no, zip_size, \
877 __FILE__, __LINE__, mtr)
908 #ifdef UNIV_IBUF_DEBUG
911 "Setting space %lu page %lu free bits to %lu should be %lu\n",
913 ibuf_index_page_calc_free(zip_size, block));
916 ut_a(val <= ibuf_index_page_calc_free(zip_size, block));
918 ibuf_bitmap_page_set_bits(bitmap_page, page_no, zip_size,
933 #ifdef UNIV_IBUF_DEBUG
947 page = buf_block_get_frame(block);
961 #ifdef UNIV_IBUF_DEBUG
962 if (max_val != ULINT_UNDEFINED) {
966 bitmap_page, page_no, zip_size,
969 if (old_val != max_val) {
971 "Ibuf: page %lu old val %lu max val %lu\n",
977 ut_a(old_val <= max_val);
980 fprintf(stderr,
"Setting page no %lu free bits to %lu should be %lu\n",
982 ibuf_index_page_calc_free(zip_size, block));
985 ut_a(val <= ibuf_index_page_calc_free(zip_size, block));
987 ibuf_bitmap_page_set_bits(bitmap_page, page_no, zip_size,
1009 ibuf_set_free_bits(block, 0, ULINT_UNDEFINED);
1037 before = ibuf_index_page_calc_free_bits(0, max_ins_size);
1039 after = ibuf_index_page_calc_free(0, block);
1045 if (before != after) {
1080 after = ibuf_index_page_calc_free_zip(zip_size, block);
1091 ibuf_bitmap_page_set_bits(bitmap_page, page_no, zip_size,
1118 mutex_enter(&ibuf_bitmap_mutex);
1120 state = ibuf_index_page_calc_free(zip_size, block1);
1124 state = ibuf_index_page_calc_free(zip_size, block2);
1128 mutex_exit(&ibuf_bitmap_mutex);
1143 return((space == IBUF_SPACE_ID && page_no == IBUF_TREE_ROOT_PAGE_NO)
1175 ut_ad(x_latch || mtr == NULL);
1180 }
else if (space != IBUF_SPACE_ID) {
1202 bitmap_page = buf_block_get_frame(
1207 file, line, &local_mtr));
1210 bitmap_page, page_no, zip_size,
1223 bitmap_page = ibuf_bitmap_get_map_page_func(space, page_no, zip_size,
1229 if (mtr == &local_mtr) {
1237 # define ibuf_rec_get_page_no(mtr,rec) ibuf_rec_get_page_no_func(mtr,rec)
1239 # define ibuf_rec_get_page_no(mtr,rec) ibuf_rec_get_page_no_func(rec)
1247 ibuf_rec_get_page_no_func(
1257 ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
1258 || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
1274 # define ibuf_rec_get_space(mtr,rec) ibuf_rec_get_space_func(mtr,rec)
1276 # define ibuf_rec_get_space(mtr,rec) ibuf_rec_get_space_func(rec)
1285 ibuf_rec_get_space_func(
1295 ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
1296 || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
1312 # define ibuf_rec_get_info(mtr,rec,op,comp,info_len,counter) \
1313 ibuf_rec_get_info_func(mtr,rec,op,comp,info_len,counter)
1315 # define ibuf_rec_get_info(mtr,rec,op,comp,info_len,counter) \
1316 ibuf_rec_get_info_func(rec,op,comp,info_len,counter)
1322 ibuf_rec_get_info_func(
1342 ulint info_len_local;
1343 ulint counter_local;
1345 ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
1346 || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
1349 ut_a(fields > IBUF_REC_FIELD_USER);
1351 types = rec_get_nth_field_old(rec, IBUF_REC_FIELD_METADATA, &len);
1353 info_len_local = len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE;
1355 switch (info_len_local) {
1358 op_local = IBUF_OP_INSERT;
1359 comp_local = info_len_local;
1361 counter_local = ULINT_UNDEFINED;
1375 ut_a(op_local < IBUF_OP_COUNT);
1376 ut_a((len - info_len_local) ==
1377 (fields - IBUF_REC_FIELD_USER)
1378 * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
1389 *info_len = info_len_local;
1393 *counter = counter_local;
1398 # define ibuf_rec_get_op_type(mtr,rec) ibuf_rec_get_op_type_func(mtr,rec)
1400 # define ibuf_rec_get_op_type(mtr,rec) ibuf_rec_get_op_type_func(rec)
1408 ibuf_rec_get_op_type_func(
1417 ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
1418 || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
1427 return(IBUF_OP_INSERT);
1431 ibuf_rec_get_info(mtr, rec, &op, NULL, NULL, NULL);
1453 return(ULINT_UNDEFINED);
1456 ptr = rec_get_nth_field_old(rec, IBUF_REC_FIELD_METADATA, &len);
1463 return(ULINT_UNDEFINED);
1480 #ifndef HAVE_ATOMIC_BUILTINS
1481 ut_ad(mutex_own(&ibuf_mutex));
1484 for (i = 0; i < IBUF_OP_COUNT; i++) {
1485 #ifdef HAVE_ATOMIC_BUILTINS
1486 os_atomic_increment_ulint(&arr[i], ops[i]);
1502 static const char* op_names[] = {
1509 ut_a(UT_ARR_SIZE(op_names) == IBUF_OP_COUNT);
1511 for (i = 0; i < IBUF_OP_COUNT; i++) {
1512 fprintf(file,
"%s %lu%s", op_names[i],
1513 (ulong) ops[i], (i < (IBUF_OP_COUNT - 1)) ?
", " :
"");
1524 ibuf_dummy_index_create(
1537 DICT_HDR_SPACE, 0, n);
1550 ibuf_dummy_index_add_col(
1562 dict_table_get_nth_col(index->
table, i), len);
1568 ibuf_dummy_index_free(
1579 # define ibuf_build_entry_from_ibuf_rec(mtr,ibuf_rec,heap,pindex) \
1580 ibuf_build_entry_from_ibuf_rec_func(mtr,ibuf_rec,heap,pindex)
1582 # define ibuf_build_entry_from_ibuf_rec(mtr,ibuf_rec,heap,pindex) \
1583 ibuf_build_entry_from_ibuf_rec_func(ibuf_rec,heap,pindex)
1604 ibuf_build_entry_from_ibuf_rec_func(
1609 const rec_t* ibuf_rec,
1625 ut_ad(mtr_memo_contains_page(mtr, ibuf_rec, MTR_MEMO_PAGE_X_FIX)
1626 || mtr_memo_contains_page(mtr, ibuf_rec, MTR_MEMO_PAGE_S_FIX));
1639 types = rec_get_nth_field_old(ibuf_rec, IBUF_REC_FIELD_METADATA, &len);
1641 ibuf_rec_get_info(mtr, ibuf_rec, NULL, &comp, &info_len, NULL);
1643 index = ibuf_dummy_index_create(n_fields, comp);
1648 ut_a(len == n_fields * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
1650 for (i = 0; i < n_fields; i++) {
1651 field = dtuple_get_nth_field(tuple, i);
1653 data = rec_get_nth_field_old(
1654 ibuf_rec, i + IBUF_REC_FIELD_USER, &len);
1659 dfield_get_type(field),
1660 types + i * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
1662 ibuf_dummy_index_add_col(index, dfield_get_type(field), len);
1695 field_offset = IBUF_REC_FIELD_USER;
1696 types_offset = DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE;
1698 for (i = 0; i < n_fields; i++) {
1704 if (len != UNIV_SQL_NULL) {
1712 types += types_offset;
1719 # define ibuf_rec_get_volume(mtr,rec) ibuf_rec_get_volume_func(mtr,rec)
1721 # define ibuf_rec_get_volume(mtr,rec) ibuf_rec_get_volume_func(rec)
1731 ibuf_rec_get_volume_func(
1736 const rec_t* ibuf_rec)
1747 ut_ad(mtr_memo_contains_page(mtr, ibuf_rec, MTR_MEMO_PAGE_X_FIX)
1748 || mtr_memo_contains_page(mtr, ibuf_rec, MTR_MEMO_PAGE_S_FIX));
1756 types = rec_get_nth_field_old(
1757 ibuf_rec, IBUF_REC_FIELD_METADATA, &len);
1759 ibuf_rec_get_info(mtr, ibuf_rec, &op, &comp, &info_len, NULL);
1761 if (op == IBUF_OP_DELETE_MARK || op == IBUF_OP_DELETE) {
1775 entry = ibuf_build_entry_from_ibuf_rec(mtr, ibuf_rec,
1776 heap, &dummy_index);
1780 ibuf_dummy_index_free(dummy_index);
1788 - IBUF_REC_FIELD_USER;
1827 ut_ad(counter != ULINT_UNDEFINED || op == IBUF_OP_INSERT);
1828 ut_ad(counter == ULINT_UNDEFINED || counter <= 0xFFFF);
1829 ut_ad(op < IBUF_OP_COUNT);
1842 tuple =
dtuple_create(heap, n_fields + IBUF_REC_FIELD_USER);
1878 if (counter == ULINT_UNDEFINED) {
1881 ut_ad(counter <= 0xFFFF);
1885 ti = type_info =
static_cast<byte*
>(
1888 i + n_fields * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE));
1900 ut_ad(op == IBUF_OP_INSERT);
1914 for (i = 0; i < n_fields; i++) {
1918 field = dtuple_get_nth_field(tuple, i + IBUF_REC_FIELD_USER);
1919 entry_field = dtuple_get_nth_field(entry, i);
1922 ifield = dict_index_get_nth_field(index, i);
1933 ut_ad(fixed_len <= (ulint)
1934 dfield_get_type(entry_field)->len);
1938 ut_ad(fixed_len == (ulint)
1939 dfield_get_type(entry_field)->len);
1945 ti, dfield_get_type(entry_field), fixed_len);
1946 ti += DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE;
1951 field = dtuple_get_nth_field(tuple, IBUF_REC_FIELD_METADATA);
1968 ibuf_search_tuple_build(
2024 ut_ad(mutex_own(&ibuf_mutex));
2032 return(
ibuf->free_list_len >= (
ibuf->size / 2) + 3 *
ibuf->height);
2044 ut_ad(mutex_own(&ibuf_mutex));
2046 return(
ibuf->free_list_len >= 3 + (
ibuf->size / 2) + 3 *
ibuf->height);
2055 ibuf_add_free_page(
void)
2074 header_page = ibuf_header_page_get(&mtr);
2087 header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER, 0, FSP_UP,
2090 if (block == NULL) {
2098 mutex_enter(&ibuf_mutex);
2099 root = ibuf_tree_root_get(&mtr);
2101 buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE_NEW);
2102 page = buf_block_get_frame(block);
2107 page + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, &mtr);
2113 ibuf->free_list_len++;
2121 mutex_exit(&ibuf_mutex);
2123 ibuf_bitmap_page_set_bits(
2136 ibuf_remove_free_page(
void)
2156 header_page = ibuf_header_page_get(&mtr);
2160 mutex_enter(&ibuf_pessimistic_insert_mutex);
2161 mutex_enter(&ibuf_mutex);
2165 mutex_exit(&ibuf_mutex);
2166 mutex_exit(&ibuf_pessimistic_insert_mutex);
2175 root = ibuf_tree_root_get(&mtr2);
2177 mutex_exit(&ibuf_mutex);
2179 page_no =
flst_get_last(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
2196 IBUF_SPACE_ID, page_no, &mtr);
2198 #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
2199 buf_page_reset_file_page_was_freed(IBUF_SPACE_ID, page_no);
2204 mutex_enter(&ibuf_mutex);
2206 root = ibuf_tree_root_get(&mtr);
2209 + PAGE_BTR_IBUF_FREE_LIST, &mtr).page);
2215 IBUF_SPACE_ID, 0, page_no, RW_X_LATCH, &mtr);
2217 buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
2219 page = buf_block_get_frame(block);
2224 flst_remove(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
2225 page + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, &mtr);
2227 mutex_exit(&ibuf_pessimistic_insert_mutex);
2230 ibuf->free_list_len--;
2236 IBUF_SPACE_ID, page_no, zip_size, &mtr);
2238 mutex_exit(&ibuf_mutex);
2240 ibuf_bitmap_page_set_bits(
2243 #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
2244 buf_page_set_file_page_was_freed(IBUF_SPACE_ID, page_no);
2260 #ifdef UNIV_SYNC_DEBUG
2282 for (i = 0; i < 4; i++) {
2284 ibool too_much_free;
2286 mutex_enter(&ibuf_mutex);
2288 mutex_exit(&ibuf_mutex);
2290 if (!too_much_free) {
2294 ibuf_remove_free_page();
2299 # define ibuf_get_merge_page_nos(contract,rec,mtr,ids,vers,pages,n_stored) \
2300 ibuf_get_merge_page_nos_func(contract,rec,mtr,ids,vers,pages,n_stored)
2302 # define ibuf_get_merge_page_nos(contract,rec,mtr,ids,vers,pages,n_stored) \
2303 ibuf_get_merge_page_nos_func(contract,rec,ids,vers,pages,n_stored)
2312 ibuf_get_merge_page_nos_func(
2323 ib_int64_t* space_versions,
2333 ulint prev_space_id;
2334 ulint first_page_no;
2335 ulint first_space_id;
2339 ulint volume_for_page;
2344 ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
2345 || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
2367 first_page_no = ibuf_rec_get_page_no(mtr, rec);
2368 first_space_id = ibuf_rec_get_space(mtr, rec);
2379 rec_page_no = ibuf_rec_get_page_no(mtr, rec);
2380 rec_space_id = ibuf_rec_get_space(mtr, rec);
2382 if (rec_space_id != first_space_id
2389 if (rec_page_no != prev_page_no
2390 || rec_space_id != prev_space_id) {
2394 prev_page_no = rec_page_no;
2395 prev_space_id = rec_space_id;
2409 volume_for_page = 0;
2411 while (*n_stored < limit) {
2418 rec_page_no = ibuf_rec_get_page_no(mtr, rec);
2419 rec_space_id = ibuf_rec_get_space(mtr, rec);
2428 > (ulint) IBUF_TREE_ROOT_PAGE_NO
2429 - (rec_space_id != 0));
2432 #ifdef UNIV_IBUF_DEBUG
2435 if ((rec_space_id != prev_space_id
2436 || rec_page_no != prev_page_no)
2437 && (prev_space_id != 0 || prev_page_no != 0)) {
2440 || (prev_page_no == first_page_no
2441 && prev_space_id == first_space_id)
2444 * 4 * UNIV_PAGE_SIZE
2445 / IBUF_PAGE_SIZE_PER_FREE_SPACE)
2448 space_ids[*n_stored] = prev_space_id;
2449 space_versions[*n_stored]
2451 page_nos[*n_stored] = prev_page_no;
2455 sum_volumes += volume_for_page;
2458 if (rec_space_id != first_space_id
2465 volume_for_page = 0;
2468 if (rec_page_no == 1 && rec_space_id == 0) {
2474 rec_volume = ibuf_rec_get_volume(mtr, rec);
2476 volume_for_page += rec_volume;
2478 prev_page_no = rec_page_no;
2479 prev_space_id = rec_space_id;
2484 #ifdef UNIV_IBUF_DEBUG
2488 fprintf(stderr,
"Ibuf merge batch %lu pages %lu volume\n",
2489 *n_stored, sum_volumes);
2491 return(sum_volumes);
2497 static __attribute__((nonnull, warn_unused_result))
2505 const rec_t* rec = btr_pcur_get_rec(pcur);
2519 static __attribute__((nonnull, warn_unused_result))
2521 ibuf_get_merge_pages(
2528 ib_int64_t* versions,
2536 ut_a(space != ULINT_UNDEFINED);
2540 while ((rec = ibuf_get_user_rec(pcur, mtr)) != 0
2541 && ibuf_rec_get_space(mtr, rec) == space
2542 && *n_pages < limit) {
2544 ulint page_no = ibuf_rec_get_page_no(mtr, rec);
2546 if (*n_pages == 0 || pages[*n_pages - 1] != page_no) {
2547 spaces[*n_pages] =
space;
2548 pages[*n_pages] = page_no;
2549 versions[*n_pages] = version;
2553 volume += ibuf_rec_get_volume(mtr, rec);
2601 == FSP_IBUF_TREE_ROOT_PAGE_NO);
2609 sum_sizes = ibuf_get_merge_page_nos(TRUE,
2610 btr_pcur_get_rec(&pcur), &mtr,
2611 space_ids, space_versions,
2614 fprintf(stderr,
"Ibuf contract sync %lu pages %lu volume %lu\n",
2615 sync, *n_pages, sum_sizes);
2621 sync, space_ids, space_versions, page_nos, *n_pages);
2623 return(sum_sizes + 1);
2629 static __attribute__((warn_unused_result))
2633 table_id_t table_id)
2660 dtuple_t* tuple = ibuf_search_tuple_build(space, 0, heap);
2674 ulint sum_sizes = 0;
2687 == FSP_IBUF_TREE_ROOT_PAGE_NO);
2691 sum_sizes = ibuf_get_merge_pages(
2693 &pages[0], &spaces[0], &versions[0], n_pages,
2703 if (sum_sizes > 0) {
2705 ut_a(*n_pages > 0 || sum_sizes == 1);
2708 ut_ad(*n_pages <= UT_ARR_SIZE(pages));
2710 for (ulint i = 0; i < *n_pages; ++
i) {
2711 ut_ad(spaces[i] == space);
2712 ut_ad(i == 0 || versions[i] == versions[i - 1]);
2717 true, spaces, versions, pages, *n_pages);
2728 static __attribute__((nonnull, warn_unused_result))
2732 table_id_t table_id,
2754 }
else if (table_id == 0) {
2755 return(ibuf_merge_pages(n_pages, sync));
2756 }
else if ((table = ibuf_get_table(table_id)) == 0) {
2761 ulint volume = ibuf_merge_space(table->
space, n_pages);
2783 return(ibuf_merge(0, &n_pages, sync));
2795 table_id_t table_id,
2804 ulint sum_bytes = 0;
2805 ulint sum_pages = 0;
2809 #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
2810 if (srv_ibuf_disable_background_merge && table_id == 0) {
2817 n_pages = PCT_IO(100);
2820 n_pages = PCT_IO(5);
2822 mutex_enter(&ibuf_mutex);
2827 if (
ibuf->size >
ibuf->max_size / 2) {
2828 ulint diff =
ibuf->size -
ibuf->max_size / 2;
2829 n_pages += PCT_IO((diff * 100)
2830 / (
ibuf->max_size + 1));
2833 mutex_exit(&ibuf_mutex);
2836 while (sum_pages < n_pages) {
2839 n_bytes = ibuf_merge(table_id, &n_pag2, FALSE);
2845 sum_bytes += n_bytes;
2846 sum_pages += n_pag2;
2856 ibuf_contract_after_insert(
2874 max_size =
ibuf->max_size;
2888 size = ibuf_contract(sync);
2890 }
while (size > 0 && sum_sizes < entry_size);
2898 ibuf_get_volume_buffered_hash(
2917 hash += (fold / (CHAR_BIT *
sizeof *hash)) %
size;
2918 bitmask = 1 << (fold % (CHAR_BIT *
sizeof *hash));
2920 if (*hash & bitmask) {
2932 # define ibuf_get_volume_buffered_count(mtr,rec,hash,size,n_recs) \
2933 ibuf_get_volume_buffered_count_func(mtr,rec,hash,size,n_recs)
2935 # define ibuf_get_volume_buffered_count(mtr,rec,hash,size,n_recs) \
2936 ibuf_get_volume_buffered_count_func(rec,hash,size,n_recs)
2945 ibuf_get_volume_buffered_count_func(
2961 ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
2962 || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
2966 ut_ad(n_fields > IBUF_REC_FIELD_USER);
2967 n_fields -= IBUF_REC_FIELD_USER;
2983 types = rec_get_nth_field_old(rec, IBUF_REC_FIELD_METADATA, &len);
2985 switch (UNIV_EXPECT(len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE,
3005 goto get_volume_comp;
3013 case IBUF_OP_INSERT:
3017 case IBUF_OP_DELETE_MARK:
3020 if (n_recs && ibuf_get_volume_buffered_hash(
3028 if (ibuf_op == IBUF_OP_DELETE_MARK) {
3034 case IBUF_OP_DELETE:
3047 ut_ad(ibuf_op == IBUF_OP_INSERT);
3056 entry = ibuf_build_entry_from_ibuf_rec(
3057 mtr, rec, heap, &dummy_index);
3061 ibuf_dummy_index_free(dummy_index);
3076 ibuf_get_volume_buffered(
3098 ulint hash_bitmap[128 /
sizeof(ulint)];
3109 memset(hash_bitmap, 0,
sizeof hash_bitmap);
3112 rec = btr_pcur_get_rec(pcur);
3124 if (page_no != ibuf_rec_get_page_no(mtr, rec)
3125 || space != ibuf_rec_get_space(mtr, rec)) {
3130 volume += ibuf_get_volume_buffered_count(
3132 hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
3148 IBUF_SPACE_ID, 0, prev_page_no, RW_X_LATCH,
3151 buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
3154 prev_page = buf_block_get_frame(block);
3158 #ifdef UNIV_BTR_DEBUG
3162 rec = page_get_supremum_rec(prev_page);
3174 return(UNIV_PAGE_SIZE);
3177 if (page_no != ibuf_rec_get_page_no(mtr, rec)
3178 || space != ibuf_rec_get_space(mtr, rec)) {
3183 volume += ibuf_get_volume_buffered_count(
3185 hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
3189 rec = btr_pcur_get_rec(pcur);
3197 if (page_no != ibuf_rec_get_page_no(mtr, rec)
3198 || space != ibuf_rec_get_space(mtr, rec)) {
3203 volume += ibuf_get_volume_buffered_count(
3205 hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
3221 IBUF_SPACE_ID, 0, next_page_no, RW_X_LATCH,
3224 buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
3227 next_page = buf_block_get_frame(block);
3231 #ifdef UNIV_BTR_DEBUG
3235 rec = page_get_infimum_rec(next_page);
3245 return(UNIV_PAGE_SIZE);
3248 if (page_no != ibuf_rec_get_page_no(mtr, rec)
3249 || space != ibuf_rec_get_space(mtr, rec)) {
3254 volume += ibuf_get_volume_buffered_count(
3256 hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
3291 rec = btr_pcur_get_rec(&pcur);
3308 # define ibuf_get_entry_counter_low(mtr,rec,space,page_no) \
3309 ibuf_get_entry_counter_low_func(mtr,rec,space,page_no)
3311 # define ibuf_get_entry_counter_low(mtr,rec,space,page_no) \
3312 ibuf_get_entry_counter_low_func(rec,space,page_no)
3323 ibuf_get_entry_counter_low_func(
3337 ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
3338 || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
3365 field = rec_get_nth_field_old(rec, IBUF_REC_FIELD_METADATA, &len);
3367 switch (len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE) {
3372 return(ULINT_UNDEFINED);
3376 ut_a(counter < 0xFFFF);
3377 return(counter + 1);
3382 # define ibuf_get_entry_counter(space,page_no,rec,mtr,exact_leaf) \
3383 ibuf_get_entry_counter_func(space,page_no,rec,mtr,exact_leaf)
3385 # define ibuf_get_entry_counter(space,page_no,rec,mtr,exact_leaf) \
3386 ibuf_get_entry_counter_func(space,page_no,rec,exact_leaf)
3396 ibuf_get_entry_counter_func(
3412 ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX));
3419 return(ULINT_UNDEFINED);
3421 return(ibuf_get_entry_counter_low(mtr, rec, space, page_no));
3422 }
else if (only_leaf
3434 return(ULINT_UNDEFINED);
3442 static __attribute__((nonnull, warn_unused_result))
3471 ibool old_bit_value;
3487 ut_ad(!no_counter || op == IBUF_OP_INSERT);
3488 ut_a(op < IBUF_OP_COUNT);
3497 if (
ibuf->max_size == 0) {
3498 return(DB_STRONG_FAIL);
3506 #ifdef UNIV_IBUF_DEBUG
3507 fputs(
"Ibuf too big\n", stderr);
3510 ibuf_contract(TRUE);
3512 return(DB_STRONG_FAIL);
3525 ibuf_entry = ibuf_entry_build(
3526 op, index, entry, space, page_no,
3527 no_counter ? ULINT_UNDEFINED : 0xFFFF, heap);
3535 mutex_enter(&ibuf_pessimistic_insert_mutex);
3536 mutex_enter(&ibuf_mutex);
3543 mutex_exit(&ibuf_mutex);
3544 mutex_exit(&ibuf_pessimistic_insert_mutex);
3546 if (UNIV_UNLIKELY(!ibuf_add_free_page())) {
3549 return(DB_STRONG_FAIL);
3556 btr_pcur_open(
ibuf->index, ibuf_entry, PAGE_CUR_LE, mode, &pcur, &mtr);
3562 buffered = ibuf_get_volume_buffered(&pcur, space, page_no,
3563 op == IBUF_OP_DELETE
3567 if (op == IBUF_OP_DELETE
3589 mutex_exit(&ibuf_mutex);
3590 mutex_exit(&ibuf_pessimistic_insert_mutex);
3593 err = DB_STRONG_FAIL;
3606 #ifdef UNIV_IBUF_COUNT_DEBUG
3607 ut_a((buffered == 0) || ibuf_count_get(space, page_no));
3612 zip_size, &bitmap_mtr);
3623 if (op == IBUF_OP_INSERT) {
3629 > ibuf_index_page_calc_free_from_bits(zip_size, bits)) {
3636 ibuf_get_merge_page_nos(FALSE,
3637 btr_pcur_get_rec(&pcur), &mtr,
3638 space_ids, space_versions,
3639 page_nos, &n_stored);
3649 ulint counter = ibuf_get_entry_counter(
3650 space, page_no, btr_pcur_get_rec(&pcur), &mtr,
3651 btr_pcur_get_btr_cur(&pcur)->low_match
3652 < IBUF_REC_FIELD_METADATA);
3655 if (counter == ULINT_UNDEFINED) {
3660 field = dtuple_get_nth_field(
3661 ibuf_entry, IBUF_REC_FIELD_METADATA);
3663 (byte*) dfield_get_data(field)
3671 bitmap_page, page_no, zip_size,
3674 if (!old_bit_value) {
3675 ibuf_bitmap_page_set_bits(bitmap_page, page_no, zip_size,
3682 cursor = btr_pcur_get_btr_cur(&pcur);
3687 cursor, &offsets, &offsets_heap,
3688 ibuf_entry, &ins_rec,
3689 &dummy_big_rec, 0, thr, &mtr);
3690 block = btr_cur_get_block(cursor);
3695 == FSP_IBUF_TREE_ROOT_PAGE_NO)) {
3696 const page_t* root = buf_block_get_frame(block);
3700 == FSP_IBUF_TREE_ROOT_PAGE_NO);
3712 root = ibuf_tree_root_get(&mtr);
3716 cursor, &offsets, &offsets_heap,
3717 ibuf_entry, &ins_rec,
3718 &dummy_big_rec, 0, thr, &mtr);
3720 if (err == DB_FAIL) {
3723 cursor, &offsets, &offsets_heap,
3724 ibuf_entry, &ins_rec,
3725 &dummy_big_rec, 0, thr, &mtr);
3728 mutex_exit(&ibuf_pessimistic_insert_mutex);
3729 ibuf_size_update(root, &mtr);
3730 mutex_exit(&ibuf_mutex);
3733 block = btr_cur_get_block(cursor);
3741 if (err == DB_SUCCESS && op != IBUF_OP_DELETE) {
3748 #ifdef UNIV_IBUF_COUNT_DEBUG
3749 if (err == DB_SUCCESS) {
3751 "Incrementing ibuf count of space %lu page %lu\n"
3752 "from %lu by 1\n", space, page_no,
3753 ibuf_count_get(space, page_no));
3755 ibuf_count_set(space, page_no,
3756 ibuf_count_get(space, page_no) + 1);
3766 ibuf_contract_after_insert(entry_size);
3770 #ifdef UNIV_IBUF_DEBUG
3774 page_nos, n_stored);
3803 DBUG_ENTER(
"ibuf_insert");
3805 DBUG_PRINT(
"ibuf", (
"op: %d, space: %ld, page_no: %ld",
3806 op, space, page_no));
3813 no_counter = use <= IBUF_USE_INSERT;
3816 case IBUF_OP_INSERT:
3819 case IBUF_USE_DELETE:
3820 case IBUF_USE_DELETE_MARK:
3822 case IBUF_USE_INSERT:
3823 case IBUF_USE_INSERT_DELETE_MARK:
3826 case IBUF_USE_COUNT:
3830 case IBUF_OP_DELETE_MARK:
3833 case IBUF_USE_INSERT:
3835 case IBUF_USE_DELETE_MARK:
3836 case IBUF_USE_DELETE:
3837 case IBUF_USE_INSERT_DELETE_MARK:
3841 case IBUF_USE_COUNT:
3845 case IBUF_OP_DELETE:
3848 case IBUF_USE_INSERT:
3849 case IBUF_USE_INSERT_DELETE_MARK:
3851 case IBUF_USE_DELETE_MARK:
3852 case IBUF_USE_DELETE:
3856 case IBUF_USE_COUNT:
3883 bpage = buf_page_hash_get(buf_pool, space, page_no);
3885 if (UNIV_LIKELY_NULL(bpage)) {
3908 index, space, zip_size, page_no, thr);
3909 if (err == DB_FAIL) {
3912 index, space, zip_size, page_no, thr);
3915 if (err == DB_SUCCESS) {
3916 #ifdef UNIV_IBUF_DEBUG
3933 static __attribute__((nonnull))
3935 ibuf_insert_to_index_page_low(
3951 const page_t* bitmap_page;
3954 DBUG_ENTER(
"ibuf_insert_to_index_page_low");
3957 offsets, &heap, 0, mtr);
3975 offsets, &heap, 0, mtr);
3980 page = buf_block_get_frame(block);
3985 " InnoDB: Error: Insert buffer insert fails;"
3986 " page free %lu, dtuple size %lu\n",
3989 fputs(
"InnoDB: Cannot insert index record ", stderr);
3991 fputs(
"\nInnoDB: The table where this index record belongs\n"
3992 "InnoDB: is now probably corrupt. Please run CHECK TABLE on\n"
3993 "InnoDB: that table.\n", stderr);
4004 "InnoDB: space %lu, page %lu, zip_size %lu, bitmap bits %lu\n",
4005 (ulong) space, (ulong) page_no,
4006 (ulong) zip_size, (ulong) old_bits);
4008 fputs(
"InnoDB: Submit a detailed bug report"
4009 " to http://bugs.mysql.com\n", stderr);
4019 ibuf_insert_to_index_page(
4029 page_t* page = buf_block_get_frame(block);
4034 DBUG_ENTER(
"ibuf_insert_to_index_page");
4037 DBUG_PRINT(
"ibuf", (
"index name: %s", index->
name));
4038 DBUG_PRINT(
"ibuf", (
"online status: %d",
4047 fputs(
"InnoDB: Trying to insert a record from"
4048 " the insert buffer to an index page\n"
4049 "InnoDB: but the 'compact' flag does not match!\n",
4057 fputs(
"InnoDB: Trying to insert a record from"
4058 " the insert buffer to an index page\n"
4059 "InnoDB: but the index page is empty!\n",
4066 fputs(
"InnoDB: Trying to insert a record from"
4067 " the insert buffer to an index page\n"
4068 "InnoDB: but the number of fields does not match!\n",
4076 fputs(
"InnoDB: The table where where"
4077 " this index record belongs\n"
4078 "InnoDB: is now probably corrupt."
4079 " Please run CHECK TABLE on\n"
4080 "InnoDB: your tables.\n"
4081 "InnoDB: Submit a detailed bug report to"
4082 " http://bugs.mysql.com!\n", stderr);
4088 PAGE_CUR_LE, &page_cur);
4092 + REC_OFFS_HEADER_SIZE *
sizeof(*offsets)
4100 rec = page_cur_get_rec(&page_cur);
4106 offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED,
4109 rec, index, offsets, entry, heap);
4118 rec, page_zip, FALSE, mtr);
4119 goto updated_in_place;
4124 update->
info_bits &= ~REC_INFO_DELETED_FLAG;
4131 && (!page_zip || btr_cur_update_alloc_zip(
4132 page_zip, &page_cur, index, offsets,
4136 rec = page_cur_get_rec(&page_cur);
4139 goto updated_in_place;
4143 rec = page_cur_get_rec(&page_cur);
4167 rec = ibuf_insert_to_index_page_low(entry, block, index,
4168 &offsets, heap, mtr,
4175 ibuf_insert_to_index_page_low(entry, block, index,
4176 &offsets, heap, mtr,
4204 block, index, entry, PAGE_CUR_LE, &page_cur);
4210 rec = page_cur_get_rec(&page_cur);
4211 page_zip = page_cur_get_page_zip(&page_cur);
4227 = page_cur_get_page(&page_cur);
4229 = page_cur_get_block(&page_cur);
4232 fputs(
" InnoDB: unable to find a record to delete-mark\n",
4234 fputs(
"InnoDB: tuple ", stderr);
4237 "InnoDB: record ", stderr);
4238 rec_print(stderr, page_cur_get_rec(&page_cur), index);
4239 fprintf(stderr,
"\nspace %u offset %u"
4240 " (%u records, index id %llu)\n"
4241 "InnoDB: Submit a detailed bug report"
4242 " to http://bugs.mysql.com\n",
4270 block, index, entry, PAGE_CUR_LE, &page_cur);
4274 page_t* page = buf_block_get_frame(block);
4275 rec_t* rec = page_cur_get_rec(&page_cur);
4280 ulint offsets_[REC_OFFS_NORMAL_SIZE];
4281 ulint* offsets = offsets_;
4283 ulint max_ins_size = 0;
4285 rec_offs_init(offsets_);
4287 offsets = rec_get_offsets(
4288 rec, index, offsets, ULINT_UNDEFINED, &heap);
4291 || !(REC_INFO_DELETED_FLAG
4296 fputs(
" InnoDB: unable to purge a record\n",
4298 fputs(
"InnoDB: tuple ", stderr);
4301 "InnoDB: record ", stderr);
4303 fprintf(stderr,
"\nspace %u offset %u"
4304 " (%u records, index id %llu)\n"
4305 "InnoDB: Submit a detailed bug report"
4306 " to http://bugs.mysql.com\n",
4323 #ifdef UNIV_ZIP_DEBUG
4324 ut_a(!page_zip || page_zip_validate(page_zip, page, index));
4327 #ifdef UNIV_ZIP_DEBUG
4328 ut_a(!page_zip || page_zip_validate(page_zip, page, index));
4337 if (UNIV_LIKELY_NULL(heap)) {
4348 static __attribute__((nonnull))
4364 if (btr_pcur_restore_position(mode, pcur, mtr)) {
4376 "InnoDB: ERROR: Submit the output to"
4377 " http://bugs.mysql.com\n"
4378 "InnoDB: ibuf cursor restoration fails!\n"
4379 "InnoDB: ibuf record inserted to page %lu:%lu\n",
4380 (ulong) space, (ulong) page_no);
4393 fputs(
"InnoDB: Validating insert buffer tree:\n", stderr);
4398 fprintf(stderr,
"InnoDB: ibuf tree ok\n");
4411 static __attribute__((warn_unused_result))
4430 ut_ad(ibuf_rec_get_page_no(mtr, btr_pcur_get_rec(pcur)) == page_no);
4431 ut_ad(ibuf_rec_get_space(mtr, btr_pcur_get_rec(pcur)) == space);
4433 #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
4434 if (ibuf_debug == 2) {
4442 btr_pcur_get_rec(pcur), NULL, TRUE, mtr);
4449 success = btr_cur_optimistic_delete(btr_pcur_get_btr_cur(pcur),
4457 root = btr_pcur_get_page(pcur);
4461 == FSP_IBUF_TREE_ROOT_PAGE_NO);
4469 #ifdef UNIV_IBUF_COUNT_DEBUG
4471 "Decrementing ibuf count of space %lu page %lu\n"
4472 "from %lu by 1\n", space, page_no,
4473 ibuf_count_get(space, page_no));
4474 ibuf_count_set(space, page_no,
4475 ibuf_count_get(space, page_no) - 1);
4481 ut_ad(ibuf_rec_get_page_no(mtr, btr_pcur_get_rec(pcur)) == page_no);
4482 ut_ad(ibuf_rec_get_space(mtr, btr_pcur_get_rec(pcur)) == space);
4489 btr_pcur_get_rec(pcur), NULL, TRUE, mtr);
4495 mutex_enter(&ibuf_mutex);
4497 if (!ibuf_restore_pos(space, page_no, search_tuple,
4500 mutex_exit(&ibuf_mutex);
4501 ut_ad(mtr->state == MTR_COMMITTED);
4505 root = ibuf_tree_root_get(mtr);
4509 ut_a(err == DB_SUCCESS);
4511 #ifdef UNIV_IBUF_COUNT_DEBUG
4512 ibuf_count_set(space, page_no, ibuf_count_get(space, page_no) - 1);
4514 ibuf_size_update(root, mtr);
4515 mutex_exit(&ibuf_mutex);
4521 ut_ad(mtr->state == MTR_COMMITTED);
4545 ibool update_ibuf_bitmap)
4554 #ifdef UNIV_IBUF_DEBUG
4558 ibool tablespace_being_deleted = FALSE;
4559 ibool corruption_noticed = FALSE;
4563 ulint mops[IBUF_OP_COUNT];
4564 ulint dops[IBUF_OP_COUNT];
4591 if (UNIV_LIKELY(update_ibuf_bitmap)) {
4606 if (UNIV_UNLIKELY(tablespace_being_deleted)) {
4611 update_ibuf_bitmap = FALSE;
4619 space, page_no, zip_size, &mtr);
4621 bitmap_page, page_no, zip_size,
4629 if (!tablespace_being_deleted) {
4645 search_tuple = ibuf_search_tuple_build(space, page_no, heap);
4662 corruption_noticed = TRUE;
4668 fputs(
" InnoDB: Dump of the ibuf bitmap page:\n",
4677 fputs(
"\nInnoDB: Dump of the page:\n", stderr);
4683 "InnoDB: Error: corruption in the tablespace."
4684 " Bitmap shows insert\n"
4685 "InnoDB: buffer records to page n:o %lu"
4686 " though the page\n"
4687 "InnoDB: type is %lu, which is"
4688 " not an index leaf page!\n"
4689 "InnoDB: We try to resolve the problem"
4690 " by skipping the insert buffer\n"
4691 "InnoDB: merge for this page."
4692 " Please run CHECK TABLE on your tables\n"
4693 "InnoDB: to determine if they are corrupt"
4695 "InnoDB: Please submit a detailed bug report"
4696 " to http://bugs.mysql.com\n\n",
4704 memset(mops, 0,
sizeof(mops));
4705 memset(dops, 0,
sizeof(dops));
4712 btr_pcur_open_on_user_rec(
4731 buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
4745 rec = btr_pcur_get_rec(&pcur);
4748 if (ibuf_rec_get_page_no(&mtr, rec) != page_no
4749 || ibuf_rec_get_space(&mtr, rec) != space) {
4753 block->
frame, page_zip, &mtr);
4759 if (UNIV_UNLIKELY(corruption_noticed)) {
4760 fputs(
"InnoDB: Discarding record\n ", stderr);
4762 fputs(
"\nInnoDB: from the insert buffer!\n\n", stderr);
4772 ibuf_op_t op = ibuf_rec_get_op_type(&mtr, rec);
4780 entry = ibuf_build_entry_from_ibuf_rec(
4781 &mtr, rec, heap, &dummy_index);
4787 case IBUF_OP_INSERT:
4788 #ifdef UNIV_IBUF_DEBUG
4790 dummy_index, entry, 0);
4794 ut_a(volume <= 4 * UNIV_PAGE_SIZE
4795 / IBUF_PAGE_SIZE_PER_FREE_SPACE);
4797 ibuf_insert_to_index_page(
4798 entry, block, dummy_index, &mtr);
4801 case IBUF_OP_DELETE_MARK:
4803 entry, block, dummy_index, &mtr);
4806 case IBUF_OP_DELETE:
4807 ibuf_delete(entry, block, dummy_index, &mtr);
4812 ut_ad(rec == btr_pcur_get_rec(&pcur));
4814 ut_ad(ibuf_rec_get_page_no(&mtr, rec)
4816 ut_ad(ibuf_rec_get_space(&mtr, rec) == space);
4825 btr_pcur_get_rec(&pcur), NULL,
4836 __FILE__, __LINE__, &mtr);
4843 buf_block_dbg_add_level(
4844 block, SYNC_IBUF_TREE_NODE);
4846 if (!ibuf_restore_pos(space, page_no,
4851 ut_ad(mtr.state == MTR_COMMITTED);
4853 ibuf_dummy_index_free(dummy_index);
4864 ibuf_dummy_index_free(dummy_index);
4866 dops[ibuf_rec_get_op_type(&mtr, rec)]++;
4870 if (ibuf_delete_rec(space, page_no, &pcur, search_tuple,
4875 ut_ad(mtr.state == MTR_COMMITTED);
4886 if (UNIV_LIKELY(update_ibuf_bitmap)) {
4890 space, page_no, zip_size, &mtr);
4892 ibuf_bitmap_page_set_bits(
4893 bitmap_page, page_no, zip_size,
4898 bitmap_page, page_no, zip_size,
4901 ulint new_bits = ibuf_index_page_calc_free(
4904 if (old_bits != new_bits) {
4905 ibuf_bitmap_page_set_bits(
4906 bitmap_page, page_no, zip_size,
4916 #ifdef HAVE_ATOMIC_BUILTINS
4917 os_atomic_increment_ulint(&
ibuf->n_merges, 1);
4918 ibuf_add_ops(
ibuf->n_merged_ops, mops);
4919 ibuf_add_ops(
ibuf->n_discarded_ops, dops);
4922 mutex_enter(&ibuf_mutex);
4925 ibuf_add_ops(
ibuf->n_merged_ops, mops);
4926 ibuf_add_ops(
ibuf->n_discarded_ops, dops);
4928 mutex_exit(&ibuf_mutex);
4931 if (update_ibuf_bitmap && !tablespace_being_deleted) {
4936 #ifdef UNIV_IBUF_COUNT_DEBUG
4937 ut_a(ibuf_count_get(space, page_no) == 0);
4955 const rec_t* ibuf_rec;
4960 ulint dops[IBUF_OP_COUNT];
4967 search_tuple = ibuf_search_tuple_build(space, 0, heap);
4969 memset(dops, 0,
sizeof(dops));
4975 btr_pcur_open_on_user_rec(
4988 ibuf_rec = btr_pcur_get_rec(&pcur);
4991 if (ibuf_rec_get_space(&mtr, ibuf_rec) != space) {
4996 page_no = ibuf_rec_get_page_no(&mtr, ibuf_rec);
4998 dops[ibuf_rec_get_op_type(&mtr, ibuf_rec)]++;
5001 if (ibuf_delete_rec(space, page_no, &pcur, search_tuple,
5006 ut_ad(mtr.state == MTR_COMMITTED);
5022 #ifdef HAVE_ATOMIC_BUILTINS
5023 ibuf_add_ops(
ibuf->n_discarded_ops, dops);
5026 mutex_enter(&ibuf_mutex);
5027 ibuf_add_ops(
ibuf->n_discarded_ops, dops);
5028 mutex_exit(&ibuf_mutex);
5048 mutex_enter(&ibuf_mutex);
5049 root = ibuf_tree_root_get(&mtr);
5050 mutex_exit(&ibuf_mutex);
5067 #ifdef UNIV_IBUF_COUNT_DEBUG
5072 mutex_enter(&ibuf_mutex);
5075 "Ibuf: size %lu, free list len %lu,"
5076 " seg size %lu, %lu merges\n",
5078 (ulong)
ibuf->free_list_len,
5079 (ulong)
ibuf->seg_size,
5080 (ulong)
ibuf->n_merges);
5082 fputs(
"merged operations:\n ", file);
5083 ibuf_print_ops(
ibuf->n_merged_ops, file);
5085 fputs(
"discarded operations:\n ", file);
5086 ibuf_print_ops(
ibuf->n_discarded_ops, file);
5088 #ifdef UNIV_IBUF_COUNT_DEBUG
5089 for (i = 0; i < IBUF_COUNT_N_SPACES; i++) {
5090 for (j = 0; j < IBUF_COUNT_N_PAGES; j++) {
5091 ulint count = ibuf_count_get(i, j);
5095 "Ibuf count for space/page %lu/%lu"
5097 (ulong) i, (ulong) j, (ulong) count);
5103 mutex_exit(&ibuf_mutex);
5126 if (zip_size == ULINT_UNDEFINED) {
5127 return(DB_TABLE_NOT_FOUND);
5133 return(DB_TABLE_NOT_FOUND);
5136 mutex_enter(&ibuf_mutex);
5138 page_size = zip_size ? zip_size : UNIV_PAGE_SIZE;
5140 for (page_no = 0; page_no <
size; page_no += page_size) {
5146 mutex_exit(&ibuf_mutex);
5147 return(DB_INTERRUPTED);
5157 space_id, page_no, zip_size, &mtr);
5159 for (i = FSP_IBUF_BITMAP_OFFSET + 1; i < page_size; i++) {
5160 const ulint
offset = page_no +
i;
5163 bitmap_page, offset, zip_size,
5166 mutex_exit(&ibuf_mutex);
5172 ER_INNODB_INDEX_CORRUPT,
5174 " is wrongly flagged to belong to the"
5176 (
unsigned) space_id,
5183 bitmap_page, offset, zip_size,
5188 ER_INNODB_INDEX_CORRUPT,
5190 " for space %u page %u are lost",
5191 (
unsigned) space_id,
5197 ibuf_bitmap_page_set_bits(
5198 bitmap_page, offset, zip_size,
5207 mutex_exit(&ibuf_mutex);