52 #ifndef UNIV_HOTBACKUP
85 UNIV_INTERN ibool btr_cur_print_record_ops = FALSE;
104 UNIV_INTERN uint btr_cur_limit_optimistic_insert_debug = 0;
109 #define BTR_CUR_PAGE_REORGANIZE_LIMIT (UNIV_PAGE_SIZE / 32)
114 #define BTR_BLOB_HDR_PART_LEN 0
116 #define BTR_BLOB_HDR_NEXT_PAGE_NO 4
119 #define BTR_BLOB_HDR_SIZE 8
129 #define BTR_TABLE_STATS_FROM_SAMPLE(value, index, sample, ext_size, not_empty)\
130 (((value) * (ib_int64_t) index->stat_n_leaf_pages \
131 + (sample) - 1 + (ext_size) + (not_empty)) / ((sample) + (ext_size)))
146 #ifndef UNIV_HOTBACKUP
153 btr_cur_unmark_extern_fields(
166 btr_cur_add_path_info(
177 btr_rec_free_updated_extern_fields(
193 btr_rec_free_externally_stored_fields(
210 btr_rec_get_externally_stored_len(
234 #ifndef UNIV_HOTBACKUP
241 btr_cur_latch_leaves(
260 switch (latch_mode) {
265 space, zip_size, page_no, mode, cursor->
index, mtr);
266 #ifdef UNIV_BTR_DEBUG
277 space, zip_size, left_page_no,
278 RW_X_LATCH, cursor->
index, mtr);
279 #ifdef UNIV_BTR_DEBUG
289 space, zip_size, page_no,
290 RW_X_LATCH, cursor->
index, mtr);
291 #ifdef UNIV_BTR_DEBUG
300 space, zip_size, right_page_no,
301 RW_X_LATCH, cursor->
index, mtr);
302 #ifdef UNIV_BTR_DEBUG
322 left_page_no, mode, cursor->
index, mtr);
324 #ifdef UNIV_BTR_DEBUG
334 space, zip_size, page_no, mode, cursor->
index, mtr);
335 #ifdef UNIV_BTR_DEBUG
382 ulint has_search_latch,
407 ulint root_height = 0;
413 ulint offsets_[REC_OFFS_NORMAL_SIZE];
415 rec_offs_init(offsets_);
419 ut_ad(level == 0 || mode == PAGE_CUR_LE);
420 ut_ad(dict_index_check_search_tuple(index, tuple));
435 ibool s_latch_by_caller;
439 ut_ad(!s_latch_by_caller
446 switch (UNIV_EXPECT(latch_mode
478 latch_mode = BTR_LATCH_MODE_WITHOUT_FLAGS(latch_mode);
480 ut_ad(!s_latch_by_caller
487 #ifndef BTR_CUR_ADAPT
494 #ifdef BTR_CUR_HASH_ADAPT
496 # ifdef UNIV_SEARCH_PERF_STAT
503 # ifdef PAGE_CUR_LE_OR_EXTENDS
504 && mode != PAGE_CUR_LE_OR_EXTENDS
512 has_search_latch, mtr)) {
517 || mode != PAGE_CUR_GE);
519 || mode != PAGE_CUR_LE);
521 || mode != PAGE_CUR_LE);
533 if (has_search_latch) {
543 switch (latch_mode) {
553 if (!s_latch_by_caller) {
558 page_cursor = btr_cur_get_page_cur(cursor);
568 height = ULINT_UNDEFINED;
576 page_mode = PAGE_CUR_L;
579 page_mode = PAGE_CUR_LE;
582 #ifdef PAGE_CUR_LE_OR_EXTENDS
583 ut_ad(mode == PAGE_CUR_L || mode == PAGE_CUR_LE
584 || mode == PAGE_CUR_LE_OR_EXTENDS);
586 ut_ad(mode == PAGE_CUR_L || mode == PAGE_CUR_LE);
596 rw_latch = RW_NO_LATCH;
601 rw_latch = latch_mode;
619 space, zip_size, page_no, rw_latch, guess, buf_mode,
635 space, zip_size, page_no,
648 index, space, zip_size,
649 page_no, cursor->
thr)) {
667 index, space, zip_size,
695 page = buf_block_get_frame(block);
697 if (rw_latch != RW_NO_LATCH) {
698 #ifdef UNIV_ZIP_DEBUG
701 ut_a(!page_zip || page_zip_validate(page_zip, page, index));
704 buf_block_dbg_add_level(
706 ? SYNC_IBUF_TREE_NODE : SYNC_TREE_NODE);
712 if (UNIV_UNLIKELY(height == ULINT_UNDEFINED)) {
715 height = btr_page_get_level(page, mtr);
716 root_height = height;
720 if (block != guess) {
727 if (rw_latch == RW_NO_LATCH) {
729 btr_cur_latch_leaves(
730 page, space, zip_size, page_no, latch_mode,
734 switch (latch_mode) {
739 if (!s_latch_by_caller) {
751 block, index, tuple, page_mode, &up_match, &up_bytes,
752 &low_match, &low_bytes, page_cursor);
755 btr_cur_add_path_info(cursor, height, root_height);
760 ut_ad(height == btr_page_get_level(page_cur_get_page(page_cursor),
763 if (level != height) {
765 const rec_t* node_ptr;
771 node_ptr = page_cur_get_rec(page_cursor);
773 offsets = rec_get_offsets(
774 node_ptr, index, offsets, ULINT_UNDEFINED, &heap);
786 rw_latch = RW_NO_LATCH;
796 space, zip_size, page_no, RW_X_LATCH, index, mtr);
798 page = buf_block_get_frame(child_block);
816 || mode != PAGE_CUR_GE);
818 || mode != PAGE_CUR_LE);
820 || mode != PAGE_CUR_LE);
825 if (UNIV_LIKELY_NULL(heap)) {
829 if (has_search_latch) {
857 ulint root_height = 0;
862 ulint offsets_[REC_OFFS_NORMAL_SIZE];
864 rec_offs_init(offsets_);
867 latch_mode &= ~BTR_ESTIMATE;
869 ut_ad(level != ULINT_UNDEFINED);
876 switch (latch_mode) {
891 page_cursor = btr_cur_get_page_cur(cursor);
898 height = ULINT_UNDEFINED;
906 page = buf_block_get_frame(block);
912 if (height == ULINT_UNDEFINED) {
915 height = btr_page_get_level(page, mtr);
916 root_height = height;
917 ut_a(height >= level);
920 ut_ad(height == btr_page_get_level(page, mtr));
923 if (height == level) {
924 btr_cur_latch_leaves(
925 page, space, zip_size, page_no,
938 switch (latch_mode) {
960 if (height == level) {
962 btr_cur_add_path_info(cursor, height,
978 btr_cur_add_path_info(cursor, height, root_height);
983 node_ptr = page_cur_get_rec(page_cursor);
984 offsets = rec_get_offsets(node_ptr, cursor->
index, offsets,
985 ULINT_UNDEFINED, &heap);
1015 ulint offsets_[REC_OFFS_NORMAL_SIZE];
1017 rec_offs_init(offsets_);
1019 switch (latch_mode) {
1028 page_cursor = btr_cur_get_page_cur(cursor);
1035 height = ULINT_UNDEFINED;
1044 page = buf_block_get_frame(block);
1048 if (height == ULINT_UNDEFINED) {
1051 height = btr_page_get_level(page, mtr);
1055 btr_cur_latch_leaves(page, space, zip_size, page_no,
1056 latch_mode, cursor, mtr);
1070 node_ptr = page_cur_get_rec(page_cursor);
1071 offsets = rec_get_offsets(node_ptr, cursor->
index, offsets,
1072 ULINT_UNDEFINED, &heap);
1077 if (UNIV_LIKELY_NULL(heap)) {
1096 static __attribute__((nonnull, warn_unused_result))
1098 btr_cur_insert_if_possible(
1114 ut_ad(mtr_memo_contains(mtr, btr_cur_get_block(cursor),
1115 MTR_MEMO_PAGE_X_FIX));
1116 page_cursor = btr_cur_get_page_cur(cursor);
1120 offsets, heap, n_ext, mtr);
1125 if (!rec && !page_cur_get_page_zip(page_cursor)
1128 page_cursor, tuple, cursor->index,
1129 offsets, heap, n_ext, mtr);
1132 ut_ad(!rec || rec_offs_validate(rec, cursor->index, *offsets));
1139 UNIV_INLINE __attribute__((warn_unused_result, nonnull(2,3,5,6)))
1141 btr_cur_ins_lock_and_undo(
1162 rec = btr_cur_get_rec(cursor);
1163 index = cursor->index;
1170 btr_cur_get_block(cursor),
1171 index, thr, mtr, inherit);
1173 if (err != DB_SUCCESS
1181 NULL, 0, NULL, NULL,
1183 if (err != DB_SUCCESS) {
1193 DATA_ROLL_PTR, roll_ptr);
1210 fprintf(stderr,
"Trx with id " TRX_ID_FMT " going to ", trx_id);
1265 block = btr_cur_get_block(cursor);
1266 page = buf_block_get_frame(block);
1267 index = cursor->
index;
1269 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
1276 #ifdef UNIV_DEBUG_VALGRIND
1278 UNIV_MEM_ASSERT_RW(page, UNIV_PAGE_SIZE);
1279 UNIV_MEM_ASSERT_RW(block->
page.
zip.
data, zip_size);
1284 if (btr_cur_print_record_ops && thr) {
1285 btr_cur_trx_report(
thr_get_trx(thr)->
id, index,
"insert ");
1302 if (UNIV_UNLIKELY(big_rec_vec == NULL)) {
1320 if (free_space_zip == 0) {
1324 index, entry, big_rec_vec);
1339 && (REC_NODE_PTR_SIZE
1341 index, entry->
fields, n_uniq, NULL)
1346 - (REC_N_NEW_EXTRA_BYTES - 2)
1347 > free_space_zip / 2)) {
1355 if (leaf && zip_size
1376 if ((max_size < rec_size
1383 }
else if (max_size < rec_size) {
1401 err = btr_cur_ins_lock_and_undo(flags, cursor, entry,
1402 thr, mtr, &inherit);
1404 if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
1409 page_cursor = btr_cur_get_page_cur(cursor);
1414 const rec_t* page_cursor_rec = page_cur_get_rec(page_cursor);
1416 offsets, heap, n_ext, mtr);
1417 reorg = page_cursor_rec != page_cur_get_rec(page_cursor);
1421 }
else if (zip_size) {
1444 offsets, heap, n_ext, mtr);
1446 if (UNIV_UNLIKELY(!*rec)) {
1447 fputs(
"InnoDB: Error: cannot insert tuple ", stderr);
1449 fputs(
" into ", stderr);
1451 fprintf(stderr,
"\nInnoDB: max insert size %lu\n",
1457 #ifdef BTR_CUR_HASH_ADAPT
1492 rec_size + PAGE_DIR_SLOT_SIZE);
1496 *big_rec = big_rec_vec;
1538 ulint n_reserved = 0;
1544 ut_ad(mtr_memo_contains(mtr,
1547 ut_ad(mtr_memo_contains(mtr, btr_cur_get_block(cursor),
1548 MTR_MEMO_PAGE_X_FIX));
1557 err = btr_cur_ins_lock_and_undo(flags, cursor, entry,
1558 thr, mtr, &dummy_inh);
1560 if (err != DB_SUCCESS) {
1573 n_extents, FSP_NORMAL, mtr);
1575 return(DB_OUT_OF_FILE_SPACE);
1586 if (UNIV_LIKELY_NULL(big_rec_vec)) {
1595 if (big_rec_vec == NULL) {
1597 if (n_reserved > 0) {
1610 flags, cursor, offsets, heap, entry, n_ext, mtr);
1613 flags, cursor, offsets, heap, entry, n_ext, mtr);
1618 #ifdef BTR_CUR_ADAPT
1621 if (!(flags & BTR_NO_LOCKING_FLAG)) {
1626 if (n_reserved > 0) {
1630 *big_rec = big_rec_vec;
1640 UNIV_INLINE __attribute__((warn_unused_result, nonnull(2,3,6,7)))
1642 btr_cur_upd_lock_and_undo(
1646 const ulint* offsets,
1647 const
upd_t* update,
1659 ut_ad(thr || (flags & BTR_NO_LOCKING_FLAG));
1661 rec = btr_cur_get_rec(cursor);
1662 index = cursor->index;
1664 ut_ad(rec_offs_validate(rec, index, offsets));
1673 flags, btr_cur_get_block(cursor), rec,
1680 if (!(flags & BTR_NO_LOCKING_FLAG)) {
1682 flags, btr_cur_get_block(cursor), rec, index,
1684 if (err != DB_SUCCESS) {
1692 flags, TRX_UNDO_MODIFY_OP, thr,
1693 index, NULL, update,
1694 cmpl_info, rec, offsets, roll_ptr));
1699 UNIV_INLINE __attribute__((nonnull))
1701 btr_cur_update_in_place_log(
1706 const
upd_t* update,
1719 1 + DATA_ROLL_PTR_LEN + 14 + 2
1732 index = dict_table_get_first_index(index->table);
1738 index, trx_id, roll_ptr, log_ptr, mtr);
1769 if (end_ptr < ptr + 1) {
1784 if (end_ptr < ptr + 2) {
1792 ut_a(rec_offset <= UNIV_PAGE_SIZE);
1798 if (!ptr || !page) {
1804 rec = page + rec_offset;
1809 offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
1811 if (!(flags & BTR_KEEP_SYS_FLAG)) {
1813 pos, trx_id, roll_ptr);
1824 #ifndef UNIV_HOTBACKUP
1852 const page_t* page = page_cur_get_page(cursor);
1854 ut_ad(page_zip == page_cur_get_page_zip(cursor));
1857 ut_ad(rec_offs_validate(page_cur_get_rec(cursor), index, offsets));
1880 rec_offs_make_valid(page_cur_get_rec(cursor), index, offsets);
1898 ut_ad(rec_offs_validate(page_cur_get_rec(cursor), index, offsets));
1924 const upd_t* update,
1940 ulint was_delete_marked;
1943 rec = btr_cur_get_rec(cursor);
1944 index = cursor->
index;
1945 ut_ad(rec_offs_validate(rec, index, offsets));
1953 == (BTR_NO_UNDO_LOG_FLAG | BTR_NO_LOCKING_FLAG
1954 | BTR_CREATE_FLAG | BTR_KEEP_SYS_FLAG));
1959 if (btr_cur_print_record_ops) {
1960 btr_cur_trx_report(trx_id, index,
"update ");
1965 block = btr_cur_get_block(cursor);
1970 if (!btr_cur_update_alloc_zip(
1971 page_zip, btr_cur_get_page_cur(cursor),
1974 return(DB_ZIP_OVERFLOW);
1977 rec = btr_cur_get_rec(cursor);
1981 err = btr_cur_upd_lock_and_undo(flags, cursor, offsets,
1983 thr, mtr, &roll_ptr);
1984 if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
1991 if (!(flags & BTR_KEEP_SYS_FLAG)) {
1999 is_hashed = (block->
index != NULL);
2011 || row_upd_changes_ord_field_binary(index, update, thr,
2027 btr_cur_update_in_place_log(flags, rec, index, update,
2028 trx_id, roll_ptr, mtr);
2030 if (was_delete_marked
2036 btr_cur_unmark_extern_fields(page_zip,
2037 rec, index, offsets, mtr);
2040 ut_ad(err == DB_SUCCESS);
2076 const upd_t* update,
2103 block = btr_cur_get_block(cursor);
2104 page = buf_block_get_frame(block);
2105 rec = btr_cur_get_rec(cursor);
2106 index = cursor->
index;
2108 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
2115 == (BTR_NO_UNDO_LOG_FLAG | BTR_NO_LOCKING_FLAG
2116 | BTR_CREATE_FLAG | BTR_KEEP_SYS_FLAG));
2120 *offsets = rec_get_offsets(rec, index, *offsets,
2121 ULINT_UNDEFINED, heap);
2122 #if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
2128 if (btr_cur_print_record_ops) {
2129 btr_cur_trx_report(trx_id, index,
"update ");
2142 flags, cursor, *offsets, update,
2143 cmpl_info, thr, trx_id, mtr));
2151 return(DB_OVERFLOW);
2155 if (
dfield_is_ext(&upd_get_nth_field(update, i)->new_val)) {
2161 page_cursor = btr_cur_get_page_cur(cursor);
2183 #ifdef UNIV_ZIP_DEBUG
2184 ut_a(!page_zip || page_zip_validate(page_zip, page, index));
2188 if (!btr_cur_update_alloc_zip(
2189 page_zip, page_cursor, index, *offsets,
2190 new_rec_size,
true, mtr)) {
2191 return(DB_ZIP_OVERFLOW);
2194 rec = page_cur_get_rec(page_cursor);
2197 if (UNIV_UNLIKELY(new_rec_size
2208 - old_rec_size + new_rec_size
2227 && (max_size >= new_rec_size))
2243 err = btr_cur_upd_lock_and_undo(flags, cursor, *offsets,
2245 thr, mtr, &roll_ptr);
2246 if (err != DB_SUCCESS) {
2265 if (!(flags & BTR_KEEP_SYS_FLAG)) {
2273 rec = btr_cur_insert_if_possible(
2274 cursor, new_entry, offsets, heap, 0, mtr);
2282 ut_ad(err == DB_SUCCESS);
2286 && !(flags & BTR_KEEP_IBUF_BITMAP)
2304 btr_cur_pess_upd_restore_supremum(
2316 page = buf_block_get_frame(block);
2331 #ifdef UNIV_BTR_DEBUG
2337 ut_ad(mtr_memo_contains(mtr, prev_block, MTR_MEMO_PAGE_X_FIX));
2340 PAGE_HEAP_NO_SUPREMUM,
2369 const upd_t* update,
2392 ulint n_reserved = 0;
2398 block = btr_cur_get_block(cursor);
2399 page = buf_block_get_frame(block);
2401 index = cursor->
index;
2405 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
2406 #ifdef UNIV_ZIP_DEBUG
2407 ut_a(!page_zip || page_zip_validate(page_zip, page, index));
2415 == (BTR_NO_UNDO_LOG_FLAG | BTR_NO_LOCKING_FLAG
2416 | BTR_CREATE_FLAG | BTR_KEEP_SYS_FLAG));
2419 flags | BTR_KEEP_IBUF_BITMAP,
2420 cursor, offsets, offsets_heap, update,
2421 cmpl_info, thr, trx_id, mtr);
2424 case DB_ZIP_OVERFLOW:
2435 && optim_err != DB_ZIP_OVERFLOW
2445 err = btr_cur_upd_lock_and_undo(flags, cursor, *offsets,
2447 thr, mtr, &roll_ptr);
2448 if (err != DB_SUCCESS) {
2452 if (optim_err == DB_OVERFLOW) {
2461 if (flags & BTR_NO_UNDO_LOG_FLAG) {
2462 reserve_flag = FSP_CLEANING;
2464 reserve_flag = FSP_NORMAL;
2468 n_extents, reserve_flag, mtr)) {
2469 err = DB_OUT_OF_FILE_SPACE;
2474 rec = btr_cur_get_rec(cursor);
2476 *offsets = rec_get_offsets(
2477 rec, index, *offsets, ULINT_UNDEFINED, offsets_heap);
2480 rec, index, *offsets, &n_ext, entry_heap);
2490 if (!(flags & BTR_KEEP_SYS_FLAG)) {
2505 ut_ad(big_rec_vec == NULL);
2507 btr_rec_free_updated_extern_fields(
2508 index, rec, page_zip, *offsets, update,
2517 ut_ad(rec_offs_validate(rec, index, *offsets));
2535 if (UNIV_UNLIKELY(big_rec_vec == NULL)) {
2541 #ifdef UNIV_ZIP_DEBUG
2543 || page_zip_validate(page_zip, page, index));
2545 if (n_reserved > 0) {
2547 index->
space, n_reserved);
2572 #ifdef UNIV_ZIP_DEBUG
2573 ut_a(!page_zip || page_zip_validate(page_zip, page, index));
2575 page_cursor = btr_cur_get_page_cur(cursor);
2581 rec = btr_cur_insert_if_possible(cursor, new_entry,
2582 offsets, offsets_heap, n_ext, mtr);
2593 btr_cur_unmark_extern_fields(
2594 page_zip, rec, index, *offsets, mtr);
2601 rec_offs_make_valid(
2602 page_cursor->
rec, index, *offsets);
2604 }
else if (page_zip &&
2614 goto return_after_reservations;
2621 ut_a(page_zip || optim_err != DB_UNDERFLOW);
2656 | BTR_NO_LOCKING_FLAG
2657 | BTR_KEEP_SYS_FLAG,
2658 cursor, offsets, offsets_heap,
2660 &dummy_big_rec, n_ext, NULL, mtr);
2662 ut_a(err == DB_SUCCESS);
2663 ut_a(dummy_big_rec == NULL);
2664 ut_ad(rec_offs_validate(rec, cursor->
index, *offsets));
2673 rec_block = btr_cur_get_block(cursor);
2683 buf_block_t* rec_block = btr_cur_get_block(cursor);
2685 #ifdef UNIV_ZIP_DEBUG
2686 ut_a(!page_zip || page_zip_validate(page_zip, page, index));
2687 page = buf_block_get_frame(rec_block);
2691 btr_cur_unmark_extern_fields(page_zip,
2692 rec, index, *offsets, mtr);
2704 btr_cur_pess_upd_restore_supremum(btr_cur_get_block(cursor),
2708 return_after_reservations:
2709 #ifdef UNIV_ZIP_DEBUG
2710 ut_a(!page_zip || page_zip_validate(page_zip, page, index));
2713 if (n_reserved > 0) {
2717 *big_rec = big_rec_vec;
2729 btr_cur_del_mark_set_clust_rec_log(
2745 1 + 1 + DATA_ROLL_PTR_LEN
2757 index, trx_id, roll_ptr, log_ptr, mtr);
2790 if (end_ptr < ptr + 2) {
2807 if (end_ptr < ptr + 2) {
2815 ut_a(offset <= UNIV_PAGE_SIZE);
2827 if (!(flags & BTR_KEEP_SYS_FLAG)) {
2829 ulint offsets_[REC_OFFS_NORMAL_SIZE];
2830 rec_offs_init(offsets_);
2834 rec_get_offsets(rec, index, offsets_,
2835 ULINT_UNDEFINED, &heap),
2836 pos, trx_id, roll_ptr);
2837 if (UNIV_LIKELY_NULL(heap)) {
2846 #ifndef UNIV_HOTBACKUP
2860 const ulint* offsets,
2870 ut_ad(rec_offs_validate(rec, index, offsets));
2876 if (btr_cur_print_record_ops && thr) {
2877 btr_cur_trx_report(
thr_get_trx(thr)->
id, index,
"del mark ");
2886 rec, index, offsets, thr);
2888 if (err != DB_SUCCESS) {
2894 index, NULL, NULL, 0, rec, offsets,
2896 if (err != DB_SUCCESS) {
2907 btr_blob_dbg_set_deleted_flag(rec, index, offsets, TRUE);
2914 rec, index, offsets,
false,
2921 btr_cur_del_mark_set_clust_rec_log(rec, index, trx->
id,
2932 btr_cur_del_mark_set_sec_rec_log(
2978 if (end_ptr < ptr + 3) {
2989 ut_a(offset <= UNIV_PAGE_SIZE);
3005 #ifndef UNIV_HOTBACKUP
3023 block = btr_cur_get_block(cursor);
3024 rec = btr_cur_get_rec(cursor);
3027 if (btr_cur_print_record_ops && thr) {
3035 btr_cur_get_block(cursor),
3036 rec, cursor->
index, thr, mtr);
3037 if (err != DB_SUCCESS) {
3050 btr_cur_del_mark_set_sec_rec_log(rec, val, mtr);
3078 btr_cur_del_mark_set_sec_rec_log(rec, val, mtr);
3101 ut_ad(mtr_memo_contains(mtr,
3104 ut_ad(mtr_memo_contains(mtr, btr_cur_get_block(cursor),
3105 MTR_MEMO_PAGE_X_FIX));
3107 return(btr_cur_compress_recommendation(cursor, mtr)
3135 ulint offsets_[REC_OFFS_NORMAL_SIZE];
3136 ulint* offsets = offsets_;
3137 ibool no_compress_needed;
3138 rec_offs_init(offsets_);
3140 ut_ad(flags == 0 || flags == BTR_CREATE_FLAG);
3141 ut_ad(mtr_memo_contains(mtr, btr_cur_get_block(cursor),
3142 MTR_MEMO_PAGE_X_FIX));
3145 block = btr_cur_get_block(cursor);
3150 || (flags & BTR_CREATE_FLAG));
3152 rec = btr_cur_get_rec(cursor);
3153 offsets = rec_get_offsets(rec, cursor->
index, offsets,
3154 ULINT_UNDEFINED, &heap);
3157 && btr_cur_can_delete_without_compress(
3160 if (no_compress_needed) {
3162 page_t* page = buf_block_get_frame(block);
3170 #ifdef UNIV_ZIP_DEBUG
3171 ut_a(page_zip_validate(page_zip, page, cursor->
index));
3174 cursor->
index, offsets, mtr);
3175 #ifdef UNIV_ZIP_DEBUG
3176 ut_a(page_zip_validate(page_zip, page, cursor->
index));
3190 cursor->
index, offsets, mtr);
3203 if (UNIV_LIKELY_NULL(heap)) {
3207 return(no_compress_needed);
3227 ibool has_reserved_extents,
3244 ulint n_reserved = 0;
3251 block = btr_cur_get_block(cursor);
3252 page = buf_block_get_frame(block);
3255 ut_ad(flags == 0 || flags == BTR_CREATE_FLAG);
3258 || (flags & BTR_CREATE_FLAG));
3261 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
3262 if (!has_reserved_extents) {
3274 *err = DB_OUT_OF_FILE_SPACE;
3281 rec = btr_cur_get_rec(cursor);
3283 #ifdef UNIV_ZIP_DEBUG
3284 ut_a(!page_zip || page_zip_validate(page_zip, page, index));
3287 offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
3290 btr_rec_free_externally_stored_fields(index,
3291 rec, offsets, page_zip,
3293 #ifdef UNIV_ZIP_DEBUG
3294 ut_a(!page_zip || page_zip_validate(page_zip, page, index));
3309 goto return_after_reservations;
3316 level = btr_page_get_level(page, mtr);
3320 page_get_infimum_rec(page)))) {
3348 btr_insert_on_non_leaf_level(
3349 flags, index, level + 1, node_ptr, mtr);
3356 #ifdef UNIV_ZIP_DEBUG
3357 ut_a(!page_zip || page_zip_validate(page_zip, page, index));
3360 ut_ad(btr_check_node_ptr(index, block, mtr));
3362 return_after_reservations:
3371 if (n_reserved > 0) {
3383 btr_cur_add_path_info(
3400 slot->
nth_rec = ULINT_UNDEFINED;
3407 slot = cursor->
path_arr + root_height + 1;
3408 slot->
nth_rec = ULINT_UNDEFINED;
3411 rec = btr_cur_get_rec(cursor);
3413 slot = cursor->
path_arr + (root_height - height);
3437 btr_estimate_n_rows_in_range_on_level(
3442 ib_int64_t n_rows_on_prev_level,
3447 ibool* is_n_rows_exact)
3465 *is_n_rows_exact = TRUE;
3488 # define N_PAGES_READ_LIMIT 10
3507 __FILE__, __LINE__, &mtr);
3509 page = buf_block_get_frame(block);
3535 if (page_no != slot1->
page_no) {
3545 if (n_pages_read == N_PAGES_READ_LIMIT
3554 }
while (page_no != slot2->
page_no);
3560 *is_n_rows_exact = FALSE;
3564 if (n_pages_read > 0) {
3568 n_rows = n_rows_on_prev_level
3569 * n_rows / n_pages_read;
3599 ulint divergence_level;
3601 ibool is_n_rows_exact;
3604 ib_int64_t table_n_rows;
3617 __FILE__, __LINE__, &mtr);
3619 btr_cur_open_at_index_side(
true, index,
3635 __FILE__, __LINE__, &mtr);
3637 btr_cur_open_at_index_side(
false, index,
3647 is_n_rows_exact = TRUE;
3650 diverged_lot = FALSE;
3652 divergence_level = 1000000;
3654 for (i = 0; ; i++) {
3660 if (slot1->
nth_rec == ULINT_UNDEFINED
3661 || slot2->
nth_rec == ULINT_UNDEFINED) {
3663 if (i > divergence_level + 1 && !is_n_rows_exact) {
3668 n_rows = n_rows * 2;
3671 DBUG_EXECUTE_IF(
"bug14007649",
return(n_rows););
3677 if (n_rows > table_n_rows / 2 && !is_n_rows_exact) {
3679 n_rows = table_n_rows / 2;
3685 n_rows = table_n_rows;
3700 diverged_lot = TRUE;
3701 divergence_level =
i;
3715 }
else if (diverged && !diverged_lot) {
3720 diverged_lot = TRUE;
3721 divergence_level =
i;
3734 }
else if (diverged_lot) {
3736 n_rows = btr_estimate_n_rows_in_range_on_level(
3737 index, slot1, slot2, n_rows,
3750 btr_record_not_null_field_in_rec(
3755 const ulint* offsets,
3758 ib_uint64_t* n_not_null)
3765 if (n_not_null == NULL) {
3769 for (i = 0; i < n_unique; i++) {
3797 ulint matched_fields;
3798 ulint matched_bytes;
3799 ib_uint64_t* n_diff;
3800 ib_uint64_t* n_not_null;
3801 ibool stats_null_not_equal;
3802 ullint n_sample_pages;
3803 ulint not_empty_flag = 0;
3804 ulint total_external_size = 0;
3810 ulint* offsets_rec = NULL;
3811 ulint* offsets_next_rec = NULL;
3818 * (
sizeof *offsets_rec
3819 +
sizeof *offsets_next_rec));
3822 heap, n_cols *
sizeof(ib_int64_t));
3829 switch (srv_innodb_stats_method) {
3830 case SRV_STATS_NULLS_IGNORED:
3832 heap, n_cols *
sizeof *n_not_null);
3835 case SRV_STATS_NULLS_UNEQUAL:
3838 stats_null_not_equal = TRUE;
3841 case SRV_STATS_NULLS_EQUAL:
3842 stats_null_not_equal = FALSE;
3858 n_sample_pages = srv_stats_transient_sample_pages;
3863 for (i = 0; i < n_sample_pages; i++) {
3880 offsets_rec = rec_get_offsets(rec, index, offsets_rec,
3881 ULINT_UNDEFINED, &heap);
3883 if (n_not_null != NULL) {
3884 btr_record_not_null_field_in_rec(
3885 n_cols, offsets_rec, n_not_null);
3892 total_external_size +=
3893 btr_rec_get_externally_stored_len(
3900 offsets_next_rec = rec_get_offsets(next_rec, index,
3906 offsets_rec, offsets_next_rec,
3907 index, stats_null_not_equal,
3911 for (j = matched_fields; j < n_cols; j++) {
3918 if (n_not_null != NULL) {
3919 btr_record_not_null_field_in_rec(
3920 n_cols, offsets_next_rec, n_not_null);
3924 += btr_rec_get_externally_stored_len(
3932 ulint* offsets_tmp = offsets_rec;
3933 offsets_rec = offsets_next_rec;
3934 offsets_next_rec = offsets_tmp;
3953 n_diff[n_cols - 1]++;
3968 for (j = 0; j < n_cols; j++) {
3971 n_diff[j], index, n_sample_pages,
3972 total_external_size, not_empty_flag);
3983 / (10 * (n_sample_pages
3984 + total_external_size));
3986 if (add_on > n_sample_pages) {
3987 add_on = n_sample_pages;
3998 if (n_not_null != NULL) {
3999 index->stat_n_non_null_key_vals[j] =
4001 n_not_null[j], index, n_sample_pages,
4002 total_external_size, not_empty_flag);
4016 btr_rec_get_field_ref_offs(
4018 const ulint* offsets,
4021 ulint field_ref_offs;
4026 ut_a(local_len != UNIV_SQL_NULL);
4037 #define btr_rec_get_field_ref(rec, offsets, n) \
4038 ((rec) + btr_rec_get_field_ref_offs(offsets, n))
4045 btr_rec_get_externally_stored_len(
4048 const ulint* offsets)
4051 ulint total_extern_len = 0;
4062 for (i = 0; i < n_fields; i++) {
4066 btr_rec_get_field_ref(rec, offsets, i)
4074 return(total_extern_len / UNIV_PAGE_SIZE);
4081 btr_cur_set_ownership_of_extern_field(
4087 const ulint* offsets,
4096 data = rec_get_nth_field(rec, offsets, i, &local_len);
4107 #if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
4116 }
else if (mtr != NULL) {
4124 btr_blob_dbg_owner(rec, index, offsets, i, val);
4140 const ulint* offsets,
4141 const upd_t* update,
4146 ut_ad(rec_offs_validate(rec, index, offsets));
4154 btr_cur_set_ownership_of_extern_field(
4155 page_zip, rec, index, offsets, i, FALSE, mtr);
4166 btr_cur_unmark_extern_fields(
4172 const ulint* offsets,
4186 for (i = 0; i <
n; i++) {
4189 btr_cur_set_ownership_of_extern_field(
4190 page_zip, rec, index, offsets, i, TRUE, mtr);
4205 const upd_t* update,
4221 = dtuple_get_nth_field(tuple, uf->
field_no);
4252 data = (byte*) dfield_get_data(field);
4281 btr_blob_get_part_len(
4283 const byte* blob_header)
4293 btr_blob_get_next_page_no(
4295 const byte* blob_header)
4315 ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
4355 const ulint* offsets,
4381 ulint n_freed_pages = 0;
4384 ut_ad(rec_offs_validate(rec, index, offsets));
4389 ut_ad(mtr_memo_contains(btr_mtr, rec_block, MTR_MEMO_PAGE_X_FIX));
4413 err = deflateInit2(&c_stream, page_zip_level,
4414 Z_DEFLATED, 15, 7, Z_DEFAULT_STRATEGY);
4421 if (btr_mtr->n_freed_pages) {
4424 btr_mtr->n_freed_pages
4425 *
sizeof *freed_pages);
4431 btr_mtr->n_freed_pages
4432 *
sizeof *freed_pages));
4449 alloc_mtr = btr_mtr;
4455 #if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
4463 field_ref = btr_rec_get_field_ref(rec, offsets, i);
4478 for (i = 0; i < big_rec_vec->
n_fields; i++) {
4479 field_ref = btr_rec_get_field_ref(
4481 #if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
4487 UNIV_MEM_ASSERT_RW(big_rec_vec->
fields[i].
data,
4490 ut_a(extern_len > 0);
4495 int err = deflateReset(&c_stream);
4498 c_stream.next_in = (Bytef*)
4500 c_stream.avail_in = extern_len;
4510 hint_page_no = 1 + rec_page_no;
4512 hint_page_no = prev_page_no + 1;
4517 FSP_NO_DIR, 0, alloc_mtr, &mtr);
4518 if (UNIV_UNLIKELY(block == NULL)) {
4520 error = DB_OUT_OF_FILE_SPACE;
4528 ut_ad(alloc_mtr == btr_mtr);
4530 ut_ad(n_freed_pages < btr_mtr->n_freed_pages);
4531 freed_pages[n_freed_pages++] =
block;
4536 page = buf_block_get_frame(block);
4545 buf_block_dbg_add_level(prev_block,
4546 SYNC_EXTERN_STORAGE);
4547 prev_page = buf_block_get_frame(prev_block);
4588 c_stream.next_out = page
4594 err = deflate(&c_stream, Z_FINISH);
4595 ut_a(err == Z_OK || err == Z_STREAM_END);
4596 ut_a(err == Z_STREAM_END
4597 || c_stream.avail_out == 0);
4630 - c_stream.avail_out,
4631 0, c_stream.avail_out);
4640 ut_ad(blob_page_zip);
4643 memcpy(blob_page_zip->
data, page,
4646 if (err == Z_OK && prev_page_no !=
FIL_NULL) {
4651 if (alloc_mtr == &mtr) {
4656 buf_block_dbg_add_level(
4658 SYNC_NO_ORDER_CHECK);
4661 if (err == Z_STREAM_END) {
4673 btr_blob_dbg_add_blob(
4674 rec, big_rec_vec->
fields[i]
4692 page_zip, rec, index, offsets,
4697 prev_page_no = page_no;
4701 btr_blob_free(block, FALSE, &mtr);
4703 if (err == Z_STREAM_END) {
4711 if (extern_len > (UNIV_PAGE_SIZE
4715 store_len = UNIV_PAGE_SIZE
4720 store_len = extern_len;
4737 extern_len -= store_len;
4739 if (alloc_mtr == &mtr) {
4744 buf_block_dbg_add_level(
4746 SYNC_NO_ORDER_CHECK);
4758 btr_blob_dbg_add_blob(
4759 rec, big_rec_vec->
fields[i]
4780 prev_page_no = page_no;
4784 if (extern_len == 0) {
4790 DBUG_EXECUTE_IF(
"btr_store_big_rec_extern",
4791 error = DB_OUT_OF_FILE_SPACE;
4797 deflateEnd(&c_stream);
4800 if (n_freed_pages) {
4803 ut_ad(alloc_mtr == btr_mtr);
4806 for (i = 0; i < n_freed_pages; i++) {
4815 #if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
4823 field_ref = btr_rec_get_field_ref(rec, offsets, i);
4829 || error != DB_SUCCESS);
4841 btr_check_blob_fil_page_type(
4868 " InnoDB: FIL_PAGE_TYPE=%lu"
4869 " on BLOB %s space %lu page %lu flags %lx\n",
4870 (ulong) type, read ?
"read" :
"purge",
4871 (ulong) space_id, (ulong) page_no, (ulong) flags);
4896 const ulint* offsets,
4903 mtr_t* local_mtr __attribute__((unused)))
4921 ut_ad(mtr_memo_contains_page(local_mtr, field_ref,
4922 MTR_MEMO_PAGE_X_FIX));
4923 ut_ad(!rec || rec_offs_validate(rec, index, offsets));
4924 ut_ad(!rec || field_ref == btr_rec_get_field_ref(rec, offsets, i));
4947 ext_zip_size = rec_zip_size;
4956 #ifdef UNIV_BLOB_DEBUG
4965 b.blob_page_no = start_page;
4979 btr_blob_dbg_rbt_delete(index, &b,
"free");
4982 btr_blob_dbg_assert_empty(index, b.blob_page_no);
4987 #ifdef UNIV_SYNC_DEBUG
4994 #ifdef UNIV_SYNC_DEBUG
5001 buf_block_dbg_add_level(rec_block, SYNC_NO_ORDER_CHECK);
5008 & BTR_EXTERN_OWNER_FLAG)
5012 & BTR_EXTERN_INHERITED_FLAG))) {
5024 ext_block =
buf_page_get(space_id, ext_zip_size, page_no,
5026 buf_block_dbg_add_level(ext_block, SYNC_EXTERN_STORAGE);
5027 page = buf_block_get_frame(ext_block);
5043 if (page_zip != NULL) {
5061 btr_check_blob_fil_page_type(space_id, page_no, page,
5065 page + FIL_PAGE_DATA
5088 btr_blob_free(ext_block, TRUE, &mtr);
5096 btr_rec_free_externally_stored_fields(
5101 const ulint* offsets,
5112 ut_ad(rec_offs_validate(rec, index, offsets));
5113 ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX));
5119 for (i = 0; i < n_fields; i++) {
5122 index, btr_rec_get_field_ref(rec, offsets, i),
5123 rec, offsets, page_zip, i, rb_ctx, mtr);
5133 btr_rec_free_updated_extern_fields(
5140 const ulint* offsets,
5141 const upd_t* update,
5149 ut_ad(rec_offs_validate(rec, index, offsets));
5150 ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX));
5156 for (i = 0; i < n_fields; i++) {
5157 const upd_field_t* ufield = upd_get_nth_field(update, i);
5161 byte* data = rec_get_nth_field(
5162 rec, offsets, ufield->
field_no, &len);
5167 rec, offsets, page_zip,
5179 btr_copy_blob_prefix(
5188 ulint copied_len = 0;
5194 const byte* blob_header;
5200 block =
buf_page_get(space_id, 0, page_no, RW_S_LATCH, &mtr);
5201 buf_block_dbg_add_level(block, SYNC_EXTERN_STORAGE);
5202 page = buf_block_get_frame(block);
5204 btr_check_blob_fil_page_type(space_id, page_no, page, TRUE);
5206 blob_header = page +
offset;
5207 part_len = btr_blob_get_part_len(blob_header);
5208 copy_len =
ut_min(part_len, len - copied_len);
5210 memcpy(buf + copied_len,
5212 copied_len += copy_len;
5214 page_no = btr_blob_get_next_page_no(blob_header);
5218 if (page_no ==
FIL_NULL || copy_len != part_len) {
5219 UNIV_MEM_ASSERT_RW(buf, copied_len);
5228 ut_ad(copied_len <= len);
5238 btr_copy_zblob_prefix(
5253 d_stream.next_out =
buf;
5254 d_stream.avail_out = len;
5255 d_stream.next_in = Z_NULL;
5256 d_stream.avail_in = 0;
5264 ut_ad(zip_size >= UNIV_ZIP_SIZE_MIN);
5265 ut_ad(zip_size <= UNIV_ZIP_SIZE_MAX);
5268 err = inflateInit(&d_stream);
5281 if (UNIV_UNLIKELY(!bpage)) {
5284 " InnoDB: Cannot load"
5286 " page %lu space %lu\n",
5287 (ulong) page_no, (ulong) space_id);
5295 " InnoDB: Unexpected type %lu of"
5297 " page %lu space %lu\n",
5299 (ulong) page_no, (ulong) space_id);
5316 d_stream.avail_in = zip_size -
offset;
5318 err = inflate(&d_stream, Z_NO_FLUSH);
5321 if (!d_stream.avail_out) {
5334 " InnoDB: inflate() of"
5336 " page %lu space %lu returned %d (%s)\n",
5337 (ulong) page_no, (ulong) space_id,
5344 if (!d_stream.avail_in) {
5347 " InnoDB: unexpected end of"
5349 " page %lu space %lu\n",
5353 err = inflate(&d_stream, Z_FINISH);
5373 page_no = next_page_no;
5379 inflateEnd(&d_stream);
5381 UNIV_MEM_ASSERT_RW(buf, d_stream.total_out);
5382 return(d_stream.total_out);
5392 btr_copy_externally_stored_field_prefix_low(
5403 if (UNIV_UNLIKELY(len == 0)) {
5408 return(btr_copy_zblob_prefix(buf, len, zip_size,
5409 space_id, page_no, offset));
5411 return(btr_copy_blob_prefix(buf, len, space_id,
5443 if (UNIV_UNLIKELY(local_len >= len)) {
5444 memcpy(buf, data, len);
5448 memcpy(buf, data, local_len);
5468 + btr_copy_externally_stored_field_prefix_low(buf + local_len,
5516 memcpy(buf, data, local_len);
5518 + btr_copy_externally_stored_field_prefix_low(buf + local_len,
5536 const ulint* offsets,
5557 data = rec_get_nth_field(rec, offsets, no, &local_len);
5572 zip_size, local_len, heap));