29 #define IBUF_BITS_PER_PAGE 4
30 #if IBUF_BITS_PER_PAGE % 2
31 # error "IBUF_BITS_PER_PAGE must be an even number!"
34 #define IBUF_BITMAP PAGE_DATA
37 #include "ibuf0ibuf.ic"
40 #ifndef UNIV_HOTBACKUP
187 #define IBUF_POOL_SIZE_PER_MAX_SIZE 2
190 #define IBUF_TABLE_NAME "SYS_IBUF_TABLE"
195 #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
197 UNIV_INTERN uint ibuf_debug;
201 UNIV_INTERN ibuf_t* ibuf = NULL;
204 UNIV_INTERN ulint ibuf_flush_count = 0;
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
265 #define IBUF_REC_INFO_SIZE 4
267 #if IBUF_REC_INFO_SIZE >= DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
268 # error "IBUF_REC_INFO_SIZE >= DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE"
272 #define IBUF_REC_OFFSET_COUNTER 0
273 #define IBUF_REC_OFFSET_TYPE 2
274 #define IBUF_REC_OFFSET_FLAGS 3
277 #define IBUF_REC_COMPACT 0x1
284 static mutex_t ibuf_pessimistic_insert_mutex;
290 static mutex_t ibuf_bitmap_mutex;
293 #define IBUF_MERGE_AREA 8
298 #define IBUF_MERGE_THRESHOLD 4
302 #define IBUF_MAX_N_PAGES_MERGED IBUF_MERGE_AREA
307 #define IBUF_CONTRACT_ON_INSERT_NON_SYNC 0
312 #define IBUF_CONTRACT_ON_INSERT_SYNC 5
317 #define IBUF_CONTRACT_DO_NOT_INSERT 10
356 ibuf_btr_pcur_commit_specify_mtr(
361 ut_d(ibuf_exit(mtr));
370 ibuf_header_page_get(
379 IBUF_SPACE_ID, 0, FSP_IBUF_HEADER_PAGE_NO, RW_X_LATCH, mtr);
380 buf_block_dbg_add_level(block, SYNC_IBUF_HEADER);
382 return(buf_block_get_frame(block));
398 ut_ad(mutex_own(&ibuf_mutex));
403 IBUF_SPACE_ID, 0, FSP_IBUF_TREE_ROOT_PAGE_NO, RW_X_LATCH, mtr);
405 buf_block_dbg_add_level(block, SYNC_TREE_NODE);
407 root = buf_block_get_frame(block);
416 #ifdef UNIV_IBUF_COUNT_DEBUG
428 ibuf_count_check(space, page_no);
430 return(ibuf_counts[space][page_no]);
443 ibuf_count_check(space, page_no);
444 ut_a(val < UNIV_PAGE_SIZE);
446 ibuf_counts[space][page_no] = val;
457 mutex_free(&ibuf_pessimistic_insert_mutex);
458 memset(&ibuf_pessimistic_insert_mutex,
459 0x0,
sizeof(ibuf_pessimistic_insert_mutex));
461 mutex_free(&ibuf_mutex);
462 memset(&ibuf_mutex, 0x0,
sizeof(ibuf_mutex));
464 mutex_free(&ibuf_bitmap_mutex);
465 memset(&ibuf_bitmap_mutex, 0x0,
sizeof(ibuf_mutex));
481 ut_ad(mutex_own(&ibuf_mutex));
484 + PAGE_BTR_IBUF_FREE_LIST, mtr);
489 ibuf->size = ibuf->seg_size - (1 + ibuf->free_list_len);
497 ibuf_init_at_db_start(
void)
509 ibuf =
static_cast<ibuf_t *
>(mem_alloc(
sizeof(ibuf_t)));
511 memset(ibuf, 0,
sizeof(*ibuf));
518 / IBUF_POOL_SIZE_PER_MAX_SIZE,
519 srv_ibuf_max_size / UNIV_PAGE_SIZE);
520 srv_ibuf_max_size = ibuf->max_size * UNIV_PAGE_SIZE;
522 mutex_create(ibuf_pessimistic_insert_mutex_key,
523 &ibuf_pessimistic_insert_mutex,
524 SYNC_IBUF_PESS_INSERT_MUTEX);
526 mutex_create(ibuf_mutex_key,
527 &ibuf_mutex, SYNC_IBUF_MUTEX);
529 mutex_create(ibuf_bitmap_mutex_key,
530 &ibuf_bitmap_mutex, SYNC_IBUF_BITMAP_MUTEX);
534 mutex_enter(&ibuf_mutex);
536 mtr_x_lock(fil_space_get_latch(IBUF_SPACE_ID, NULL), &mtr);
538 header_page = ibuf_header_page_get(&mtr);
540 fseg_n_reserved_pages(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER,
546 ibuf->seg_size = n_used;
552 IBUF_SPACE_ID, 0, FSP_IBUF_TREE_ROOT_PAGE_NO,
554 buf_block_dbg_add_level(block, SYNC_TREE_NODE);
556 root = buf_block_get_frame(block);
559 ibuf_size_update(root, &mtr);
560 mutex_exit(&ibuf_mutex);
568 table = dict_mem_table_create(IBUF_TABLE_NAME, IBUF_SPACE_ID, 1, 0);
570 dict_mem_table_add_col(table, heap,
"DUMMY_COLUMN", DATA_BINARY, 0, 0);
572 table->
id = DICT_IBUF_ID_MIN + IBUF_SPACE_ID;
574 dict_table_add_to_cache(table, heap);
577 index = dict_mem_index_create(
578 IBUF_TABLE_NAME,
"CLUST_IND",
581 dict_mem_index_add_field(index,
"DUMMY_COLUMN", 0);
583 index->
id = DICT_IBUF_ID_MIN + IBUF_SPACE_ID;
585 error = dict_index_add_to_cache(table, index,
586 FSP_IBUF_TREE_ROOT_PAGE_NO, FALSE);
587 ut_a(error == DB_SUCCESS);
589 ibuf->index = dict_table_get_first_index(table);
596 ibuf_bitmap_page_init(
607 page = buf_block_get_frame(block);
614 * IBUF_BITS_PER_PAGE);
619 memset(page + IBUF_BITMAP, 0, byte_offset);
623 #ifndef UNIV_HOTBACKUP
633 ibuf_parse_bitmap_init(
640 ut_ad(ptr && end_ptr);
643 ibuf_bitmap_page_init(block, mtr);
648 #ifndef UNIV_HOTBACKUP
657 # define ibuf_bitmap_page_get_bits(page, offset, zs, bit, mtr) \
658 ibuf_bitmap_page_get_bits_low(page, offset, zs, \
659 MTR_MEMO_PAGE_X_FIX, mtr, bit)
668 # define ibuf_bitmap_page_get_bits(page, offset, zs, bit, mtr) \
669 ibuf_bitmap_page_get_bits_low(page, offset, zs, bit)
677 ibuf_bitmap_page_get_bits_low(
699 ut_ad(bit < IBUF_BITS_PER_PAGE);
700 #if IBUF_BITS_PER_PAGE % 2
701 # error "IBUF_BITS_PER_PAGE % 2 != 0"
704 ut_ad(mtr_memo_contains_page(mtr, page, latch_type));
707 bit_offset = (page_no % UNIV_PAGE_SIZE) * IBUF_BITS_PER_PAGE
710 bit_offset = (page_no & (zip_size - 1)) * IBUF_BITS_PER_PAGE
714 byte_offset = bit_offset / 8;
715 bit_offset = bit_offset % 8;
717 ut_ad(byte_offset + IBUF_BITMAP < UNIV_PAGE_SIZE);
723 if (bit == IBUF_BITMAP_FREE) {
724 ut_ad(bit_offset + 1 < 8);
736 ibuf_bitmap_page_set_bits(
750 ut_ad(bit < IBUF_BITS_PER_PAGE);
751 #if IBUF_BITS_PER_PAGE % 2
752 # error "IBUF_BITS_PER_PAGE % 2 != 0"
755 ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX));
756 #ifdef UNIV_IBUF_COUNT_DEBUG
757 ut_a((bit != IBUF_BITMAP_BUFFERED) || (val != FALSE)
762 bit_offset = (page_no % UNIV_PAGE_SIZE) * IBUF_BITS_PER_PAGE
765 bit_offset = (page_no & (zip_size - 1)) * IBUF_BITS_PER_PAGE
769 byte_offset = bit_offset / 8;
770 bit_offset = bit_offset % 8;
772 ut_ad(byte_offset + IBUF_BITMAP < UNIV_PAGE_SIZE);
776 if (bit == IBUF_BITMAP_FREE) {
777 ut_ad(bit_offset + 1 < 8);
796 ibuf_bitmap_page_no_calc(
805 return(FSP_IBUF_BITMAP_OFFSET
806 + (page_no & ~(UNIV_PAGE_SIZE - 1)));
808 return(FSP_IBUF_BITMAP_OFFSET
809 + (page_no & ~(zip_size - 1)));
821 ibuf_bitmap_get_map_page_func(
833 block = buf_page_get_gen(space, zip_size,
834 ibuf_bitmap_page_no_calc(zip_size, page_no),
837 buf_block_dbg_add_level(block, SYNC_IBUF_BITMAP);
839 return(buf_block_get_frame(block));
852 #define ibuf_bitmap_get_map_page(space, page_no, zip_size, mtr) \
853 ibuf_bitmap_get_map_page_func(space, page_no, zip_size, \
854 __FILE__, __LINE__, mtr)
863 ibuf_set_free_bits_low(
884 bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, mtr);
885 #ifdef UNIV_IBUF_DEBUG
888 "Setting space %lu page %lu free bits to %lu should be %lu\n",
890 ibuf_index_page_calc_free(zip_size, block));
893 ut_a(val <= ibuf_index_page_calc_free(zip_size, block));
895 ibuf_bitmap_page_set_bits(bitmap_page, page_no, zip_size,
896 IBUF_BITMAP_FREE, val, mtr);
906 ibuf_set_free_bits_func(
910 #ifdef UNIV_IBUF_DEBUG
924 page = buf_block_get_frame(block);
936 bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, &mtr);
938 #ifdef UNIV_IBUF_DEBUG
939 if (max_val != ULINT_UNDEFINED) {
942 old_val = ibuf_bitmap_page_get_bits(
943 bitmap_page, page_no, zip_size,
944 IBUF_BITMAP_FREE, &mtr);
946 if (old_val != max_val) {
948 "Ibuf: page %lu old val %lu max val %lu\n",
954 ut_a(old_val <= max_val);
957 fprintf(stderr,
"Setting page no %lu free bits to %lu should be %lu\n",
959 ibuf_index_page_calc_free(zip_size, block));
962 ut_a(val <= ibuf_index_page_calc_free(zip_size, block));
964 ibuf_bitmap_page_set_bits(bitmap_page, page_no, zip_size,
965 IBUF_BITMAP_FREE, val, &mtr);
980 ibuf_reset_free_bits(
986 ibuf_set_free_bits(block, 0, ULINT_UNDEFINED);
999 ibuf_update_free_bits_low(
1014 before = ibuf_index_page_calc_free_bits(0, max_ins_size);
1016 after = ibuf_index_page_calc_free(0, block);
1022 if (before != after) {
1023 ibuf_set_free_bits_low(0, block, after, mtr);
1037 ibuf_update_free_bits_zip(
1055 bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, mtr);
1057 after = ibuf_index_page_calc_free_zip(zip_size, block);
1065 buf_page_make_young(&block->
page);
1068 ibuf_bitmap_page_set_bits(bitmap_page, page_no, zip_size,
1069 IBUF_BITMAP_FREE, after, mtr);
1081 ibuf_update_free_bits_for_two_pages_low(
1095 mutex_enter(&ibuf_bitmap_mutex);
1097 state = ibuf_index_page_calc_free(zip_size, block1);
1099 ibuf_set_free_bits_low(zip_size, block1, state, mtr);
1101 state = ibuf_index_page_calc_free(zip_size, block2);
1103 ibuf_set_free_bits_low(zip_size, block2, state, mtr);
1105 mutex_exit(&ibuf_bitmap_mutex);
1113 ibuf_fixed_addr_page(
1120 return((space == IBUF_SPACE_ID && page_no == IBUF_TREE_ROOT_PAGE_NO)
1152 ut_ad(x_latch || mtr == NULL);
1157 if (ibuf_fixed_addr_page(space, zip_size, page_no)) {
1160 }
else if (space != IBUF_SPACE_ID) {
1182 bitmap_page = buf_block_get_frame(
1185 ibuf_bitmap_page_no_calc(zip_size, page_no),
1187 file, line, &local_mtr));
1188 # ifdef UNIV_SYNC_DEBUG
1193 void* latch = sync_thread_levels_contains(SYNC_IBUF_BITMAP);
1195 fprintf(stderr,
"Bug#58212 UNIV_SYNC_DEBUG"
1196 " levels %p (%u,%u)\n",
1197 latch, (
unsigned) space, (
unsigned) page_no);
1200 ret = ibuf_bitmap_page_get_bits_low(
1201 bitmap_page, page_no, zip_size,
1202 MTR_MEMO_BUF_FIX, &local_mtr, IBUF_BITMAP_IBUF);
1214 bitmap_page = ibuf_bitmap_get_map_page_func(space, page_no, zip_size,
1217 ret = ibuf_bitmap_page_get_bits(bitmap_page, page_no, zip_size,
1218 IBUF_BITMAP_IBUF, mtr);
1220 if (mtr == &local_mtr) {
1228 # define ibuf_rec_get_page_no(mtr,rec) ibuf_rec_get_page_no_func(mtr,rec)
1230 # define ibuf_rec_get_page_no(mtr,rec) ibuf_rec_get_page_no_func(rec)
1238 ibuf_rec_get_page_no_func(
1248 ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
1249 || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
1253 field = rec_get_nth_field_old(rec, 1, &len);
1257 ut_a(trx_sys_multiple_tablespace_format);
1259 field = rec_get_nth_field_old(rec, 2, &len);
1261 ut_a(trx_doublewrite_must_reset_space_ids);
1262 ut_a(!trx_sys_multiple_tablespace_format);
1264 field = rec_get_nth_field_old(rec, 0, &len);
1273 # define ibuf_rec_get_space(mtr,rec) ibuf_rec_get_space_func(mtr,rec)
1275 # define ibuf_rec_get_space(mtr,rec) ibuf_rec_get_space_func(rec)
1284 ibuf_rec_get_space_func(
1294 ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
1295 || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
1299 field = rec_get_nth_field_old(rec, 1, &len);
1304 ut_a(trx_sys_multiple_tablespace_format);
1305 field = rec_get_nth_field_old(rec, 0, &len);
1311 ut_a(trx_doublewrite_must_reset_space_ids);
1312 ut_a(!trx_sys_multiple_tablespace_format);
1318 # define ibuf_rec_get_info(mtr,rec,op,comp,info_len,counter) \
1319 ibuf_rec_get_info_func(mtr,rec,op,comp,info_len,counter)
1321 # define ibuf_rec_get_info(mtr,rec,op,comp,info_len,counter) \
1322 ibuf_rec_get_info_func(rec,op,comp,info_len,counter)
1328 ibuf_rec_get_info_func(
1348 ulint info_len_local;
1349 ulint counter_local;
1351 ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
1352 || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
1357 types = rec_get_nth_field_old(rec, 3, &len);
1359 info_len_local = len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE;
1361 switch (info_len_local) {
1364 op_local = IBUF_OP_INSERT;
1365 comp_local = info_len_local;
1367 counter_local = ULINT_UNDEFINED;
1370 case IBUF_REC_INFO_SIZE:
1371 op_local = (ibuf_op_t)types[IBUF_REC_OFFSET_TYPE];
1372 comp_local = types[IBUF_REC_OFFSET_FLAGS] & IBUF_REC_COMPACT;
1374 types + IBUF_REC_OFFSET_COUNTER);
1381 ut_a(op_local < IBUF_OP_COUNT);
1382 ut_a((len - info_len_local) ==
1383 (fields - 4) * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
1394 *info_len = info_len_local;
1398 *counter = counter_local;
1403 # define ibuf_rec_get_op_type(mtr,rec) ibuf_rec_get_op_type_func(mtr,rec)
1405 # define ibuf_rec_get_op_type(mtr,rec) ibuf_rec_get_op_type_func(rec)
1413 ibuf_rec_get_op_type_func(
1422 ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
1423 || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
1427 (void) rec_get_nth_field_old(rec, 1, &len);
1432 return(IBUF_OP_INSERT);
1436 ibuf_rec_get_info(mtr, rec, &op, NULL, NULL, NULL);
1449 ibuf_rec_get_counter(
1458 return(ULINT_UNDEFINED);
1461 ptr = rec_get_nth_field_old(rec, 3, &len);
1468 return(ULINT_UNDEFINED);
1485 #ifndef HAVE_ATOMIC_BUILTINS
1486 ut_ad(mutex_own(&ibuf_mutex));
1489 for (i = 0; i < IBUF_OP_COUNT; i++) {
1490 #ifdef HAVE_ATOMIC_BUILTINS
1491 os_atomic_increment_ulint(&arr[i], ops[i]);
1507 static const char* op_names[] = {
1514 ut_a(UT_ARR_SIZE(op_names) == IBUF_OP_COUNT);
1516 for (i = 0; i < IBUF_OP_COUNT; i++) {
1517 fprintf(file,
"%s %lu%s", op_names[i],
1518 (ulong) ops[i], (i < (IBUF_OP_COUNT - 1)) ?
", " :
"");
1529 ibuf_dummy_index_create(
1537 table = dict_mem_table_create(
"IBUF_DUMMY",
1541 index = dict_mem_index_create(
"IBUF_DUMMY",
"IBUF_DUMMY",
1542 DICT_HDR_SPACE, 0, n);
1544 index->
table = table;
1555 ibuf_dummy_index_add_col(
1562 dict_mem_table_add_col(index->
table, NULL, NULL,
1566 dict_index_add_col(index, index->
table,
1567 dict_table_get_nth_col(index->
table, i), len);
1573 ibuf_dummy_index_free(
1579 dict_mem_index_free(index);
1580 dict_mem_table_free(table);
1593 ibuf_build_entry_pre_4_1_x(
1595 const rec_t* ibuf_rec,
1606 ut_a(trx_doublewrite_must_reset_space_ids);
1607 ut_a(!trx_sys_multiple_tablespace_format);
1611 types = rec_get_nth_field_old(ibuf_rec, 1, &len);
1613 ut_a(len == n_fields * DATA_ORDER_NULL_TYPE_BUF_SIZE);
1615 for (i = 0; i < n_fields; i++) {
1619 field = dtuple_get_nth_field(tuple, i);
1621 data = rec_get_nth_field_old(ibuf_rec, i + 2, &len);
1626 dfield_get_type(field),
1627 types + i * DATA_ORDER_NULL_TYPE_BUF_SIZE);
1630 *pindex = ibuf_dummy_index_create(n_fields, FALSE);
1636 # define ibuf_build_entry_from_ibuf_rec(mtr,ibuf_rec,heap,pindex) \
1637 ibuf_build_entry_from_ibuf_rec_func(mtr,ibuf_rec,heap,pindex)
1639 # define ibuf_build_entry_from_ibuf_rec(mtr,ibuf_rec,heap,pindex) \
1640 ibuf_build_entry_from_ibuf_rec_func(ibuf_rec,heap,pindex)
1661 ibuf_build_entry_from_ibuf_rec_func(
1666 const rec_t* ibuf_rec,
1682 ut_ad(mtr_memo_contains_page(mtr, ibuf_rec, MTR_MEMO_PAGE_X_FIX)
1683 || mtr_memo_contains_page(mtr, ibuf_rec, MTR_MEMO_PAGE_S_FIX));
1686 data = rec_get_nth_field_old(ibuf_rec, 1, &len);
1691 return(ibuf_build_entry_pre_4_1_x(ibuf_rec, heap, pindex));
1696 ut_a(trx_sys_multiple_tablespace_format);
1704 types = rec_get_nth_field_old(ibuf_rec, 3, &len);
1706 ibuf_rec_get_info(mtr, ibuf_rec, NULL, &comp, &info_len, NULL);
1708 index = ibuf_dummy_index_create(n_fields, comp);
1713 ut_a(len == n_fields * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
1715 for (i = 0; i < n_fields; i++) {
1716 field = dtuple_get_nth_field(tuple, i);
1718 data = rec_get_nth_field_old(ibuf_rec, i + 4, &len);
1723 dfield_get_type(field),
1724 types + i * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
1726 ibuf_dummy_index_add_col(index, dfield_get_type(field), len);
1763 types_offset = DATA_ORDER_NULL_TYPE_BUF_SIZE;
1766 types_offset = DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE;
1769 for (i = 0; i < n_fields; i++) {
1775 if (len != UNIV_SQL_NULL) {
1777 }
else if (pre_4_1) {
1787 types += types_offset;
1794 # define ibuf_rec_get_volume(mtr,rec) ibuf_rec_get_volume_func(mtr,rec)
1796 # define ibuf_rec_get_volume(mtr,rec) ibuf_rec_get_volume_func(rec)
1806 ibuf_rec_get_volume_func(
1811 const rec_t* ibuf_rec)
1821 ut_ad(mtr_memo_contains_page(mtr, ibuf_rec, MTR_MEMO_PAGE_X_FIX)
1822 || mtr_memo_contains_page(mtr, ibuf_rec, MTR_MEMO_PAGE_S_FIX));
1826 data = rec_get_nth_field_old(ibuf_rec, 1, &len);
1827 pre_4_1 = (len > 1);
1832 ut_a(trx_doublewrite_must_reset_space_ids);
1833 ut_a(!trx_sys_multiple_tablespace_format);
1837 types = rec_get_nth_field_old(ibuf_rec, 1, &len);
1839 ut_ad(len == n_fields * DATA_ORDER_NULL_TYPE_BUF_SIZE);
1846 ut_a(trx_sys_multiple_tablespace_format);
1849 types = rec_get_nth_field_old(ibuf_rec, 3, &len);
1851 ibuf_rec_get_info(mtr, ibuf_rec, &op, &comp, &info_len, NULL);
1853 if (op == IBUF_OP_DELETE_MARK || op == IBUF_OP_DELETE) {
1867 entry = ibuf_build_entry_from_ibuf_rec(
1868 mtr, ibuf_rec, heap, &dummy_index);
1872 ibuf_dummy_index_free(dummy_index);
1882 data_size = ibuf_rec_get_size(ibuf_rec, types, n_fields, pre_4_1, comp);
1919 ut_ad(counter != ULINT_UNDEFINED || op == IBUF_OP_INSERT);
1920 ut_ad(counter == ULINT_UNDEFINED || counter <= 0xFFFF);
1921 ut_ad(op < IBUF_OP_COUNT);
1938 field = dtuple_get_nth_field(tuple, 0);
1948 field = dtuple_get_nth_field(tuple, 1);
1960 field = dtuple_get_nth_field(tuple, 2);
1970 if (counter == ULINT_UNDEFINED) {
1973 ut_ad(counter <= 0xFFFF);
1974 i = IBUF_REC_INFO_SIZE;
1977 ti = type_info =
static_cast<byte *
>(
mem_heap_alloc(heap, i + n_fields
1978 * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE));
1990 ut_ad(op == IBUF_OP_INSERT);
1992 case IBUF_REC_INFO_SIZE:
1995 ti[IBUF_REC_OFFSET_TYPE] = (byte) op;
1997 ? IBUF_REC_COMPACT : 0;
1998 ti += IBUF_REC_INFO_SIZE;
2004 for (i = 0; i < n_fields; i++) {
2011 field = dtuple_get_nth_field(tuple, i + 4);
2012 entry_field = dtuple_get_nth_field(entry, i);
2015 ifield = dict_index_get_nth_field(index, i);
2026 ut_ad(fixed_len <= (ulint)
2027 dfield_get_type(entry_field)->len);
2031 ut_ad(fixed_len == (ulint)
2032 dfield_get_type(entry_field)->len);
2038 ti, dfield_get_type(entry_field), fixed_len);
2039 ti += DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE;
2044 field = dtuple_get_nth_field(tuple, 3);
2061 ibuf_search_tuple_build(
2072 ut_a(trx_doublewrite_must_reset_space_ids);
2073 ut_a(!trx_sys_multiple_tablespace_format);
2079 field = dtuple_get_nth_field(tuple, 0);
2098 ibuf_new_search_tuple_build(
2108 ut_a(trx_sys_multiple_tablespace_format);
2114 field = dtuple_get_nth_field(tuple, 0);
2124 field = dtuple_get_nth_field(tuple, 1);
2134 field = dtuple_get_nth_field(tuple, 2);
2153 ibuf_data_enough_free_for_insert(
void)
2156 ut_ad(mutex_own(&ibuf_mutex));
2164 return(ibuf->free_list_len >= (ibuf->size / 2) + 3 * ibuf->height);
2173 ibuf_data_too_much_free(
void)
2176 ut_ad(mutex_own(&ibuf_mutex));
2178 return(ibuf->free_list_len >= 3 + (ibuf->size / 2) + 3 * ibuf->height);
2187 ibuf_add_free_page(
void)
2203 mtr_x_lock(fil_space_get_latch(IBUF_SPACE_ID, &flags), &mtr);
2206 header_page = ibuf_header_page_get(&mtr);
2218 page_no = fseg_alloc_free_page(
2219 header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER, 0, FSP_UP,
2222 if (UNIV_UNLIKELY(page_no ==
FIL_NULL)) {
2228 IBUF_SPACE_ID, 0, page_no, RW_X_LATCH, &mtr);
2229 buf_block_dbg_add_level(block, SYNC_TREE_NODE_NEW);
2231 page = buf_block_get_frame(block);
2236 mutex_enter(&ibuf_mutex);
2238 root = ibuf_tree_root_get(&mtr);
2242 flst_add_last(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
2243 page + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, &mtr);
2249 ibuf->free_list_len++;
2254 bitmap_page = ibuf_bitmap_get_map_page(
2255 IBUF_SPACE_ID, page_no, zip_size, &mtr);
2257 mutex_exit(&ibuf_mutex);
2259 ibuf_bitmap_page_set_bits(
2260 bitmap_page, page_no, zip_size, IBUF_BITMAP_IBUF, TRUE, &mtr);
2271 ibuf_remove_free_page(
void)
2288 mtr_x_lock(fil_space_get_latch(IBUF_SPACE_ID, &flags), &mtr);
2291 header_page = ibuf_header_page_get(&mtr);
2295 mutex_enter(&ibuf_pessimistic_insert_mutex);
2296 mutex_enter(&ibuf_mutex);
2298 if (!ibuf_data_too_much_free()) {
2300 mutex_exit(&ibuf_mutex);
2301 mutex_exit(&ibuf_pessimistic_insert_mutex);
2310 root = ibuf_tree_root_get(&mtr2);
2312 mutex_exit(&ibuf_mutex);
2314 page_no =
flst_get_last(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
2330 fseg_free_page(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER,
2331 IBUF_SPACE_ID, page_no, &mtr);
2333 #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
2334 buf_page_reset_file_page_was_freed(IBUF_SPACE_ID, page_no);
2339 mutex_enter(&ibuf_mutex);
2341 root = ibuf_tree_root_get(&mtr);
2344 + PAGE_BTR_IBUF_FREE_LIST, &mtr).page);
2350 IBUF_SPACE_ID, 0, page_no, RW_X_LATCH, &mtr);
2352 buf_block_dbg_add_level(block, SYNC_TREE_NODE);
2355 page = buf_block_get_frame(block);
2360 flst_remove(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
2361 page + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, &mtr);
2363 mutex_exit(&ibuf_pessimistic_insert_mutex);
2366 ibuf->free_list_len--;
2371 bitmap_page = ibuf_bitmap_get_map_page(
2372 IBUF_SPACE_ID, page_no, zip_size, &mtr);
2374 mutex_exit(&ibuf_mutex);
2376 ibuf_bitmap_page_set_bits(
2377 bitmap_page, page_no, zip_size, IBUF_BITMAP_IBUF, FALSE, &mtr);
2379 #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
2380 buf_page_set_file_page_was_freed(IBUF_SPACE_ID, page_no);
2391 ibuf_free_excess_pages(
void)
2396 #ifdef UNIV_SYNC_DEBUG
2397 ut_ad(rw_lock_own(fil_space_get_latch(IBUF_SPACE_ID, NULL),
2402 fil_space_get_latch(IBUF_SPACE_ID, NULL)) == 1);
2418 for (i = 0; i < 4; i++) {
2420 ibool too_much_free;
2422 mutex_enter(&ibuf_mutex);
2423 too_much_free = ibuf_data_too_much_free();
2424 mutex_exit(&ibuf_mutex);
2426 if (!too_much_free) {
2430 ibuf_remove_free_page();
2435 # define ibuf_get_merge_page_nos(contract,rec,mtr,ids,vers,pages,n_stored) \
2436 ibuf_get_merge_page_nos_func(contract,rec,mtr,ids,vers,pages,n_stored)
2438 # define ibuf_get_merge_page_nos(contract,rec,mtr,ids,vers,pages,n_stored) \
2439 ibuf_get_merge_page_nos_func(contract,rec,ids,vers,pages,n_stored)
2448 ibuf_get_merge_page_nos_func(
2459 ib_int64_t* space_versions,
2469 ulint prev_space_id;
2470 ulint first_page_no;
2471 ulint first_space_id;
2475 ulint volume_for_page;
2480 ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
2481 || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
2503 first_page_no = ibuf_rec_get_page_no(mtr, rec);
2504 first_space_id = ibuf_rec_get_space(mtr, rec);
2515 rec_page_no = ibuf_rec_get_page_no(mtr, rec);
2516 rec_space_id = ibuf_rec_get_space(mtr, rec);
2518 if (rec_space_id != first_space_id
2519 || (rec_page_no / IBUF_MERGE_AREA)
2520 != (first_page_no / IBUF_MERGE_AREA)) {
2525 if (rec_page_no != prev_page_no
2526 || rec_space_id != prev_space_id) {
2530 prev_page_no = rec_page_no;
2531 prev_space_id = rec_space_id;
2545 volume_for_page = 0;
2547 while (*n_stored < limit) {
2554 rec_page_no = ibuf_rec_get_page_no(mtr, rec);
2555 rec_space_id = ibuf_rec_get_space(mtr, rec);
2556 ut_ad(rec_page_no > IBUF_TREE_ROOT_PAGE_NO);
2559 #ifdef UNIV_IBUF_DEBUG
2560 ut_a(*n_stored < IBUF_MAX_N_PAGES_MERGED);
2562 if ((rec_space_id != prev_space_id
2563 || rec_page_no != prev_page_no)
2564 && (prev_space_id != 0 || prev_page_no != 0)) {
2567 || (prev_page_no == first_page_no
2568 && prev_space_id == first_space_id)
2570 > ((IBUF_MERGE_THRESHOLD - 1)
2571 * 4 * UNIV_PAGE_SIZE
2572 / IBUF_PAGE_SIZE_PER_FREE_SPACE)
2573 / IBUF_MERGE_THRESHOLD)) {
2575 space_ids[*n_stored] = prev_space_id;
2576 space_versions[*n_stored]
2577 = fil_space_get_version(prev_space_id);
2578 page_nos[*n_stored] = prev_page_no;
2582 sum_volumes += volume_for_page;
2585 if (rec_space_id != first_space_id
2586 || rec_page_no / IBUF_MERGE_AREA
2587 != first_page_no / IBUF_MERGE_AREA) {
2592 volume_for_page = 0;
2595 if (rec_page_no == 1 && rec_space_id == 0) {
2601 rec_volume = ibuf_rec_get_volume(mtr, rec);
2603 volume_for_page += rec_volume;
2605 prev_page_no = rec_page_no;
2606 prev_space_id = rec_space_id;
2611 #ifdef UNIV_IBUF_DEBUG
2612 ut_a(*n_stored <= IBUF_MAX_N_PAGES_MERGED);
2615 fprintf(stderr,
"Ibuf merge batch %lu pages %lu volume\n",
2616 *n_stored, sum_volumes);
2618 return(sum_volumes);
2636 ulint page_nos[IBUF_MAX_N_PAGES_MERGED];
2637 ulint space_ids[IBUF_MAX_N_PAGES_MERGED];
2638 ib_int64_t space_versions[IBUF_MAX_N_PAGES_MERGED];
2649 if (UNIV_UNLIKELY(ibuf->empty)
2671 == FSP_IBUF_TREE_ROOT_PAGE_NO);
2679 sum_sizes = ibuf_get_merge_page_nos(TRUE,
2680 btr_pcur_get_rec(&pcur), &mtr,
2681 space_ids, space_versions,
2684 fprintf(stderr,
"Ibuf contract sync %lu pages %lu volume %lu\n",
2685 sync, *n_pages, sum_sizes);
2690 buf_read_ibuf_merge_pages(sync, space_ids, space_versions, page_nos,
2693 return(sum_sizes + 1);
2711 return(ibuf_contract_ext(&n_pages, sync));
2721 ibuf_contract_for_n_pages(
2730 ulint sum_bytes = 0;
2731 ulint sum_pages = 0;
2738 while (sum_pages < n_pages) {
2739 n_bytes = ibuf_contract_ext(&n_pag2, sync);
2745 sum_bytes += n_bytes;
2746 sum_pages += n_pag2;
2756 ibuf_contract_after_insert(
2774 max_size = ibuf->max_size;
2776 if (srv_ibuf_active_contract ==
false
2777 && size < max_size + IBUF_CONTRACT_ON_INSERT_NON_SYNC) {
2781 sync = (size >= max_size + IBUF_CONTRACT_ON_INSERT_SYNC);
2789 size = ibuf_contract(sync);
2791 }
while (size > 0 && sum_sizes < entry_size);
2799 ibuf_get_volume_buffered_hash(
2817 hash += (fold / (8 *
sizeof *hash)) % size;
2818 bitmask = 1 << (fold % (8 *
sizeof *hash));
2820 if (*hash & bitmask) {
2832 # define ibuf_get_volume_buffered_count(mtr,rec,hash,size,n_recs) \
2833 ibuf_get_volume_buffered_count_func(mtr,rec,hash,size,n_recs)
2835 # define ibuf_get_volume_buffered_count(mtr,rec,hash,size,n_recs) \
2836 ibuf_get_volume_buffered_count_func(rec,hash,size,n_recs)
2845 ibuf_get_volume_buffered_count_func(
2861 ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
2862 || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
2866 ut_ad(n_fields > 4);
2874 ut_ad(trx_sys_multiple_tablespace_format);
2876 types = rec_get_nth_field_old(rec, 3, &len);
2878 switch (UNIV_EXPECT(len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE,
2879 IBUF_REC_INFO_SIZE)) {
2888 len = ibuf_rec_get_size(rec, types, n_fields, FALSE, 0);
2898 goto get_volume_comp;
2900 case IBUF_REC_INFO_SIZE:
2901 ibuf_op = (ibuf_op_t) types[IBUF_REC_OFFSET_TYPE];
2906 case IBUF_OP_INSERT:
2910 case IBUF_OP_DELETE_MARK:
2913 if (n_recs && ibuf_get_volume_buffered_hash(
2914 rec, types + IBUF_REC_INFO_SIZE,
2916 types[IBUF_REC_OFFSET_FLAGS] & IBUF_REC_COMPACT,
2921 if (ibuf_op == IBUF_OP_DELETE_MARK) {
2927 case IBUF_OP_DELETE:
2940 ut_ad(ibuf_op == IBUF_OP_INSERT);
2949 entry = ibuf_build_entry_from_ibuf_rec(
2950 mtr, rec, heap, &dummy_index);
2954 ibuf_dummy_index_free(dummy_index);
2969 ibuf_get_volume_buffered(
2991 ulint hash_bitmap[128 /
sizeof(ulint)];
2993 ut_a(trx_sys_multiple_tablespace_format);
3004 memset(hash_bitmap, 0,
sizeof hash_bitmap);
3007 rec = btr_pcur_get_rec(pcur);
3019 if (page_no != ibuf_rec_get_page_no(mtr, rec)
3020 || space != ibuf_rec_get_space(mtr, rec)) {
3025 volume += ibuf_get_volume_buffered_count(
3027 hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
3043 IBUF_SPACE_ID, 0, prev_page_no, RW_X_LATCH,
3046 buf_block_dbg_add_level(block, SYNC_TREE_NODE);
3049 prev_page = buf_block_get_frame(block);
3053 #ifdef UNIV_BTR_DEBUG
3057 rec = page_get_supremum_rec(prev_page);
3069 return(UNIV_PAGE_SIZE);
3072 if (page_no != ibuf_rec_get_page_no(mtr, rec)
3073 || space != ibuf_rec_get_space(mtr, rec)) {
3078 volume += ibuf_get_volume_buffered_count(
3080 hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
3084 rec = btr_pcur_get_rec(pcur);
3092 if (page_no != ibuf_rec_get_page_no(mtr, rec)
3093 || space != ibuf_rec_get_space(mtr, rec)) {
3098 volume += ibuf_get_volume_buffered_count(
3100 hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
3116 IBUF_SPACE_ID, 0, next_page_no, RW_X_LATCH,
3119 buf_block_dbg_add_level(block, SYNC_TREE_NODE);
3122 next_page = buf_block_get_frame(block);
3126 #ifdef UNIV_BTR_DEBUG
3130 rec = page_get_infimum_rec(next_page);
3140 return(UNIV_PAGE_SIZE);
3143 if (page_no != ibuf_rec_get_page_no(mtr, rec)
3144 || space != ibuf_rec_get_space(mtr, rec)) {
3149 volume += ibuf_get_volume_buffered_count(
3151 hash_bitmap, UT_ARR_SIZE(hash_bitmap), n_recs);
3160 ibuf_update_max_tablespace_id(
void)
3179 btr_pcur_move_to_prev(&pcur, &mtr);
3186 rec = btr_pcur_get_rec(&pcur);
3188 field = rec_get_nth_field_old(rec, 0, &len);
3199 fil_set_max_space_id_if_bigger(max_space_id);
3203 # define ibuf_get_entry_counter_low(mtr,rec,space,page_no) \
3204 ibuf_get_entry_counter_low_func(mtr,rec,space,page_no)
3206 # define ibuf_get_entry_counter_low(mtr,rec,space,page_no) \
3207 ibuf_get_entry_counter_low_func(rec,space,page_no)
3216 ibuf_get_entry_counter_low_func(
3230 ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX)
3231 || mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_S_FIX));
3234 field = rec_get_nth_field_old(rec, 1, &len);
3236 if (UNIV_UNLIKELY(len != 1)) {
3238 ut_a(trx_doublewrite_must_reset_space_ids);
3239 ut_a(!trx_sys_multiple_tablespace_format);
3241 return(ULINT_UNDEFINED);
3244 ut_a(trx_sys_multiple_tablespace_format);
3247 field = rec_get_nth_field_old(rec, 0, &len);
3256 field = rec_get_nth_field_old(rec, 2, &len);
3265 field = rec_get_nth_field_old(rec, 3, &len);
3267 switch (len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE) {
3272 return(ULINT_UNDEFINED);
3274 case IBUF_REC_INFO_SIZE:
3276 ut_a(counter < 0xFFFF);
3277 return(counter + 1);
3287 ibuf_set_entry_counter(
3295 ibool is_optimistic,
3304 ut_ad(mtr_memo_contains(mtr, btr_pcur_get_block(pcur),
3305 MTR_MEMO_PAGE_X_FIX));
3310 counter = ibuf_get_entry_counter_low(
3311 mtr, btr_pcur_get_rec(pcur), space, page_no);
3313 if (UNIV_UNLIKELY(counter == ULINT_UNDEFINED)) {
3328 btr_cur_t* cursor = btr_pcur_get_btr_cur(pcur);
3346 ut_a(cursor->ibuf_cnt != ULINT_UNDEFINED);
3348 page = btr_pcur_get_page(pcur);
3354 IBUF_SPACE_ID, 0, prev_page_no,
3357 buf_block_dbg_add_level(block, SYNC_TREE_NODE);
3359 prev_page = buf_block_get_frame(block);
3362 page_get_supremum_rec(prev_page));
3366 counter = ibuf_get_entry_counter_low(
3367 mtr, rec, space, page_no);
3369 if (UNIV_UNLIKELY(counter == ULINT_UNDEFINED)) {
3377 if (counter < cursor->ibuf_cnt) {
3380 if (is_optimistic) {
3388 ibuf->index, rec, block,
3389 btr_pcur_get_btr_cur(pcur));
3416 field = dtuple_get_nth_field(entry, 3);
3417 data =
static_cast<byte *
>(dfield_get_data(field));
3455 ibool old_bit_value;
3461 ulint space_ids[IBUF_MAX_N_PAGES_MERGED];
3462 ib_int64_t space_versions[IBUF_MAX_N_PAGES_MERGED];
3463 ulint page_nos[IBUF_MAX_N_PAGES_MERGED];
3471 ut_ad(!no_counter || op == IBUF_OP_INSERT);
3472 ut_a(op < IBUF_OP_COUNT);
3474 ut_a(trx_sys_multiple_tablespace_format);
3485 if (ibuf->size >= ibuf->max_size + IBUF_CONTRACT_DO_NOT_INSERT) {
3490 #ifdef UNIV_IBUF_DEBUG
3491 fputs(
"Ibuf too big\n", stderr);
3494 ibuf_contract(TRUE);
3496 return(DB_STRONG_FAIL);
3509 ibuf_entry = ibuf_entry_build(
3510 op, index, entry, space, page_no,
3511 no_counter ? ULINT_UNDEFINED : 0xFFFF, heap);
3519 mutex_enter(&ibuf_pessimistic_insert_mutex);
3520 mutex_enter(&ibuf_mutex);
3522 if (UNIV_LIKELY(ibuf_data_enough_free_for_insert())) {
3527 mutex_exit(&ibuf_mutex);
3528 mutex_exit(&ibuf_pessimistic_insert_mutex);
3530 if (UNIV_UNLIKELY(!ibuf_add_free_page())) {
3533 return(DB_STRONG_FAIL);
3540 btr_pcur_open(ibuf->index, ibuf_entry, PAGE_CUR_LE, mode, &pcur, &mtr);
3546 buffered = ibuf_get_volume_buffered(&pcur, space, page_no,
3547 op == IBUF_OP_DELETE
3551 if (op == IBUF_OP_DELETE
3553 || buf_pool_watch_occurred(space, page_no))) {
3573 mutex_exit(&ibuf_mutex);
3574 mutex_exit(&ibuf_pessimistic_insert_mutex);
3577 err = DB_STRONG_FAIL;
3590 #ifdef UNIV_IBUF_COUNT_DEBUG
3591 ut_a((buffered == 0) || ibuf_count_get(space, page_no));
3595 bitmap_page = ibuf_bitmap_get_map_page(space, page_no,
3596 zip_size, &bitmap_mtr);
3606 if (op == IBUF_OP_INSERT) {
3607 ulint bits = ibuf_bitmap_page_get_bits(
3608 bitmap_page, page_no, zip_size, IBUF_BITMAP_FREE,
3612 > ibuf_index_page_calc_free_from_bits(zip_size, bits)) {
3619 ibuf_get_merge_page_nos(FALSE,
3620 btr_pcur_get_rec(&pcur), &mtr,
3621 space_ids, space_versions,
3622 page_nos, &n_stored);
3632 && !ibuf_set_entry_counter(ibuf_entry, space, page_no, &pcur,
3643 old_bit_value = ibuf_bitmap_page_get_bits(
3644 bitmap_page, page_no, zip_size,
3645 IBUF_BITMAP_BUFFERED, &bitmap_mtr);
3647 if (!old_bit_value) {
3648 ibuf_bitmap_page_set_bits(bitmap_page, page_no, zip_size,
3649 IBUF_BITMAP_BUFFERED, TRUE,
3655 cursor = btr_pcur_get_btr_cur(&pcur);
3658 err = btr_cur_optimistic_insert(BTR_NO_LOCKING_FLAG, cursor,
3659 ibuf_entry, &ins_rec,
3660 &dummy_big_rec, 0, thr, &mtr);
3666 == FSP_IBUF_TREE_ROOT_PAGE_NO)) {
3667 const page_t* page_root = buf_block_get_frame(block);
3671 == FSP_IBUF_TREE_ROOT_PAGE_NO);
3683 root = ibuf_tree_root_get(&mtr);
3685 err = btr_cur_pessimistic_insert(BTR_NO_LOCKING_FLAG
3686 | BTR_NO_UNDO_LOG_FLAG,
3688 ibuf_entry, &ins_rec,
3689 &dummy_big_rec, 0, thr, &mtr);
3690 mutex_exit(&ibuf_pessimistic_insert_mutex);
3691 ibuf_size_update(root, &mtr);
3692 mutex_exit(&ibuf_mutex);
3699 if (err == DB_SUCCESS && op != IBUF_OP_DELETE) {
3706 #ifdef UNIV_IBUF_COUNT_DEBUG
3707 if (err == DB_SUCCESS) {
3709 "Incrementing ibuf count of space %lu page %lu\n"
3710 "from %lu by 1\n", space, page_no,
3711 ibuf_count_get(space, page_no));
3713 ibuf_count_set(space, page_no,
3714 ibuf_count_get(space, page_no) + 1);
3724 ibuf_contract_after_insert(entry_size);
3728 #ifdef UNIV_IBUF_DEBUG
3729 ut_a(n_stored <= IBUF_MAX_N_PAGES_MERGED);
3731 buf_read_ibuf_merge_pages(FALSE, space_ids, space_versions,
3732 page_nos, n_stored);
3768 no_counter = use <= IBUF_USE_INSERT;
3771 case IBUF_OP_INSERT:
3774 case IBUF_USE_DELETE:
3775 case IBUF_USE_DELETE_MARK:
3777 case IBUF_USE_INSERT:
3778 case IBUF_USE_INSERT_DELETE_MARK:
3781 case IBUF_USE_COUNT:
3785 case IBUF_OP_DELETE_MARK:
3788 case IBUF_USE_INSERT:
3790 case IBUF_USE_DELETE_MARK:
3791 case IBUF_USE_DELETE:
3792 case IBUF_USE_INSERT_DELETE_MARK:
3796 case IBUF_USE_COUNT:
3800 case IBUF_OP_DELETE:
3803 case IBUF_USE_INSERT:
3804 case IBUF_USE_INSERT_DELETE_MARK:
3806 case IBUF_USE_DELETE_MARK:
3807 case IBUF_USE_DELETE:
3811 case IBUF_USE_COUNT:
3844 if (UNIV_LIKELY_NULL(bpage)) {
3867 index, space, zip_size, page_no, thr);
3868 if (err == DB_FAIL) {
3871 index, space, zip_size, page_no, thr);
3874 if (err == DB_SUCCESS) {
3875 #ifdef UNIV_IBUF_DEBUG
3882 ut_a(err == DB_STRONG_FAIL);
3893 ibuf_insert_to_index_page_low(
3907 const page_t* bitmap_page;
3917 btr_page_reorganize(block, index, mtr);
3927 page = buf_block_get_frame(block);
3932 " InnoDB: Error: Insert buffer insert fails;"
3933 " page free %lu, dtuple size %lu\n",
3936 fputs(
"InnoDB: Cannot insert index record ", stderr);
3937 dtuple_print(stderr, entry);
3938 fputs(
"\nInnoDB: The table where this index record belongs\n"
3939 "InnoDB: is now probably corrupt. Please run CHECK TABLE on\n"
3940 "InnoDB: that table.\n", stderr);
3946 bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, mtr);
3947 old_bits = ibuf_bitmap_page_get_bits(bitmap_page, page_no, zip_size,
3948 IBUF_BITMAP_FREE, mtr);
3951 "InnoDB: space %lu, page %lu, zip_size %lu, bitmap bits %lu\n",
3952 (ulong) space, (ulong) page_no,
3953 (ulong) zip_size, (ulong) old_bits);
3955 fputs(
"InnoDB: Submit a detailed bug report"
3956 " to http://bugs.mysql.com\n", stderr);
3964 ibuf_insert_to_index_page(
3974 page_t* page = buf_block_get_frame(block);
3979 ut_ad(!buf_block_align(page)->is_hashed);
3983 fputs(
"InnoDB: Trying to insert a record from"
3984 " the insert buffer to an index page\n"
3985 "InnoDB: but the 'compact' flag does not match!\n",
3993 fputs(
"InnoDB: Trying to insert a record from"
3994 " the insert buffer to an index page\n"
3995 "InnoDB: but the index page is empty!\n",
4002 fputs(
"InnoDB: Trying to insert a record from"
4003 " the insert buffer to an index page\n"
4004 "InnoDB: but the number of fields does not match!\n",
4007 buf_page_print(page, 0);
4009 dtuple_print(stderr, entry);
4011 fputs(
"InnoDB: The table where where"
4012 " this index record belongs\n"
4013 "InnoDB: is now probably corrupt."
4014 " Please run CHECK TABLE on\n"
4015 "InnoDB: your tables.\n"
4016 "InnoDB: Submit a detailed bug report to"
4017 " http://bugs.mysql.com!\n", stderr);
4023 PAGE_CUR_LE, &page_cur);
4031 rec = page_cur_get_rec(&page_cur);
4039 offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED,
4042 index, entry, rec, NULL, heap);
4050 btr_cur_set_deleted_flag_for_ibuf(
4051 rec, page_zip, FALSE, mtr);
4059 update->
info_bits &= ~REC_INFO_DELETED_FLAG;
4066 && (!page_zip || btr_cur_update_alloc_zip(
4067 page_zip, block, index,
4073 goto updated_in_place;
4100 ibuf_insert_to_index_page_low(entry, block, index, mtr,
4104 ibuf_insert_to_index_page_low(entry, block, index, mtr,
4128 block, index, entry, PAGE_CUR_LE, &page_cur);
4134 rec = page_cur_get_rec(&page_cur);
4135 page_zip = page_cur_get_page_zip(&page_cur);
4146 btr_cur_set_deleted_flag_for_ibuf(rec, page_zip,
4151 fputs(
" InnoDB: unable to find a record to delete-mark\n",
4153 fputs(
"InnoDB: tuple ", stderr);
4154 dtuple_print(stderr, entry);
4156 "InnoDB: record ", stderr);
4157 rec_print(stderr, page_cur_get_rec(&page_cur), index);
4160 "InnoDB: Submit a detailed bug report"
4161 " to http://bugs.mysql.com\n", stderr);
4185 block, index, entry, PAGE_CUR_LE, &page_cur);
4189 page_t* page = buf_block_get_frame(block);
4190 rec_t* rec = page_cur_get_rec(&page_cur);
4195 ulint offsets_[REC_OFFS_NORMAL_SIZE];
4196 ulint* offsets = offsets_;
4200 rec_offs_init(offsets_);
4202 offsets = rec_get_offsets(
4203 rec, index, offsets, ULINT_UNDEFINED, &heap);
4209 ut_ad(REC_INFO_DELETED_FLAG
4219 #ifdef UNIV_ZIP_DEBUG
4220 ut_a(!page_zip || page_zip_validate(page_zip, page));
4223 #ifdef UNIV_ZIP_DEBUG
4224 ut_a(!page_zip || page_zip_validate(page_zip, page));
4228 ibuf_update_free_bits_zip(block, mtr);
4230 ibuf_update_free_bits_low(block, max_ins_size, mtr);
4233 if (UNIV_LIKELY_NULL(heap)) {
4244 static __attribute__((nonnull))
4260 if (btr_pcur_restore_position(mode, pcur, mtr)) {
4265 if (fil_space_get_flags(space) == ULINT_UNDEFINED) {
4269 ibuf_btr_pcur_commit_specify_mtr(pcur, mtr);
4272 "InnoDB: ERROR: Submit the output to"
4273 " http://bugs.mysql.com\n"
4274 "InnoDB: ibuf cursor restoration fails!\n"
4275 "InnoDB: ibuf record inserted to page %lu:%lu\n",
4276 (ulong) space, (ulong) page_no);
4279 rec_print_old(stderr, btr_pcur_get_rec(pcur));
4280 rec_print_old(stderr, pcur->old_rec);
4281 dtuple_print(stderr, search_tuple);
4283 rec_print_old(stderr,
4287 ibuf_btr_pcur_commit_specify_mtr(pcur, mtr);
4289 fputs(
"InnoDB: Validating insert buffer tree:\n", stderr);
4290 if (!btr_validate_index(ibuf->index, NULL)) {
4294 fprintf(stderr,
"InnoDB: ibuf tree ok\n");
4325 ut_ad(ibuf_rec_get_page_no(mtr, btr_pcur_get_rec(pcur)) == page_no);
4326 ut_ad(ibuf_rec_get_space(mtr, btr_pcur_get_rec(pcur)) == space);
4328 success = btr_cur_optimistic_delete(btr_pcur_get_btr_cur(pcur), mtr);
4335 root = btr_pcur_get_page(pcur);
4339 == FSP_IBUF_TREE_ROOT_PAGE_NO);
4343 ut_ad(!ibuf->empty);
4347 #ifdef UNIV_IBUF_COUNT_DEBUG
4349 "Decrementing ibuf count of space %lu page %lu\n"
4350 "from %lu by 1\n", space, page_no,
4351 ibuf_count_get(space, page_no));
4352 ibuf_count_set(space, page_no,
4353 ibuf_count_get(space, page_no) - 1);
4359 ut_ad(ibuf_rec_get_page_no(mtr, btr_pcur_get_rec(pcur)) == page_no);
4360 ut_ad(ibuf_rec_get_space(mtr, btr_pcur_get_rec(pcur)) == space);
4363 btr_pcur_store_position(pcur, mtr);
4364 ibuf_btr_pcur_commit_specify_mtr(pcur, mtr);
4367 mutex_enter(&ibuf_mutex);
4369 if (!ibuf_restore_pos(space, page_no, search_tuple,
4372 mutex_exit(&ibuf_mutex);
4374 ut_ad(mtr->state == MTR_COMMITTED);
4378 root = ibuf_tree_root_get(mtr);
4380 btr_cur_pessimistic_delete(&err, TRUE, btr_pcur_get_btr_cur(pcur),
4382 ut_a(err == DB_SUCCESS);
4384 #ifdef UNIV_IBUF_COUNT_DEBUG
4385 ibuf_count_set(space, page_no, ibuf_count_get(space, page_no) - 1);
4387 ibuf_size_update(root, mtr);
4388 mutex_exit(&ibuf_mutex);
4391 ibuf_btr_pcur_commit_specify_mtr(pcur, mtr);
4395 ut_ad(mtr->state == MTR_COMMITTED);
4410 ibuf_merge_or_delete_for_page(
4419 ibool update_ibuf_bitmap)
4428 #ifdef UNIV_IBUF_DEBUG
4432 ibool tablespace_being_deleted = FALSE;
4433 ibool corruption_noticed = FALSE;
4437 ulint mops[IBUF_OP_COUNT];
4438 ulint dops[IBUF_OP_COUNT];
4459 if (ibuf_fixed_addr_page(space, 0, page_no)
4464 if (UNIV_LIKELY(update_ibuf_bitmap)) {
4467 if (ibuf_fixed_addr_page(space, zip_size, page_no)
4477 tablespace_being_deleted = fil_inc_pending_ibuf_merges(space);
4479 if (UNIV_UNLIKELY(tablespace_being_deleted)) {
4484 update_ibuf_bitmap = FALSE;
4491 bitmap_page = ibuf_bitmap_get_map_page(
4492 space, page_no, zip_size, &mtr);
4493 bitmap_bits = ibuf_bitmap_page_get_bits(
4494 bitmap_page, page_no, zip_size,
4495 IBUF_BITMAP_BUFFERED, &mtr);
4502 if (!tablespace_being_deleted) {
4503 fil_decr_pending_ibuf_merges(space);
4510 && (ibuf_fixed_addr_page(space, zip_size, page_no)
4520 search_tuple = ibuf_search_tuple_build(space, page_no, heap);
4522 search_tuple = ibuf_new_search_tuple_build(space, page_no,
4535 if (UNIV_UNLIKELY(fil_page_get_type(block->
frame)
4541 corruption_noticed = TRUE;
4547 fputs(
" InnoDB: Dump of the ibuf bitmap page:\n",
4550 bitmap_page = ibuf_bitmap_get_map_page(space, page_no,
4552 buf_page_print(bitmap_page, 0);
4555 fputs(
"\nInnoDB: Dump of the page:\n", stderr);
4557 buf_page_print(block->
frame, 0);
4560 "InnoDB: Error: corruption in the tablespace."
4561 " Bitmap shows insert\n"
4562 "InnoDB: buffer records to page n:o %lu"
4563 " though the page\n"
4564 "InnoDB: type is %lu, which is"
4565 " not an index leaf page!\n"
4566 "InnoDB: We try to resolve the problem"
4567 " by skipping the insert buffer\n"
4568 "InnoDB: merge for this page."
4569 " Please run CHECK TABLE on your tables\n"
4570 "InnoDB: to determine if they are corrupt"
4572 "InnoDB: Please submit a detailed bug report"
4573 " to http://bugs.mysql.com\n\n",
4576 fil_page_get_type(block->
frame));
4580 memset(mops, 0,
sizeof(mops));
4581 memset(dops, 0,
sizeof(dops));
4589 success = buf_page_get_known_nowait(
4595 buf_block_dbg_add_level(block, SYNC_TREE_NODE);
4600 btr_pcur_open_on_user_rec(
4615 rec = btr_pcur_get_rec(&pcur);
4618 if (ibuf_rec_get_page_no(&mtr, rec) != page_no
4619 || ibuf_rec_get_space(&mtr, rec) != space) {
4623 block->
frame, page_zip, &mtr);
4629 if (UNIV_UNLIKELY(corruption_noticed)) {
4630 fputs(
"InnoDB: Discarding record\n ", stderr);
4631 rec_print_old(stderr, rec);
4632 fputs(
"\nInnoDB: from the insert buffer!\n\n", stderr);
4642 ibuf_op_t op = ibuf_rec_get_op_type(&mtr, rec);
4650 entry = ibuf_build_entry_from_ibuf_rec(
4651 &mtr, rec, heap, &dummy_index);
4657 case IBUF_OP_INSERT:
4658 #ifdef UNIV_IBUF_DEBUG
4660 dummy_index, entry, 0);
4664 ut_a(volume <= 4 * UNIV_PAGE_SIZE
4665 / IBUF_PAGE_SIZE_PER_FREE_SPACE);
4667 ibuf_insert_to_index_page(
4668 entry, block, dummy_index, &mtr);
4671 case IBUF_OP_DELETE_MARK:
4673 entry, block, dummy_index, &mtr);
4676 case IBUF_OP_DELETE:
4677 ibuf_delete(entry, block, dummy_index, &mtr);
4682 ut_ad(rec == btr_pcur_get_rec(&pcur));
4684 ut_ad(ibuf_rec_get_page_no(&mtr, rec)
4686 ut_ad(ibuf_rec_get_space(&mtr, rec) == space);
4688 btr_pcur_store_position(&pcur, &mtr);
4689 ibuf_btr_pcur_commit_specify_mtr(&pcur, &mtr);
4693 success = buf_page_get_known_nowait(
4696 __FILE__, __LINE__, &mtr);
4699 buf_block_dbg_add_level(block, SYNC_TREE_NODE);
4701 if (!ibuf_restore_pos(space, page_no,
4707 ut_ad(mtr.state == MTR_COMMITTED);
4709 ibuf_dummy_index_free(dummy_index);
4720 ibuf_dummy_index_free(dummy_index);
4722 dops[ibuf_rec_get_op_type(&mtr, rec)]++;
4726 if (ibuf_delete_rec(space, page_no, &pcur, search_tuple,
4741 if (UNIV_LIKELY(update_ibuf_bitmap)) {
4744 bitmap_page = ibuf_bitmap_get_map_page(
4745 space, page_no, zip_size, &mtr);
4747 ibuf_bitmap_page_set_bits(
4748 bitmap_page, page_no, zip_size,
4749 IBUF_BITMAP_BUFFERED, FALSE, &mtr);
4752 ulint old_bits = ibuf_bitmap_page_get_bits(
4753 bitmap_page, page_no, zip_size,
4754 IBUF_BITMAP_FREE, &mtr);
4756 ulint new_bits = ibuf_index_page_calc_free(
4759 if (old_bits != new_bits) {
4760 ibuf_bitmap_page_set_bits(
4761 bitmap_page, page_no, zip_size,
4762 IBUF_BITMAP_FREE, new_bits, &mtr);
4771 #ifdef HAVE_ATOMIC_BUILTINS
4772 os_atomic_increment_ulint(&ibuf->n_merges, 1);
4773 ibuf_add_ops(ibuf->n_merged_ops, mops);
4774 ibuf_add_ops(ibuf->n_discarded_ops, dops);
4777 mutex_enter(&ibuf_mutex);
4780 ibuf_add_ops(ibuf->n_merged_ops, mops);
4781 ibuf_add_ops(ibuf->n_discarded_ops, dops);
4783 mutex_exit(&ibuf_mutex);
4786 if (update_ibuf_bitmap && !tablespace_being_deleted) {
4788 fil_decr_pending_ibuf_merges(space);
4791 #ifdef UNIV_IBUF_COUNT_DEBUG
4792 ut_a(ibuf_count_get(space, page_no) == 0);
4803 ibuf_delete_for_discarded_space(
4810 const rec_t* ibuf_rec;
4815 ulint dops[IBUF_OP_COUNT];
4822 search_tuple = ibuf_new_search_tuple_build(space, 0, heap);
4824 memset(dops, 0,
sizeof(dops));
4830 btr_pcur_open_on_user_rec(
4843 ibuf_rec = btr_pcur_get_rec(&pcur);
4846 if (ibuf_rec_get_space(&mtr, ibuf_rec) != space) {
4851 page_no = ibuf_rec_get_page_no(&mtr, ibuf_rec);
4853 dops[ibuf_rec_get_op_type(&mtr, ibuf_rec)]++;
4856 if (ibuf_delete_rec(space, page_no, &pcur, search_tuple,
4876 #ifdef HAVE_ATOMIC_BUILTINS
4877 ibuf_add_ops(ibuf->n_discarded_ops, dops);
4880 mutex_enter(&ibuf_mutex);
4881 ibuf_add_ops(ibuf->n_discarded_ops, dops);
4882 mutex_exit(&ibuf_mutex);
4902 mutex_enter(&ibuf_mutex);
4903 root = ibuf_tree_root_get(&mtr);
4904 mutex_exit(&ibuf_mutex);
4907 ut_a(is_empty == ibuf->empty);
4921 #ifdef UNIV_IBUF_COUNT_DEBUG
4926 mutex_enter(&ibuf_mutex);
4929 "Ibuf: size %lu, free list len %lu,"
4930 " seg size %lu, %lu merges\n",
4932 (ulong) ibuf->free_list_len,
4933 (ulong) ibuf->seg_size,
4934 (ulong) ibuf->n_merges);
4936 fputs(
"merged operations:\n ", file);
4937 ibuf_print_ops(ibuf->n_merged_ops, file);
4939 fputs(
"discarded operations:\n ", file);
4940 ibuf_print_ops(ibuf->n_discarded_ops, file);
4942 #ifdef UNIV_IBUF_COUNT_DEBUG
4943 for (i = 0; i < IBUF_COUNT_N_SPACES; i++) {
4944 for (j = 0; j < IBUF_COUNT_N_PAGES; j++) {
4945 ulint count = ibuf_count_get(i, j);
4949 "Ibuf count for space/page %lu/%lu"
4951 (ulong) i, (ulong) j, (ulong) count);
4957 mutex_exit(&ibuf_mutex);