51 #ifndef UNIV_HOTBACKUP
72 typedef enum btr_op_enum {
75 BTR_INSERT_IGNORE_UNIQUE_OP,
83 UNIV_INTERN ibool btr_cur_print_record_ops = FALSE;
87 UNIV_INTERN ulint btr_cur_n_non_sea = 0;
90 UNIV_INTERN ulint btr_cur_n_sea = 0;
94 UNIV_INTERN ulint btr_cur_n_non_sea_old = 0;
98 UNIV_INTERN ulint btr_cur_n_sea_old = 0;
102 #define BTR_CUR_PAGE_REORGANIZE_LIMIT (UNIV_PAGE_SIZE / 32)
107 #define BTR_BLOB_HDR_PART_LEN 0
109 #define BTR_BLOB_HDR_NEXT_PAGE_NO 4
112 #define BTR_BLOB_HDR_SIZE 8
122 #ifndef UNIV_HOTBACKUP
129 btr_cur_unmark_extern_fields(
135 const ulint* offsets,
142 btr_cur_add_path_info(
153 btr_rec_free_updated_extern_fields(
160 const ulint* offsets,
169 btr_rec_free_externally_stored_fields(
174 const ulint* offsets,
186 btr_rec_get_externally_stored_len(
189 const ulint* offsets);
196 btr_rec_set_deleted_flag(
210 #ifndef UNIV_HOTBACKUP
217 btr_cur_latch_leaves(
236 switch (latch_mode) {
240 get_block =
btr_block_get(space, zip_size, page_no, mode, mtr);
241 #ifdef UNIV_BTR_DEBUG
254 #ifdef UNIV_BTR_DEBUG
265 #ifdef UNIV_BTR_DEBUG
276 #ifdef UNIV_BTR_DEBUG
295 left_page_no, mode, mtr);
297 #ifdef UNIV_BTR_DEBUG
306 get_block =
btr_block_get(space, zip_size, page_no, mode, mtr);
307 #ifdef UNIV_BTR_DEBUG
331 btr_cur_search_to_nth_level(
354 ulint has_search_latch,
379 ulint root_height = 0;
385 ulint offsets_[REC_OFFS_NORMAL_SIZE];
386 ulint* offsets = offsets_;
387 rec_offs_init(offsets_);
391 ut_ad(level == 0 || mode == PAGE_CUR_LE);
392 ut_ad(dict_index_check_search_tuple(index, tuple));
404 switch (UNIV_EXPECT(latch_mode
412 ? BTR_INSERT_IGNORE_UNIQUE_OP
416 btr_op = BTR_DELETE_OP;
420 btr_op = BTR_DELMARK_OP;
443 cursor->
index = index;
445 cursor->ibuf_cnt = ULINT_UNDEFINED;
447 #ifndef BTR_CUR_ADAPT
454 #ifdef BTR_CUR_HASH_ADAPT
456 #ifdef UNIV_SEARCH_PERF_STAT
463 #ifdef PAGE_CUR_LE_OR_EXTENDS
464 && mode != PAGE_CUR_LE_OR_EXTENDS
469 && UNIV_LIKELY(btr_search_enabled)
470 && btr_search_guess_on_hash(index, info, tuple, mode,
472 has_search_latch, mtr)) {
477 || mode != PAGE_CUR_GE);
479 || mode != PAGE_CUR_LE);
481 || mode != PAGE_CUR_LE);
493 if (has_search_latch) {
514 page_cursor = btr_cur_get_page_cur(cursor);
524 height = ULINT_UNDEFINED;
532 page_mode = PAGE_CUR_L;
535 page_mode = PAGE_CUR_LE;
538 #ifdef PAGE_CUR_LE_OR_EXTENDS
539 ut_ad(mode == PAGE_CUR_L || mode == PAGE_CUR_LE
540 || mode == PAGE_CUR_LE_OR_EXTENDS);
542 ut_ad(mode == PAGE_CUR_L || mode == PAGE_CUR_LE);
552 rw_latch = RW_NO_LATCH;
557 rw_latch = latch_mode;
559 if (btr_op != BTR_NO_OP
565 buf_mode = btr_op == BTR_DELETE_OP
574 block = buf_page_get_gen(
575 space, zip_size, page_no, rw_latch, guess, buf_mode,
587 case BTR_INSERT_IGNORE_UNIQUE_OP:
590 if (ibuf_insert(IBUF_OP_INSERT, tuple, index,
591 space, zip_size, page_no,
603 if (ibuf_insert(IBUF_OP_DELETE_MARK, tuple,
604 index, space, zip_size,
605 page_no, cursor->
thr)) {
622 }
else if (ibuf_insert(IBUF_OP_DELETE, tuple,
623 index, space, zip_size,
631 buf_pool_watch_unset(space, page_no);
635 buf_pool_watch_unset(space, page_no);
651 page = buf_block_get_frame(block);
653 if (rw_latch != RW_NO_LATCH) {
654 #ifdef UNIV_ZIP_DEBUG
657 ut_a(!page_zip || page_zip_validate(page_zip, page));
660 buf_block_dbg_add_level(block, SYNC_TREE_NODE);
665 if (UNIV_UNLIKELY(height == ULINT_UNDEFINED)) {
669 root_height = height;
673 if (block != guess) {
680 if (rw_latch == RW_NO_LATCH) {
682 btr_cur_latch_leaves(
683 page, space, zip_size, page_no, latch_mode,
700 block, index, tuple, page_mode, &up_match, &up_bytes,
701 &low_match, &low_bytes, page_cursor);
704 btr_cur_add_path_info(cursor, height, root_height);
712 if (level != height) {
714 const rec_t* node_ptr;
720 node_ptr = page_cur_get_rec(page_cursor);
722 offsets = rec_get_offsets(
723 node_ptr, index, offsets, ULINT_UNDEFINED, &heap);
737 & REC_INFO_MIN_REC_FLAG;
741 = ibuf_rec_get_counter(node_ptr);
743 ut_a(cursor->ibuf_cnt <= 0xFFFF
744 || cursor->ibuf_cnt == ULINT_UNDEFINED);
748 rw_latch = RW_NO_LATCH;
758 space, zip_size, page_no, RW_X_LATCH, mtr);
773 if (UNIV_LIKELY(btr_search_enabled)) {
779 || mode != PAGE_CUR_GE);
781 || mode != PAGE_CUR_LE);
783 || mode != PAGE_CUR_LE);
788 if (UNIV_LIKELY_NULL(heap)) {
792 if (has_search_latch) {
802 btr_cur_open_at_index_side_func(
818 ulint root_height = 0;
823 ulint offsets_[REC_OFFS_NORMAL_SIZE];
824 ulint* offsets = offsets_;
825 rec_offs_init(offsets_);
828 latch_mode = latch_mode & ~BTR_ESTIMATE;
841 page_cursor = btr_cur_get_page_cur(cursor);
842 cursor->
index = index;
848 height = ULINT_UNDEFINED;
853 block = buf_page_get_gen(space, zip_size, page_no,
856 page = buf_block_get_frame(block);
861 if (height == ULINT_UNDEFINED) {
865 root_height = height;
869 btr_cur_latch_leaves(page, space, zip_size, page_no,
870 latch_mode, cursor, mtr);
897 btr_cur_add_path_info(cursor, height,
913 btr_cur_add_path_info(cursor, height, root_height);
918 node_ptr = page_cur_get_rec(page_cursor);
919 offsets = rec_get_offsets(node_ptr, cursor->
index, offsets,
920 ULINT_UNDEFINED, &heap);
925 if (UNIV_LIKELY_NULL(heap)) {
934 btr_cur_open_at_rnd_pos_func(
950 ulint offsets_[REC_OFFS_NORMAL_SIZE];
951 ulint* offsets = offsets_;
952 rec_offs_init(offsets_);
960 page_cursor = btr_cur_get_page_cur(cursor);
961 cursor->
index = index;
967 height = ULINT_UNDEFINED;
973 block = buf_page_get_gen(space, zip_size, page_no,
976 page = buf_block_get_frame(block);
979 if (height == ULINT_UNDEFINED) {
986 btr_cur_latch_leaves(page, space, zip_size, page_no,
987 latch_mode, cursor, mtr);
1001 node_ptr = page_cur_get_rec(page_cursor);
1002 offsets = rec_get_offsets(node_ptr, cursor->
index, offsets,
1003 ULINT_UNDEFINED, &heap);
1008 if (UNIV_LIKELY_NULL(heap)) {
1023 btr_cur_insert_if_possible(
1040 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
1041 page_cursor = btr_cur_get_page_cur(cursor);
1045 cursor->
index, n_ext, mtr);
1047 if (UNIV_UNLIKELY(!rec)) {
1050 if (btr_page_reorganize(block, cursor->
index, mtr)) {
1053 PAGE_CUR_LE, page_cursor);
1056 cursor->
index, n_ext, mtr);
1068 btr_cur_ins_lock_and_undo(
1090 index = cursor->
index;
1094 index, thr, mtr, inherit);
1096 if (err != DB_SUCCESS) {
1107 if (err != DB_SUCCESS) {
1114 if (!(flags & BTR_KEEP_SYS_FLAG)) {
1117 DATA_ROLL_PTR, roll_ptr);
1135 fprintf(stderr,
"Trx with id " TRX_ID_FMT " going to ",
1138 dict_index_name_print(stderr, trx, index);
1152 btr_cur_optimistic_insert(
1190 page = buf_block_get_frame(block);
1191 index = cursor->
index;
1193 #ifdef UNIV_DEBUG_VALGRIND
1195 UNIV_MEM_ASSERT_RW(page, UNIV_PAGE_SIZE);
1196 UNIV_MEM_ASSERT_RW(block->
page.
zip.
data, zip_size);
1200 if (!dtuple_check_typed_no_assert(entry)) {
1201 fputs(
"InnoDB: Error in a tuple to insert into ", stderr);
1202 dict_index_name_print(stderr,
thr_get_trx(thr), index);
1205 if (btr_cur_print_record_ops && thr) {
1206 btr_cur_trx_report(
thr_get_trx(thr), index,
"insert into ");
1207 dtuple_print(stderr, entry);
1211 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
1223 big_rec_vec = dtuple_convert_big_rec(index, entry, &n_ext);
1225 if (UNIV_UNLIKELY(big_rec_vec == NULL)) {
1227 return(DB_TOO_BIG_RECORD);
1233 if (UNIV_UNLIKELY(zip_size)) {
1247 if (UNIV_LIKELY(entry->
n_fields >= n_uniq)
1248 && UNIV_UNLIKELY(REC_NODE_PTR_SIZE
1250 index, entry->
fields, n_uniq,
1256 - (REC_N_NEW_EXTRA_BYTES - 2)
1257 > free_space_zip / 2)) {
1260 dtuple_convert_back_big_rec(
1261 index, entry, big_rec_vec);
1264 return(DB_TOO_BIG_RECORD);
1274 && UNIV_LIKELY(leaf)
1276 && (btr_page_get_split_rec_to_right(cursor, &dummy_rec)
1277 || btr_page_get_split_rec_to_left(cursor, &dummy_rec))) {
1283 dtuple_convert_back_big_rec(index, entry, big_rec_vec);
1289 if (UNIV_UNLIKELY(max_size < BTR_CUR_PAGE_REORGANIZE_LIMIT
1290 || max_size < rec_size)
1298 err = btr_cur_ins_lock_and_undo(flags, cursor, entry,
1299 thr, mtr, &inherit);
1301 if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
1306 page_cursor = btr_cur_get_page_cur(cursor);
1311 const rec_t* page_cursor_rec = page_cur_get_rec(page_cursor);
1314 reorg = page_cursor_rec != page_cur_get_rec(page_cursor);
1316 if (UNIV_UNLIKELY(reorg)) {
1322 if (UNIV_UNLIKELY(!*rec) && UNIV_LIKELY(!reorg)) {
1324 if (UNIV_UNLIKELY(!btr_page_reorganize(block, index, mtr))) {
1340 if (UNIV_UNLIKELY(!*rec)) {
1341 if (UNIV_LIKELY(zip_size != 0)) {
1346 fputs(
"InnoDB: Error: cannot insert tuple ", stderr);
1347 dtuple_print(stderr, entry);
1348 fputs(
" into ", stderr);
1349 dict_index_name_print(stderr,
thr_get_trx(thr), index);
1350 fprintf(stderr,
"\nInnoDB: max insert size %lu\n",
1356 #ifdef BTR_CUR_HASH_ADAPT
1358 btr_search_update_hash_node_on_insert(cursor);
1360 btr_search_update_hash_on_insert(cursor);
1364 if (!(flags & BTR_NO_LOCKING_FLAG) && inherit) {
1370 fprintf(stderr,
"Insert into page %lu, max ins size %lu,"
1371 " rec %lu ind type %lu\n",
1373 rec_size + PAGE_DIR_SLOT_SIZE, index->
type);
1391 ibuf_update_free_bits_zip(block, mtr);
1397 rec_size + PAGE_DIR_SLOT_SIZE);
1401 *big_rec = big_rec_vec;
1414 btr_cur_pessimistic_insert(
1441 ulint n_extents = 0;
1448 ut_ad(mtr_memo_contains(mtr,
1452 MTR_MEMO_PAGE_X_FIX));
1459 err = btr_cur_optimistic_insert(flags, cursor, entry, rec,
1460 big_rec, n_ext, thr, mtr);
1461 if (err != DB_FAIL) {
1469 err = btr_cur_ins_lock_and_undo(flags, cursor, entry,
1470 thr, mtr, &dummy_inh);
1472 if (err != DB_SUCCESS) {
1477 if (!(flags & BTR_NO_UNDO_LOG_FLAG)) {
1484 success = fsp_reserve_free_extents(&n_reserved, index->
space,
1485 n_extents, FSP_NORMAL, mtr);
1487 return(DB_OUT_OF_FILE_SPACE);
1498 if (UNIV_LIKELY_NULL(big_rec_vec)) {
1502 dtuple_convert_back_big_rec(index, entry, big_rec_vec);
1505 big_rec_vec = dtuple_convert_big_rec(index, entry, &n_ext);
1507 if (big_rec_vec == NULL) {
1509 if (n_extents > 0) {
1510 fil_space_release_free_extents(index->
space,
1513 return(DB_TOO_BIG_RECORD);
1521 *rec = btr_root_raise_and_insert(cursor, entry, n_ext, mtr);
1523 *rec = btr_page_split_and_insert(cursor, entry, n_ext, mtr);
1526 if (UNIV_LIKELY_NULL(heap)) {
1532 #ifdef BTR_CUR_ADAPT
1533 btr_search_update_hash_on_insert(cursor);
1535 if (!(flags & BTR_NO_LOCKING_FLAG)) {
1540 if (n_extents > 0) {
1541 fil_space_release_free_extents(index->
space, n_reserved);
1544 *big_rec = big_rec_vec;
1556 btr_cur_upd_lock_and_undo(
1560 const upd_t* update,
1571 ut_ad(cursor && update && thr && roll_ptr);
1574 index = cursor->
index;
1589 if (!(flags & BTR_NO_LOCKING_FLAG)) {
1591 ulint offsets_[REC_OFFS_NORMAL_SIZE];
1592 rec_offs_init(offsets_);
1596 rec_get_offsets(rec, index, offsets_,
1597 ULINT_UNDEFINED, &heap), thr);
1598 if (UNIV_LIKELY_NULL(heap)) {
1601 if (err != DB_SUCCESS) {
1610 index, NULL, update,
1611 cmpl_info, rec, roll_ptr);
1619 btr_cur_update_in_place_log(
1624 const upd_t* update,
1637 1 + DATA_ROLL_PTR_LEN + 14 + 2
1650 index = dict_table_get_first_index(index->
table);
1669 btr_cur_parse_update_in_place(
1687 if (end_ptr < ptr + 1) {
1702 if (end_ptr < ptr + 2) {
1710 ut_a(rec_offset <= UNIV_PAGE_SIZE);
1716 if (!ptr || !page) {
1722 rec = page + rec_offset;
1727 offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
1729 if (!(flags & BTR_KEEP_SYS_FLAG)) {
1731 pos, trx_id, roll_ptr);
1742 #ifndef UNIV_HOTBACKUP
1749 btr_cur_update_alloc_zip(
1795 ibuf_reset_free_bits(block);
1809 btr_cur_update_in_place(
1815 const upd_t* update,
1829 ulint was_delete_marked;
1831 ulint offsets_[REC_OFFS_NORMAL_SIZE];
1832 ulint* offsets = offsets_;
1833 rec_offs_init(offsets_);
1836 index = cursor->
index;
1842 offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
1844 if (btr_cur_print_record_ops && thr) {
1845 btr_cur_trx_report(trx, index,
"update ");
1854 if (UNIV_LIKELY_NULL(page_zip)
1855 && !btr_cur_update_alloc_zip(page_zip, block, index,
1857 return(DB_ZIP_OVERFLOW);
1861 err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info,
1862 thr, mtr, &roll_ptr);
1863 if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
1865 if (UNIV_LIKELY_NULL(heap)) {
1880 btr_search_update_hash_on_delete(cursor);
1886 if (!(flags & BTR_KEEP_SYS_FLAG)) {
1888 index, offsets, trx, roll_ptr);
1903 ibuf_update_free_bits_zip(block, mtr);
1906 btr_cur_update_in_place_log(flags, rec, index, update,
1907 trx, roll_ptr, mtr);
1909 if (was_delete_marked
1911 buf_block_get_frame(block)))) {
1915 btr_cur_unmark_extern_fields(page_zip,
1916 rec, index, offsets, mtr);
1919 if (UNIV_LIKELY_NULL(heap)) {
1936 btr_cur_optimistic_update(
1942 const upd_t* update,
1969 page = buf_block_get_frame(block);
1971 index = cursor->
index;
1973 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
1978 offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
1981 if (btr_cur_print_record_ops && thr) {
1982 btr_cur_trx_report(
thr_get_trx(thr), index,
"update ");
1995 return(btr_cur_update_in_place(flags, cursor, update,
1996 cmpl_info, thr, mtr));
2005 return(DB_OVERFLOW);
2009 if (
dfield_is_ext(&upd_get_nth_field(update, i)->new_val)) {
2015 page_cursor = btr_cur_get_page_cur(cursor);
2031 #ifdef UNIV_ZIP_DEBUG
2032 ut_a(!page_zip || page_zip_validate(page_zip, page));
2035 if (UNIV_LIKELY_NULL(page_zip)
2036 && !btr_cur_update_alloc_zip(page_zip, block, index,
2037 new_rec_size, TRUE, mtr)) {
2038 err = DB_ZIP_OVERFLOW;
2042 if (UNIV_UNLIKELY(new_rec_size
2051 - old_rec_size + new_rec_size
2060 max_size = old_rec_size
2063 if (!(((max_size >= BTR_CUR_PAGE_REORGANIZE_LIMIT)
2064 && (max_size >= new_rec_size))
2076 err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info,
2077 thr, mtr, &roll_ptr);
2078 if (err != DB_SUCCESS) {
2089 btr_search_update_hash_on_delete(cursor);
2095 rec_offs_make_valid(page_cur_get_rec(page_cursor), index, offsets);
2103 if (!(flags & BTR_KEEP_SYS_FLAG)) {
2111 rec = btr_cur_insert_if_possible(cursor, new_entry, 0, mtr);
2117 ibuf_update_free_bits_zip(block, mtr);
2140 btr_cur_pess_upd_restore_supremum(
2152 page = buf_block_get_frame(block);
2167 #ifdef UNIV_BTR_DEBUG
2173 ut_ad(mtr_memo_contains(mtr, prev_block, MTR_MEMO_PAGE_X_FIX));
2176 PAGE_HEAP_NO_SUPREMUM,
2189 btr_cur_pessimistic_update(
2197 const upd_t* update,
2220 ulint n_extents = 0;
2223 ulint* offsets = NULL;
2228 page = buf_block_get_frame(block);
2231 index = cursor->
index;
2235 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
2236 #ifdef UNIV_ZIP_DEBUG
2237 ut_a(!page_zip || page_zip_validate(page_zip, page));
2242 optim_err = btr_cur_optimistic_update(flags, cursor, update,
2243 cmpl_info, thr, mtr);
2245 switch (optim_err) {
2248 case DB_ZIP_OVERFLOW:
2255 err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info,
2256 thr, mtr, &roll_ptr);
2257 if (err != DB_SUCCESS) {
2262 if (optim_err == DB_OVERFLOW) {
2271 if (flags & BTR_NO_UNDO_LOG_FLAG) {
2272 reserve_flag = FSP_CLEANING;
2274 reserve_flag = FSP_NORMAL;
2277 if (!fsp_reserve_free_extents(&n_reserved, index->
space,
2278 n_extents, reserve_flag, mtr)) {
2279 return(DB_OUT_OF_FILE_SPACE);
2286 offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, heap);
2296 rec_offs_make_valid(rec, index, offsets);
2306 if (!(flags & BTR_KEEP_SYS_FLAG)) {
2321 ut_ad(big_rec_vec == NULL);
2323 btr_rec_free_updated_extern_fields(
2324 index, rec, page_zip, offsets, update,
2332 offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, heap);
2333 n_ext += btr_push_update_extern_fields(new_entry, update, *heap);
2335 if (UNIV_LIKELY_NULL(page_zip)) {
2349 big_rec_vec = dtuple_convert_big_rec(index, new_entry, &n_ext);
2350 if (UNIV_UNLIKELY(big_rec_vec == NULL)) {
2352 err = DB_TOO_BIG_RECORD;
2353 goto return_after_reservations;
2368 btr_search_update_hash_on_delete(cursor);
2370 #ifdef UNIV_ZIP_DEBUG
2371 ut_a(!page_zip || page_zip_validate(page_zip, page));
2373 page_cursor = btr_cur_get_page_cur(cursor);
2379 rec = btr_cur_insert_if_possible(cursor, new_entry, n_ext, mtr);
2385 offsets = rec_get_offsets(rec, index, offsets,
2386 ULINT_UNDEFINED, heap);
2391 btr_cur_unmark_extern_fields(page_zip,
2392 rec, index, offsets, mtr);
2395 btr_cur_compress_if_useful(cursor, mtr);
2400 ibuf_update_free_bits_zip(block, mtr);
2404 goto return_after_reservations;
2406 ut_a(optim_err != DB_UNDERFLOW);
2411 ibuf_reset_free_bits(block);
2422 err = btr_cur_pessimistic_insert(BTR_NO_UNDO_LOG_FLAG
2423 | BTR_NO_LOCKING_FLAG
2424 | BTR_KEEP_SYS_FLAG,
2425 cursor, new_entry, &rec,
2426 &dummy_big_rec, n_ext, NULL, mtr);
2428 ut_a(err == DB_SUCCESS);
2429 ut_a(dummy_big_rec == NULL);
2449 #ifdef UNIV_ZIP_DEBUG
2450 ut_a(!page_zip || page_zip_validate(page_zip, page));
2451 page = buf_block_get_frame(rec_block);
2455 offsets = rec_get_offsets(rec, index, offsets,
2456 ULINT_UNDEFINED, heap);
2457 btr_cur_unmark_extern_fields(page_zip,
2458 rec, index, offsets, mtr);
2474 return_after_reservations:
2475 #ifdef UNIV_ZIP_DEBUG
2476 ut_a(!page_zip || page_zip_validate(page_zip, page));
2479 if (n_extents > 0) {
2480 fil_space_release_free_extents(index->
space, n_reserved);
2483 *big_rec = big_rec_vec;
2495 btr_cur_del_mark_set_clust_rec_log(
2515 1 + 1 + DATA_ROLL_PTR_LEN
2543 btr_cur_parse_del_mark_set_clust_rec(
2562 if (end_ptr < ptr + 2) {
2579 if (end_ptr < ptr + 2) {
2587 ut_a(offset <= UNIV_PAGE_SIZE);
2590 rec = page + offset;
2596 btr_rec_set_deleted_flag(rec, page_zip, val);
2598 if (!(flags & BTR_KEEP_SYS_FLAG)) {
2600 ulint offsets_[REC_OFFS_NORMAL_SIZE];
2601 rec_offs_init(offsets_);
2605 rec_get_offsets(rec, index, offsets_,
2606 ULINT_UNDEFINED, &heap),
2607 pos, trx_id, roll_ptr);
2608 if (UNIV_LIKELY_NULL(heap)) {
2617 #ifndef UNIV_HOTBACKUP
2626 btr_cur_del_mark_set_clust_rec(
2642 ulint offsets_[REC_OFFS_NORMAL_SIZE];
2643 ulint* offsets = offsets_;
2644 rec_offs_init(offsets_);
2647 index = cursor->
index;
2649 offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
2652 if (btr_cur_print_record_ops && thr) {
2653 btr_cur_trx_report(
thr_get_trx(thr), index,
"del mark ");
2663 rec, index, offsets, thr);
2665 if (err != DB_SUCCESS) {
2671 index, NULL, NULL, 0, rec,
2673 if (err != DB_SUCCESS) {
2686 btr_rec_set_deleted_flag(rec, page_zip, val);
2690 if (!(flags & BTR_KEEP_SYS_FLAG)) {
2692 index, offsets, trx, roll_ptr);
2699 btr_cur_del_mark_set_clust_rec_log(flags, rec, index, val, trx,
2703 if (UNIV_LIKELY_NULL(heap)) {
2714 btr_cur_del_mark_set_sec_rec_log(
2749 btr_cur_parse_del_mark_set_sec_rec(
2760 if (end_ptr < ptr + 3) {
2771 ut_a(offset <= UNIV_PAGE_SIZE);
2774 rec = page + offset;
2780 btr_rec_set_deleted_flag(rec, page_zip, val);
2786 #ifndef UNIV_HOTBACKUP
2792 btr_cur_del_mark_set_sec_rec(
2808 if (btr_cur_print_record_ops && thr) {
2817 rec, cursor->
index, thr, mtr);
2818 if (err != DB_SUCCESS) {
2836 btr_cur_del_mark_set_sec_rec_log(rec, val, mtr);
2846 btr_cur_set_deleted_flag_for_ibuf(
2859 btr_rec_set_deleted_flag(rec, page_zip, val);
2861 btr_cur_del_mark_set_sec_rec_log(rec, val, mtr);
2875 btr_cur_compress_if_useful(
2882 ut_ad(mtr_memo_contains(mtr,
2886 MTR_MEMO_PAGE_X_FIX));
2888 return(btr_cur_compress_recommendation(cursor, mtr)
2889 && btr_compress(cursor, mtr));
2899 btr_cur_optimistic_delete(
2913 ulint offsets_[REC_OFFS_NORMAL_SIZE];
2914 ulint* offsets = offsets_;
2915 ibool no_compress_needed;
2916 rec_offs_init(offsets_);
2919 MTR_MEMO_PAGE_X_FIX));
2927 offsets = rec_get_offsets(rec, cursor->
index, offsets,
2928 ULINT_UNDEFINED, &heap);
2931 && btr_cur_can_delete_without_compress(
2934 if (no_compress_needed) {
2936 page_t* page = buf_block_get_frame(block);
2942 btr_search_update_hash_on_delete(cursor);
2948 #ifdef UNIV_ZIP_DEBUG
2949 ut_a(!page_zip || page_zip_validate(page_zip, page));
2952 cursor->
index, offsets, mtr);
2953 #ifdef UNIV_ZIP_DEBUG
2954 ut_a(!page_zip || page_zip_validate(page_zip, page));
2964 }
else if (page_zip) {
2965 ibuf_update_free_bits_zip(block, mtr);
2967 ibuf_update_free_bits_low(block, max_ins, mtr);
2971 if (UNIV_LIKELY_NULL(heap)) {
2975 return(no_compress_needed);
2988 btr_cur_pessimistic_delete(
2995 ibool has_reserved_extents,
3012 ulint n_extents = 0;
3021 page = buf_block_get_frame(block);
3026 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
3027 if (!has_reserved_extents) {
3034 success = fsp_reserve_free_extents(&n_reserved,
3039 *err = DB_OUT_OF_FILE_SPACE;
3048 #ifdef UNIV_ZIP_DEBUG
3049 ut_a(!page_zip || page_zip_validate(page_zip, page));
3052 offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
3055 btr_rec_free_externally_stored_fields(index,
3056 rec, offsets, page_zip,
3058 #ifdef UNIV_ZIP_DEBUG
3059 ut_a(!page_zip || page_zip_validate(page_zip, page));
3070 btr_discard_page(cursor, mtr);
3075 goto return_after_reservations;
3083 page_get_infimum_rec(page)))) {
3098 btr_set_min_rec_mark(next_rec, mtr);
3105 btr_node_ptr_delete(index, block, mtr);
3107 node_ptr = dict_index_build_node_ptr(
3111 btr_insert_on_non_leaf_level(index,
3112 level + 1, node_ptr, mtr);
3116 btr_search_update_hash_on_delete(cursor);
3119 #ifdef UNIV_ZIP_DEBUG
3120 ut_a(!page_zip || page_zip_validate(page_zip, page));
3123 ut_ad(btr_check_node_ptr(index, block, mtr));
3127 return_after_reservations:
3131 ret = btr_cur_compress_if_useful(cursor, mtr);
3134 if (n_extents > 0) {
3135 fil_space_release_free_extents(index->
space, n_reserved);
3146 btr_cur_add_path_info(
3163 slot->
nth_rec = ULINT_UNDEFINED;
3170 slot = cursor->
path_arr + root_height + 1;
3171 slot->
nth_rec = ULINT_UNDEFINED;
3176 slot = cursor->
path_arr + (root_height - height);
3200 btr_estimate_n_rows_in_range_on_level(
3205 ib_int64_t n_rows_on_prev_level,
3210 ibool* is_n_rows_exact)
3228 *is_n_rows_exact = TRUE;
3245 zip_size = fil_space_get_zip_size(space);
3251 # define N_PAGES_READ_LIMIT 10
3264 block =
buf_page_get(space, zip_size, page_no, RW_S_LATCH,
3267 page = buf_block_get_frame(block);
3286 if (page_no != slot1->
page_no) {
3296 if (n_pages_read == N_PAGES_READ_LIMIT
3305 }
while (page_no != slot2->
page_no);
3311 *is_n_rows_exact = FALSE;
3315 if (n_pages_read > 0) {
3319 n_rows = n_rows_on_prev_level
3320 * n_rows / n_pages_read;
3335 btr_estimate_n_rows_in_range(
3350 ulint divergence_level;
3352 ibool is_n_rows_exact;
3362 btr_cur_search_to_nth_level(index, 0, tuple1, mode1,
3365 __FILE__, __LINE__, &mtr);
3367 btr_cur_open_at_index_side(TRUE, index,
3380 btr_cur_search_to_nth_level(index, 0, tuple2, mode2,
3383 __FILE__, __LINE__, &mtr);
3385 btr_cur_open_at_index_side(FALSE, index,
3395 is_n_rows_exact = TRUE;
3398 diverged_lot = FALSE;
3400 divergence_level = 1000000;
3402 for (i = 0; ; i++) {
3408 if (slot1->
nth_rec == ULINT_UNDEFINED
3409 || slot2->
nth_rec == ULINT_UNDEFINED) {
3411 if (i > divergence_level + 1 && !is_n_rows_exact) {
3416 n_rows = n_rows * 2;
3424 && !is_n_rows_exact) {
3447 diverged_lot = TRUE;
3448 divergence_level = i;
3462 }
else if (diverged && !diverged_lot) {
3467 diverged_lot = TRUE;
3468 divergence_level = i;
3481 }
else if (diverged_lot) {
3483 n_rows = btr_estimate_n_rows_in_range_on_level(
3484 index, slot1, slot2, n_rows,
3496 btr_estimate_number_of_different_key_vals(
3504 ulint matched_fields;
3505 ulint matched_bytes;
3507 ullint n_sample_pages;
3508 ulint not_empty_flag = 0;
3509 ulint total_external_size = 0;
3515 ulint offsets_rec_[REC_OFFS_NORMAL_SIZE];
3516 ulint offsets_next_rec_[REC_OFFS_NORMAL_SIZE];
3517 ulint* offsets_rec = offsets_rec_;
3518 ulint* offsets_next_rec= offsets_next_rec_;
3519 rec_offs_init(offsets_rec_);
3520 rec_offs_init(offsets_next_rec_);
3524 n_diff = (ib_int64_t *)
mem_zalloc((n_cols + 1) *
sizeof(ib_int64_t));
3535 n_sample_pages = srv_stats_sample_pages;
3540 for (i = 0; i < n_sample_pages; i++) {
3554 supremum = page_get_supremum_rec(page);
3557 if (rec != supremum) {
3559 offsets_rec = rec_get_offsets(rec, index, offsets_rec,
3560 ULINT_UNDEFINED, &heap);
3563 while (rec != supremum) {
3565 if (next_rec == supremum) {
3571 offsets_next_rec = rec_get_offsets(next_rec, index,
3576 offsets_rec, offsets_next_rec,
3577 index, &matched_fields,
3580 for (j = matched_fields + 1; j <= n_cols; j++) {
3588 += btr_rec_get_externally_stored_len(
3596 ulint* offsets_tmp = offsets_rec;
3597 offsets_rec = offsets_next_rec;
3598 offsets_next_rec = offsets_tmp;
3621 offsets_rec = rec_get_offsets(rec, index, offsets_rec,
3622 ULINT_UNDEFINED, &heap);
3623 total_external_size += btr_rec_get_externally_stored_len(
3636 for (j = 0; j <= n_cols; j++) {
3640 + n_sample_pages - 1
3641 + total_external_size
3644 + total_external_size));
3655 / (10 * (n_sample_pages
3656 + total_external_size));
3658 if (add_on > n_sample_pages) {
3659 add_on = n_sample_pages;
3666 if (UNIV_LIKELY_NULL(heap)) {
3678 btr_rec_get_externally_stored_len(
3681 const ulint* offsets)
3687 ulint total_extern_len = 0;
3693 for (i = 0; i < n_fields; i++) {
3696 data = rec_get_nth_field(rec, offsets, i, &local_len);
3708 return(total_extern_len / UNIV_PAGE_SIZE);
3715 btr_cur_set_ownership_of_extern_field(
3721 const ulint* offsets,
3730 data = rec_get_nth_field(rec, offsets, i, &local_len);
3744 if (UNIV_LIKELY_NULL(page_zip)) {
3747 }
else if (UNIV_LIKELY(mtr != NULL)) {
3764 btr_cur_mark_extern_inherited_fields(
3770 const ulint* offsets,
3771 const upd_t* update,
3777 ibool change_ownership = FALSE;
3789 for (i = 0; i < n; i++) {
3797 if (upd_get_nth_field(update, j)
3805 btr_cur_set_ownership_of_extern_field(
3806 page_zip, rec, index, offsets, i, FALSE, mtr);
3808 change_ownership = TRUE;
3814 return(change_ownership);
3823 btr_cur_mark_dtuple_inherited_extern(
3827 const upd_t* update)
3833 dfield_t* dfield = dtuple_get_nth_field(entry, i);
3845 if (upd_get_nth_field(update, j)->field_no == i) {
3851 data = (
unsigned char *)dfield_get_data(dfield);
3867 btr_cur_unmark_extern_fields(
3873 const ulint* offsets,
3887 for (i = 0; i < n; i++) {
3890 btr_cur_set_ownership_of_extern_field(
3891 page_zip, rec, index, offsets, i, TRUE, mtr);
3900 btr_cur_unmark_dtuple_extern_fields(
3907 dfield_t* dfield = dtuple_get_nth_field(entry, i);
3910 byte* data = (
unsigned char *)dfield_get_data(dfield);
3926 btr_push_update_extern_fields(
3945 = dtuple_get_nth_field(tuple, uf->
field_no);
3976 data = (
unsigned char *)dfield_get_data(field);
4004 btr_blob_get_part_len(
4006 const byte* blob_header)
4016 btr_blob_get_next_page_no(
4018 const byte* blob_header)
4038 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
4043 mutex_enter(&block->
mutex);
4053 if (buf_LRU_free_block(&block->
page, all, NULL)
4059 buf_LRU_free_block(&block->
page, FALSE, NULL);
4064 mutex_exit(&block->
mutex);
4075 btr_store_big_rec_extern_fields(
4081 const ulint* offsets,
4109 ut_ad(mtr_memo_contains(local_mtr, rec_block, MTR_MEMO_PAGE_X_FIX));
4122 if (UNIV_LIKELY_NULL(page_zip)) {
4133 err = deflateInit2(&c_stream, Z_DEFAULT_COMPRESSION,
4134 Z_DEFLATED, 15, 7, Z_DEFAULT_STRATEGY);
4141 for (i = 0; i < big_rec_vec->
n_fields; i++) {
4146 field_ref = rec_get_nth_field(
4151 field_ref += local_len;
4153 extern_len = big_rec_vec->
fields[i].
len;
4154 UNIV_MEM_ASSERT_RW(big_rec_vec->
fields[i].
data,
4157 ut_a(extern_len > 0);
4161 if (UNIV_LIKELY_NULL(page_zip)) {
4162 int err = deflateReset(&c_stream);
4165 c_stream.next_in = (Bytef *) big_rec_vec->
fields[i].
data;
4166 c_stream.avail_in = extern_len;
4176 hint_page_no = 1 + rec_page_no;
4178 hint_page_no = prev_page_no + 1;
4181 block = btr_page_alloc(index, hint_page_no,
4182 FSP_NO_DIR, 0, &mtr);
4183 if (UNIV_UNLIKELY(block == NULL)) {
4187 if (UNIV_LIKELY_NULL(page_zip)) {
4188 deflateEnd(&c_stream);
4192 return(DB_OUT_OF_FILE_SPACE);
4196 page = buf_block_get_frame(block);
4205 buf_block_dbg_add_level(prev_block,
4206 SYNC_EXTERN_STORAGE);
4207 prev_page = buf_block_get_frame(prev_block);
4209 if (UNIV_LIKELY_NULL(page_zip)) {
4220 + BTR_BLOB_HDR_NEXT_PAGE_NO,
4226 if (UNIV_LIKELY_NULL(page_zip)) {
4246 c_stream.next_out = page
4252 err = deflate(&c_stream, Z_FINISH);
4253 ut_a(err == Z_OK || err == Z_STREAM_END);
4254 ut_a(err == Z_STREAM_END
4255 || c_stream.avail_out == 0);
4288 - c_stream.avail_out,
4289 0, c_stream.avail_out);
4298 ut_ad(blob_page_zip);
4301 memcpy(blob_page_zip->
data, page,
4304 if (err == Z_OK && prev_page_no !=
FIL_NULL) {
4312 buf_block_dbg_add_level(rec_block,
4313 SYNC_NO_ORDER_CHECK);
4315 if (err == Z_STREAM_END) {
4341 page_zip, rec, index, offsets,
4345 prev_page_no = page_no;
4349 btr_blob_free(block, FALSE, &mtr);
4351 if (err == Z_STREAM_END) {
4359 if (extern_len > (UNIV_PAGE_SIZE
4363 store_len = UNIV_PAGE_SIZE
4368 store_len = extern_len;
4372 + BTR_BLOB_HDR_SIZE,
4379 + BTR_BLOB_HDR_PART_LEN,
4382 + BTR_BLOB_HDR_NEXT_PAGE_NO,
4385 extern_len -= store_len;
4390 buf_block_dbg_add_level(rec_block,
4391 SYNC_NO_ORDER_CHECK);
4418 prev_page_no = page_no;
4422 if (extern_len == 0) {
4429 if (UNIV_LIKELY_NULL(page_zip)) {
4430 deflateEnd(&c_stream);
4441 btr_check_blob_fil_page_type(
4448 ulint type = fil_page_get_type(page);
4454 ulint flags = fil_space_get_flags(space_id);
4467 " InnoDB: FIL_PAGE_TYPE=%lu"
4468 " on BLOB %s space %lu page %lu flags %lx\n",
4469 (ulong) type, read ?
"read" :
"purge",
4470 (ulong) space_id, (ulong) page_no, (ulong) flags);
4482 btr_free_externally_stored_field(
4495 const ulint* offsets,
4516 ut_ad(mtr_memo_contains_page(local_mtr, field_ref,
4517 MTR_MEMO_PAGE_X_FIX));
4522 const byte* f = rec_get_nth_field(rec, offsets,
4527 ut_ad(f == field_ref);
4531 if (UNIV_UNLIKELY(!memcmp(field_ref, field_ref_zero,
4543 ext_zip_size = fil_space_get_zip_size(space_id);
4552 ext_zip_size = rec_zip_size;
4562 #ifdef UNIV_SYNC_DEBUG
4569 #ifdef UNIV_SYNC_DEBUG
4578 buf_block_dbg_add_level(rec_block, SYNC_NO_ORDER_CHECK);
4597 ext_block =
buf_page_get(space_id, ext_zip_size, page_no,
4599 buf_block_dbg_add_level(ext_block, SYNC_EXTERN_STORAGE);
4600 page = buf_block_get_frame(ext_block);
4605 switch (fil_page_get_type(page)) {
4614 btr_page_free_low(index, ext_block, 0, &mtr);
4616 if (UNIV_LIKELY(page_zip != NULL)) {
4634 btr_check_blob_fil_page_type(space_id, page_no, page,
4638 page + FIL_PAGE_DATA
4639 + BTR_BLOB_HDR_NEXT_PAGE_NO);
4645 btr_page_free_low(index, ext_block, 0, &mtr);
4661 btr_blob_free(ext_block, TRUE, &mtr);
4669 btr_rec_free_externally_stored_fields(
4674 const ulint* offsets,
4686 ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX));
4692 for (i = 0; i < n_fields; i++) {
4696 = rec_get_nth_field(rec, offsets, i, &len);
4699 btr_free_externally_stored_field(
4701 rec, offsets, page_zip, i, rb_ctx, mtr);
4711 btr_rec_free_updated_extern_fields(
4718 const ulint* offsets,
4719 const upd_t* update,
4728 ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX));
4734 for (i = 0; i < n_fields; i++) {
4735 const upd_field_t* ufield = upd_get_nth_field(update, i);
4739 byte* data = rec_get_nth_field(
4740 rec, offsets, ufield->
field_no, &len);
4743 btr_free_externally_stored_field(
4745 rec, offsets, page_zip,
4757 btr_copy_blob_prefix(
4766 ulint copied_len = 0;
4772 const byte* blob_header;
4778 block =
buf_page_get(space_id, 0, page_no, RW_S_LATCH, &mtr);
4779 buf_block_dbg_add_level(block, SYNC_EXTERN_STORAGE);
4780 page = buf_block_get_frame(block);
4782 btr_check_blob_fil_page_type(space_id, page_no, page, TRUE);
4784 blob_header = page + offset;
4785 part_len = btr_blob_get_part_len(blob_header);
4786 copy_len =
ut_min(part_len, len - copied_len);
4788 memcpy(buf + copied_len,
4789 blob_header + BTR_BLOB_HDR_SIZE, copy_len);
4790 copied_len += copy_len;
4792 page_no = btr_blob_get_next_page_no(blob_header);
4796 if (page_no ==
FIL_NULL || copy_len != part_len) {
4797 UNIV_MEM_ASSERT_RW(buf, copied_len);
4806 ut_ad(copied_len <= len);
4815 btr_copy_zblob_prefix(
4827 ut_ad(zip_size <= UNIV_PAGE_SIZE);
4839 bpage = buf_page_get_zip(space_id, zip_size, page_no);
4841 if (UNIV_UNLIKELY(!bpage)) {
4844 " InnoDB: Cannot load"
4846 " page %lu space %lu\n",
4847 (ulong) page_no, (ulong) space_id);
4852 (fil_page_get_type(bpage->
zip.
data) != page_type)) {
4855 " InnoDB: Unexpected type %lu of"
4857 " page %lu space %lu\n",
4858 (ulong) fil_page_get_type(bpage->
zip.
data),
4859 (ulong) page_no, (ulong) space_id);
4874 d_stream->next_in = bpage->
zip.
data + offset;
4875 d_stream->avail_in = zip_size - offset;
4877 err = inflate(d_stream, Z_NO_FLUSH);
4880 if (!d_stream->avail_out) {
4893 " InnoDB: inflate() of"
4895 " page %lu space %lu returned %d (%s)\n",
4896 (ulong) page_no, (ulong) space_id,
4897 err, d_stream->msg);
4903 if (!d_stream->avail_in) {
4906 " InnoDB: unexpected end of"
4908 " page %lu space %lu\n",
4912 err = inflate(d_stream, Z_FINISH);
4932 page_no = next_page_no;
4945 btr_copy_externally_stored_field_prefix_low(
4956 if (UNIV_UNLIKELY(len == 0)) {
4960 if (UNIV_UNLIKELY(zip_size)) {
4970 err = inflateInit(&d_stream);
4973 d_stream.next_out = buf;
4974 d_stream.avail_out = len;
4975 d_stream.avail_in = 0;
4977 btr_copy_zblob_prefix(&d_stream, zip_size,
4978 space_id, page_no, offset);
4979 inflateEnd(&d_stream);
4981 UNIV_MEM_ASSERT_RW(buf, d_stream.total_out);
4982 return(d_stream.total_out);
4984 return(btr_copy_blob_prefix(buf, len, space_id,
4996 btr_copy_externally_stored_field_prefix(
5016 if (UNIV_UNLIKELY(local_len >= len)) {
5017 memcpy(buf, data, len);
5021 memcpy(buf, data, local_len);
5041 + btr_copy_externally_stored_field_prefix_low(buf + local_len,
5054 btr_copy_externally_stored_field(
5087 buf = (
unsigned char *)
mem_heap_alloc(heap, local_len + extern_len);
5089 memcpy(buf, data, local_len);
5091 + btr_copy_externally_stored_field_prefix_low(buf + local_len,
5105 btr_rec_copy_externally_stored_field(
5109 const ulint* offsets,
5130 data = rec_get_nth_field(rec, offsets, no, &local_len);
5144 return(btr_copy_externally_stored_field(len, data,
5145 zip_size, local_len, heap));