diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2021-04-14 11:35:39 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2021-04-14 11:35:39 +0300 |
commit | 6c3e860cbf36831c118f6ea183acbbeb3c889bed (patch) | |
tree | 8585545cc8a95e790c01eb164f74685674f9f23b /storage | |
parent | 9ff737b25edbcb0c74d9d312f6da702e7d993e88 (diff) | |
parent | 5008171b05e0d3b8b5f4af312b94a312281e77c7 (diff) | |
download | mariadb-git-6c3e860cbf36831c118f6ea183acbbeb3c889bed.tar.gz |
Merge 10.4 into 10.5
Diffstat (limited to 'storage')
47 files changed, 721 insertions, 435 deletions
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index a6a8d62ade6..de87ad02e68 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -848,7 +848,7 @@ btr_page_get_father_node_ptr_func( node_ptr = btr_cur_get_rec(cursor); - offsets = rec_get_offsets(node_ptr, index, offsets, false, + offsets = rec_get_offsets(node_ptr, index, offsets, 0, ULINT_UNDEFINED, &heap); if (btr_node_ptr_get_child_page_no(node_ptr, offsets) != page_no) { @@ -865,10 +865,11 @@ btr_page_get_father_node_ptr_func( print_rec = page_rec_get_next( page_get_infimum_rec(page_align(user_rec))); offsets = rec_get_offsets(print_rec, index, offsets, - page_rec_is_leaf(user_rec), + page_rec_is_leaf(user_rec) + ? index->n_core_fields : 0, ULINT_UNDEFINED, &heap); page_rec_print(print_rec, offsets); - offsets = rec_get_offsets(node_ptr, index, offsets, false, + offsets = rec_get_offsets(node_ptr, index, offsets, 0, ULINT_UNDEFINED, &heap); page_rec_print(node_ptr, offsets); @@ -2214,7 +2215,9 @@ btr_page_get_split_rec( incl_data += insert_size; } else { offsets = rec_get_offsets(rec, cursor->index, offsets, - page_is_leaf(page), + page_is_leaf(page) + ? cursor->index->n_core_fields + : 0, ULINT_UNDEFINED, &heap); incl_data += rec_offs_size(offsets); } @@ -2323,7 +2326,9 @@ btr_page_insert_fits( space after rec is removed from page. */ *offsets = rec_get_offsets(rec, cursor->index, *offsets, - page_is_leaf(page), + page_is_leaf(page) + ? cursor->index->n_core_fields + : 0, ULINT_UNDEFINED, heap); total_data -= rec_offs_size(*offsets); @@ -2583,7 +2588,8 @@ btr_page_tuple_smaller( first_rec = page_cur_get_rec(&pcur); *offsets = rec_get_offsets( - first_rec, cursor->index, *offsets, page_is_leaf(block->frame), + first_rec, cursor->index, *offsets, + page_is_leaf(block->frame) ? cursor->index->n_core_fields : 0, n_uniq, heap); return(cmp_dtuple_rec(tuple, first_rec, *offsets) < 0); @@ -2872,7 +2878,9 @@ func_start: first_rec = move_limit = split_rec; *offsets = rec_get_offsets(split_rec, cursor->index, *offsets, - page_is_leaf(page), n_uniq, heap); + page_is_leaf(page) + ? cursor->index->n_core_fields : 0, + n_uniq, heap); insert_left = !tuple || cmp_dtuple_rec(tuple, split_rec, *offsets) < 0; @@ -3518,7 +3526,7 @@ retry: rec_offs* offsets2 = NULL; /* For rtree, we need to update father's mbr. */ - if (dict_index_is_spatial(index)) { + if (index->is_spatial()) { /* We only support merge pages with the same parent page */ if (!rtr_check_same_block( @@ -3536,7 +3544,8 @@ retry: offsets2 = rec_get_offsets( btr_cur_get_rec(&cursor2), index, NULL, - page_is_leaf(cursor2.page_cur.block->frame), + page_is_leaf(cursor2.page_cur.block->frame) + ? index->n_fields : 0, ULINT_UNDEFINED, &heap); /* Check if parent entry needs to be updated */ @@ -3706,13 +3715,14 @@ retry: #endif /* UNIV_DEBUG */ /* For rtree, we need to update father's mbr. */ - if (dict_index_is_spatial(index)) { + if (index->is_spatial()) { rec_offs* offsets2; ulint rec_info; offsets2 = rec_get_offsets( btr_cur_get_rec(&cursor2), index, NULL, - page_is_leaf(cursor2.page_cur.block->frame), + page_is_leaf(cursor2.page_cur.block->frame) + ? index->n_fields : 0, ULINT_UNDEFINED, &heap); ut_ad(btr_node_ptr_get_child_page_no( @@ -3927,16 +3937,16 @@ btr_discard_only_page_on_level( } #endif /* UNIV_BTR_DEBUG */ - mem_heap_t* heap = NULL; - const rec_t* rec = NULL; - rec_offs* offsets = NULL; - + mem_heap_t* heap = nullptr; + const rec_t* rec = nullptr; + rec_offs* offsets = nullptr; if (index->table->instant || index->must_avoid_clear_instant_add()) { if (!rec_is_metadata(r, *index)) { } else if (!index->table->instant || rec_is_alter_metadata(r, *index)) { heap = mem_heap_create(srv_page_size); - offsets = rec_get_offsets(r, index, NULL, true, + offsets = rec_get_offsets(r, index, nullptr, + index->n_core_fields, ULINT_UNDEFINED, &heap); rec = rec_copy(mem_heap_alloc(heap, rec_offs_size(offsets)), @@ -4193,7 +4203,7 @@ btr_print_recursive( node_ptr = page_cur_get_rec(&cursor); *offsets = rec_get_offsets( - node_ptr, index, *offsets, false, + node_ptr, index, *offsets, 0, ULINT_UNDEFINED, heap); btr_print_recursive(index, btr_node_ptr_get_child(node_ptr, @@ -4342,7 +4352,9 @@ btr_index_rec_validate( page = page_align(rec); - if (dict_index_is_ibuf(index)) { + ut_ad(index->n_core_fields); + + if (index->is_ibuf()) { /* The insert buffer index tree can contain records from any other index: we cannot check the number of fields or their length */ @@ -4406,7 +4418,8 @@ n_field_mismatch: } } - offsets = rec_get_offsets(rec, index, offsets, page_is_leaf(page), + offsets = rec_get_offsets(rec, index, offsets, page_is_leaf(page) + ? index->n_core_fields : 0, ULINT_UNDEFINED, &heap); const dict_field_t* field = index->fields; ut_ad(rec_offs_n_fields(offsets) @@ -4659,7 +4672,7 @@ btr_validate_level( page_cur_move_to_next(&cursor); node_ptr = page_cur_get_rec(&cursor); - offsets = rec_get_offsets(node_ptr, index, offsets, false, + offsets = rec_get_offsets(node_ptr, index, offsets, 0, ULINT_UNDEFINED, &heap); savepoint2 = mtr_set_savepoint(&mtr); @@ -4778,10 +4791,12 @@ loop: right_rec = page_rec_get_next(page_get_infimum_rec( right_page)); offsets = rec_get_offsets(rec, index, offsets, - page_is_leaf(page), + page_is_leaf(page) + ? index->n_core_fields : 0, ULINT_UNDEFINED, &heap); offsets2 = rec_get_offsets(right_rec, index, offsets2, - page_is_leaf(right_page), + page_is_leaf(right_page) + ? index->n_core_fields : 0, ULINT_UNDEFINED, &heap); /* For spatial index, we cannot guarantee the key ordering diff --git a/storage/innobase/btr/btr0bulk.cc b/storage/innobase/btr/btr0bulk.cc index 6e8b88172e8..9004064a1b9 100644 --- a/storage/innobase/btr/btr0bulk.cc +++ b/storage/innobase/btr/btr0bulk.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2014, 2019, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -170,7 +170,8 @@ inline void PageBulk::insertPage(rec_t *rec, rec_offs *offsets) (fmt == REDUNDANT ? PAGE_OLD_INFIMUM : PAGE_NEW_INFIMUM)) { const rec_t *old_rec = m_cur_rec; - rec_offs *old_offsets= rec_get_offsets(old_rec, m_index, nullptr, is_leaf, + rec_offs *old_offsets= rec_get_offsets(old_rec, m_index, nullptr, is_leaf + ? m_index->n_core_fields : 0, ULINT_UNDEFINED, &m_heap); ut_ad(cmp_rec_rec(rec, old_rec, offsets, old_offsets, m_index) > 0); } @@ -604,6 +605,7 @@ PageBulk::getSplitRec() ut_ad(m_page_zip != NULL); ut_ad(m_rec_no >= 2); + ut_ad(!m_index->is_instant()); ut_ad(page_get_free_space_of_empty(m_is_comp) > m_free_space); total_used_size = page_get_free_space_of_empty(m_is_comp) @@ -613,13 +615,13 @@ PageBulk::getSplitRec() n_recs = 0; offsets = NULL; rec = page_get_infimum_rec(m_page); + const ulint n_core = page_is_leaf(m_page) ? m_index->n_core_fields : 0; do { rec = page_rec_get_next(rec); ut_ad(page_rec_is_user_rec(rec)); - offsets = rec_get_offsets(rec, m_index, offsets, - page_is_leaf(m_page), + offsets = rec_get_offsets(rec, m_index, offsets, n_core, ULINT_UNDEFINED, &m_heap); total_recs_size += rec_offs_size(offsets); n_recs++; @@ -648,9 +650,11 @@ PageBulk::copyIn( ut_ad(m_rec_no == 0); ut_ad(page_rec_is_user_rec(rec)); + const ulint n_core = page_rec_is_leaf(rec) + ? m_index->n_core_fields : 0; + do { - offsets = rec_get_offsets(rec, m_index, offsets, - page_rec_is_leaf(split_rec), + offsets = rec_get_offsets(rec, m_index, offsets, n_core, ULINT_UNDEFINED, &m_heap); insert(rec, offsets); @@ -691,8 +695,10 @@ PageBulk::copyOut( /* Set last record's next in page */ rec_offs* offsets = NULL; rec = page_rec_get_prev(split_rec); - offsets = rec_get_offsets(rec, m_index, offsets, - page_rec_is_leaf(split_rec), + const ulint n_core = page_rec_is_leaf(split_rec) + ? m_index->n_core_fields : 0; + + offsets = rec_get_offsets(rec, m_index, offsets, n_core, ULINT_UNDEFINED, &m_heap); mach_write_to_2(rec - REC_NEXT, m_is_comp ? static_cast<uint16_t> @@ -703,8 +709,7 @@ PageBulk::copyOut( m_cur_rec = rec; m_heap_top = rec_get_end(rec, offsets); - offsets = rec_get_offsets(last_rec, m_index, offsets, - page_rec_is_leaf(split_rec), + offsets = rec_get_offsets(last_rec, m_index, offsets, n_core, ULINT_UNDEFINED, &m_heap); m_free_space += ulint(rec_get_end(last_rec, offsets) - m_heap_top) @@ -1118,7 +1123,8 @@ BtrBulk::insert( /* Convert tuple to rec. */ rec = rec_convert_dtuple_to_rec(static_cast<byte*>(mem_heap_alloc( page_bulk->m_heap, rec_size)), m_index, tuple, n_ext); - offsets = rec_get_offsets(rec, m_index, offsets, !level, + offsets = rec_get_offsets(rec, m_index, offsets, level + ? 0 : m_index->n_core_fields, ULINT_UNDEFINED, &page_bulk->m_heap); page_bulk->insert(rec, offsets); diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index 18671308ece..7cf3301bdb9 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -592,7 +592,8 @@ incompatible: } mem_heap_t* heap = NULL; - rec_offs* offsets = rec_get_offsets(rec, index, NULL, true, + rec_offs* offsets = rec_get_offsets(rec, index, NULL, + index->n_core_fields, ULINT_UNDEFINED, &heap); if (rec_offs_any_default(offsets)) { inconsistent: @@ -2039,7 +2040,7 @@ retry_page_get: node_ptr = page_cur_get_rec(page_cursor); - offsets = rec_get_offsets(node_ptr, index, offsets, false, + offsets = rec_get_offsets(node_ptr, index, offsets, 0, ULINT_UNDEFINED, &heap); /* If the rec is the first or last in the page for @@ -2169,7 +2170,7 @@ need_opposite_intention: offsets2 = rec_get_offsets( first_rec, index, offsets2, - false, ULINT_UNDEFINED, &heap); + 0, ULINT_UNDEFINED, &heap); cmp_rec_rec(node_ptr, first_rec, offsets, offsets2, index, false, &matched_fields); @@ -2187,7 +2188,7 @@ need_opposite_intention: offsets2 = rec_get_offsets( last_rec, index, offsets2, - false, ULINT_UNDEFINED, &heap); + 0, ULINT_UNDEFINED, &heap); cmp_rec_rec( node_ptr, last_rec, offsets, offsets2, index, @@ -2356,7 +2357,7 @@ need_opposite_intention: offsets = rec_get_offsets( my_node_ptr, index, offsets, - false, ULINT_UNDEFINED, &heap); + 0, ULINT_UNDEFINED, &heap); ulint my_page_no = btr_node_ptr_get_child_page_no( @@ -2781,7 +2782,7 @@ btr_cur_open_at_index_side_func( node_ptr = page_cur_get_rec(page_cursor); offsets = rec_get_offsets(node_ptr, cursor->index, offsets, - false, ULINT_UNDEFINED, &heap); + 0, ULINT_UNDEFINED, &heap); /* If the rec is the first or last in the page for pessimistic delete intention, it might cause node_ptr insert @@ -3073,7 +3074,7 @@ btr_cur_open_at_rnd_pos_func( node_ptr = page_cur_get_rec(page_cursor); offsets = rec_get_offsets(node_ptr, cursor->index, offsets, - false, ULINT_UNDEFINED, &heap); + 0, ULINT_UNDEFINED, &heap); /* If the rec is the first or last in the page for pessimistic delete intention, it might cause node_ptr insert @@ -4584,7 +4585,7 @@ btr_cur_optimistic_update( ut_ad(fil_page_index_page_check(page)); ut_ad(btr_page_get_index_id(page) == index->id); - *offsets = rec_get_offsets(rec, index, *offsets, true, + *offsets = rec_get_offsets(rec, index, *offsets, index->n_core_fields, ULINT_UNDEFINED, heap); #if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG ut_a(!rec_offs_any_null_extern(rec, *offsets) @@ -5509,7 +5510,8 @@ btr_cur_optimistic_delete_func( rec = btr_cur_get_rec(cursor); - offsets = rec_get_offsets(rec, cursor->index, offsets, true, + offsets = rec_get_offsets(rec, cursor->index, offsets, + cursor->index->n_core_fields, ULINT_UNDEFINED, &heap); const ibool no_compress_needed = !rec_offs_any_extern(offsets) @@ -5717,7 +5719,8 @@ btr_cur_pessimistic_delete( ut_a(!page_zip || page_zip_validate(page_zip, page, index)); #endif /* UNIV_ZIP_DEBUG */ - offsets = rec_get_offsets(rec, index, NULL, page_is_leaf(page), + offsets = rec_get_offsets(rec, index, NULL, page_is_leaf(page) + ? index->n_core_fields : 0, ULINT_UNDEFINED, &heap); if (rec_offs_any_extern(offsets)) { @@ -5818,7 +5821,7 @@ discard_page: pointer as the predefined minimum record */ min_mark_next_rec = true; - } else if (dict_index_is_spatial(index)) { + } else if (index->is_spatial()) { /* For rtree, if delete the leftmost node pointer, we need to update parent page. */ rtr_mbr_t father_mbr; @@ -5833,7 +5836,7 @@ discard_page: &father_cursor); offsets = rec_get_offsets( btr_cur_get_rec(&father_cursor), index, NULL, - false, ULINT_UNDEFINED, &heap); + 0, ULINT_UNDEFINED, &heap); father_rec = btr_cur_get_rec(&father_cursor); rtr_read_mbr(rec_get_nth_field( @@ -6753,12 +6756,13 @@ btr_estimate_number_of_different_key_vals(dict_index_t* index) page = btr_cur_get_page(&cursor); rec = page_rec_get_next(page_get_infimum_rec(page)); - const bool is_leaf = page_is_leaf(page); + const ulint n_core = page_is_leaf(page) + ? index->n_core_fields : 0; if (!page_rec_is_supremum(rec)) { not_empty_flag = 1; offsets_rec = rec_get_offsets(rec, index, offsets_rec, - is_leaf, + n_core, ULINT_UNDEFINED, &heap); if (n_not_null != NULL) { @@ -6779,7 +6783,7 @@ btr_estimate_number_of_different_key_vals(dict_index_t* index) offsets_next_rec = rec_get_offsets(next_rec, index, offsets_next_rec, - is_leaf, + n_core, ULINT_UNDEFINED, &heap); diff --git a/storage/innobase/btr/btr0defragment.cc b/storage/innobase/btr/btr0defragment.cc index 2c4c338ce70..ebe9854b5dc 100644 --- a/storage/innobase/btr/btr0defragment.cc +++ b/storage/innobase/btr/btr0defragment.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (C) 2012, 2014 Facebook, Inc. All Rights Reserved. -Copyright (C) 2014, 2020, MariaDB Corporation. +Copyright (C) 2014, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -384,12 +384,12 @@ btr_defragment_calc_n_recs_for_size( ulint size = 0; page_cur_t cur; + const ulint n_core = page_is_leaf(page) ? index->n_core_fields : 0; page_cur_set_before_first(block, &cur); page_cur_move_to_next(&cur); while (page_cur_get_rec(&cur) != page_get_supremum_rec(page)) { rec_t* cur_rec = page_cur_get_rec(&cur); - offsets = rec_get_offsets(cur_rec, index, offsets, - page_is_leaf(page), + offsets = rec_get_offsets(cur_rec, index, offsets, n_core, ULINT_UNDEFINED, &heap); ulint rec_size = rec_offs_size(offsets); size += rec_size; @@ -401,6 +401,9 @@ btr_defragment_calc_n_recs_for_size( page_cur_move_to_next(&cur); } *n_recs_size = size; + if (UNIV_LIKELY_NULL(heap)) { + mem_heap_free(heap); + } return n_recs; } diff --git a/storage/innobase/btr/btr0pcur.cc b/storage/innobase/btr/btr0pcur.cc index 27ca51c3c3a..574998a9f3f 100644 --- a/storage/innobase/btr/btr0pcur.cc +++ b/storage/innobase/btr/btr0pcur.cc @@ -61,6 +61,7 @@ btr_pcur_reset( cursor->btr_cur.index = NULL; cursor->btr_cur.page_cur.rec = NULL; cursor->old_rec = NULL; + cursor->old_n_core_fields = 0; cursor->old_n_fields = 0; cursor->old_stored = false; @@ -184,19 +185,21 @@ before_first: if (index->is_ibuf()) { ut_ad(!index->table->not_redundant()); - cursor->old_n_fields = rec_get_n_fields_old(rec); - } else if (page_rec_is_leaf(rec)) { - cursor->old_n_fields = dict_index_get_n_unique_in_tree(index); - } else if (index->is_spatial()) { - ut_ad(dict_index_get_n_unique_in_tree_nonleaf(index) - == DICT_INDEX_SPATIAL_NODEPTR_SIZE); - /* For R-tree, we have to compare - the child page numbers as well. */ - cursor->old_n_fields = DICT_INDEX_SPATIAL_NODEPTR_SIZE + 1; + cursor->old_n_fields = uint16_t(rec_get_n_fields_old(rec)); } else { - cursor->old_n_fields = dict_index_get_n_unique_in_tree(index); + cursor->old_n_fields = static_cast<uint16>( + dict_index_get_n_unique_in_tree(index)); + if (index->is_spatial() && !page_rec_is_leaf(rec)) { + ut_ad(dict_index_get_n_unique_in_tree_nonleaf(index) + == DICT_INDEX_SPATIAL_NODEPTR_SIZE); + /* For R-tree, we have to compare + the child page numbers as well. */ + cursor->old_n_fields + = DICT_INDEX_SPATIAL_NODEPTR_SIZE + 1; + } } + cursor->old_n_core_fields = index->n_core_fields; cursor->old_rec = rec_copy_prefix_to_buf(rec, index, cursor->old_n_fields, &cursor->old_rec_buf, @@ -231,6 +234,7 @@ btr_pcur_copy_stored_position( + (pcur_donate->old_rec - pcur_donate->old_rec_buf); } + pcur_receive->old_n_core_fields = pcur_donate->old_n_core_fields; pcur_receive->old_n_fields = pcur_donate->old_n_fields; } @@ -322,6 +326,8 @@ btr_pcur_restore_position_func( } ut_a(cursor->old_rec); + ut_a(cursor->old_n_core_fields); + ut_a(cursor->old_n_core_fields <= index->n_core_fields); ut_a(cursor->old_n_fields); switch (latch_mode) { @@ -355,11 +361,16 @@ btr_pcur_restore_position_func( rec_offs_init(offsets2_); heap = mem_heap_create(256); + ut_ad(cursor->old_n_core_fields + == index->n_core_fields); + offsets1 = rec_get_offsets( - cursor->old_rec, index, offsets1, true, + cursor->old_rec, index, offsets1, + cursor->old_n_core_fields, cursor->old_n_fields, &heap); offsets2 = rec_get_offsets( - rec, index, offsets2, true, + rec, index, offsets2, + index->n_core_fields, cursor->old_n_fields, &heap); ut_ad(!cmp_rec_rec(cursor->old_rec, @@ -384,8 +395,14 @@ btr_pcur_restore_position_func( heap = mem_heap_create(256); - tuple = dict_index_build_data_tuple(cursor->old_rec, index, true, - cursor->old_n_fields, heap); + tuple = dtuple_create(heap, cursor->old_n_fields); + + dict_index_copy_types(tuple, index, cursor->old_n_fields); + + rec_copy_prefix_to_dtuple(tuple, cursor->old_rec, index, + cursor->old_n_core_fields, + cursor->old_n_fields, heap); + ut_ad(dtuple_check_typed(tuple)); /* Save the old search mode of the cursor */ old_mode = cursor->search_mode; @@ -424,7 +441,8 @@ btr_pcur_restore_position_func( && btr_pcur_is_on_user_rec(cursor) && !cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor), rec_get_offsets(btr_pcur_get_rec(cursor), - index, offsets, true, + index, offsets, + index->n_core_fields, ULINT_UNDEFINED, &heap))) { /* We have to store the NEW value for the modify clock, diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc index b00009820a8..f22e3a5991b 100644 --- a/storage/innobase/btr/btr0sea.cc +++ b/storage/innobase/btr/btr0sea.cc @@ -737,7 +737,8 @@ btr_search_update_hash_ref( ulint fold = rec_fold( rec, - rec_get_offsets(rec, index, offsets_, true, + rec_get_offsets(rec, index, offsets_, + index->n_core_fields, ULINT_UNDEFINED, &heap), block->curr_n_fields, block->curr_n_bytes, index->id); @@ -795,7 +796,8 @@ btr_search_check_guess( match = 0; - offsets = rec_get_offsets(rec, cursor->index, offsets, true, + offsets = rec_get_offsets(rec, cursor->index, offsets, + cursor->index->n_core_fields, n_unique, &heap); cmp = cmp_dtuple_rec_with_match(tuple, rec, offsets, &match); @@ -846,7 +848,8 @@ btr_search_check_guess( } offsets = rec_get_offsets(prev_rec, cursor->index, offsets, - true, n_unique, &heap); + cursor->index->n_core_fields, + n_unique, &heap); cmp = cmp_dtuple_rec_with_match( tuple, prev_rec, offsets, &match); if (mode == PAGE_CUR_GE) { @@ -869,7 +872,8 @@ btr_search_check_guess( } offsets = rec_get_offsets(next_rec, cursor->index, offsets, - true, n_unique, &heap); + cursor->index->n_core_fields, + n_unique, &heap); cmp = cmp_dtuple_rec_with_match( tuple, next_rec, offsets, &match); if (mode == PAGE_CUR_LE) { @@ -1344,7 +1348,7 @@ retry: while (!page_rec_is_supremum(rec)) { offsets = rec_get_offsets( - rec, index, offsets, true, + rec, index, offsets, index->n_core_fields, btr_search_get_n_fields(n_fields, n_bytes), &heap); fold = rec_fold(rec, offsets, n_fields, n_bytes, index_id); @@ -1568,7 +1572,7 @@ btr_search_build_page_hash_index( ut_a(index->id == btr_page_get_index_id(page)); offsets = rec_get_offsets( - rec, index, offsets, true, + rec, index, offsets, index->n_core_fields, btr_search_get_n_fields(n_fields, n_bytes), &heap); ut_ad(page_rec_is_supremum(rec) @@ -1599,7 +1603,7 @@ btr_search_build_page_hash_index( } offsets = rec_get_offsets( - next_rec, index, offsets, true, + next_rec, index, offsets, index->n_core_fields, btr_search_get_n_fields(n_fields, n_bytes), &heap); next_fold = rec_fold(next_rec, offsets, n_fields, n_bytes, index->id); @@ -1840,7 +1844,8 @@ void btr_search_update_hash_on_delete(btr_cur_t* cursor) rec = btr_cur_get_rec(cursor); - fold = rec_fold(rec, rec_get_offsets(rec, index, offsets_, true, + fold = rec_fold(rec, rec_get_offsets(rec, index, offsets_, + index->n_core_fields, ULINT_UNDEFINED, &heap), block->curr_n_fields, block->curr_n_bytes, index->id); if (UNIV_LIKELY_NULL(heap)) { @@ -2013,13 +2018,14 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch) ins_rec = page_rec_get_next_const(rec); next_rec = page_rec_get_next_const(ins_rec); - offsets = rec_get_offsets(ins_rec, index, offsets, true, + offsets = rec_get_offsets(ins_rec, index, offsets, + index->n_core_fields, ULINT_UNDEFINED, &heap); ins_fold = rec_fold(ins_rec, offsets, n_fields, n_bytes, index->id); if (!page_rec_is_supremum(next_rec)) { offsets = rec_get_offsets( - next_rec, index, offsets, true, + next_rec, index, offsets, index->n_core_fields, btr_search_get_n_fields(n_fields, n_bytes), &heap); next_fold = rec_fold(next_rec, offsets, n_fields, n_bytes, index->id); @@ -2031,7 +2037,7 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch) if (!page_rec_is_infimum(rec) && !rec_is_metadata(rec, *index)) { offsets = rec_get_offsets( - rec, index, offsets, true, + rec, index, offsets, index->n_core_fields, btr_search_get_n_fields(n_fields, n_bytes), &heap); fold = rec_fold(rec, offsets, n_fields, n_bytes, index->id); } else { @@ -2259,7 +2265,8 @@ state_ok: page_index_id = btr_page_get_index_id(block->frame); offsets = rec_get_offsets( - node->data, block->index, offsets, true, + node->data, block->index, offsets, + block->index->n_core_fields, btr_search_get_n_fields(block->curr_n_fields, block->curr_n_bytes), &heap); diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index f613162fb04..06a38f49212 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -2,7 +2,7 @@ Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2020, MariaDB Corporation. +Copyright (c) 2013, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -255,7 +255,7 @@ dict_table_try_drop_aborted( && !UT_LIST_GET_FIRST(table->locks)) { /* Silence a debug assertion in row_merge_drop_indexes(). */ ut_d(table->acquire()); - row_merge_drop_indexes(trx, table, TRUE); + row_merge_drop_indexes(trx, table, true); ut_d(table->release()); ut_ad(table->get_ref_count() == ref_count); trx_commit_for_mysql(trx); @@ -3866,7 +3866,9 @@ dict_index_build_node_ptr( dtype_set(dfield_get_type(field), DATA_SYS_CHILD, DATA_NOT_NULL, 4); - rec_copy_prefix_to_dtuple(tuple, rec, index, !level, n_unique, heap); + rec_copy_prefix_to_dtuple(tuple, rec, index, + level ? 0 : index->n_core_fields, + n_unique, heap); dtuple_set_info_bits(tuple, dtuple_get_info_bits(tuple) | REC_STATUS_NODE_PTR); @@ -3890,11 +3892,14 @@ dict_index_build_data_tuple( ulint n_fields, mem_heap_t* heap) { + ut_ad(!index->is_clust()); + dtuple_t* tuple = dtuple_create(heap, n_fields); dict_index_copy_types(tuple, index, n_fields); - rec_copy_prefix_to_dtuple(tuple, rec, index, leaf, n_fields, heap); + rec_copy_prefix_to_dtuple(tuple, rec, index, + leaf ? n_fields : 0, n_fields, heap); ut_ad(dtuple_check_typed(tuple)); diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc index 96f2d7b6e3b..97889e22981 100644 --- a/storage/innobase/dict/dict0mem.cc +++ b/storage/innobase/dict/dict0mem.cc @@ -2,7 +2,7 @@ Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2020, MariaDB Corporation. +Copyright (c) 2013, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -938,7 +938,7 @@ dict_mem_fill_vcol_from_v_indexes( Later virtual column set will be refreshed during loading of table. */ if (!dict_index_has_virtual(index) - || index->has_new_v_col) { + || index->has_new_v_col()) { continue; } @@ -1377,7 +1377,8 @@ dict_index_t::vers_history_row( rec_t* clust_rec = row_get_clust_rec(BTR_SEARCH_LEAF, rec, this, &clust_index, &mtr); if (clust_rec) { - offsets = rec_get_offsets(clust_rec, clust_index, offsets, true, + offsets = rec_get_offsets(clust_rec, clust_index, offsets, + clust_index->n_core_fields, ULINT_UNDEFINED, &heap); history_row = clust_index->vers_history_row(clust_rec, offsets); diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index 8386cc80d81..42f75252cee 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2009, 2019, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, 2020, MariaDB Corporation. +Copyright (c) 2015, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1156,7 +1156,7 @@ dict_stats_analyze_index_level( prev_rec_offsets = rec_get_offsets( prev_rec, index, prev_rec_offsets, - true, + index->n_core_fields, n_uniq, &heap); prev_rec = rec_copy_prefix_to_buf( @@ -1168,8 +1168,9 @@ dict_stats_analyze_index_level( continue; } - rec_offsets = rec_get_offsets( - rec, index, rec_offsets, !level, n_uniq, &heap); + rec_offsets = rec_get_offsets(rec, index, rec_offsets, + level ? 0 : index->n_core_fields, + n_uniq, &heap); (*total_recs)++; @@ -1177,7 +1178,8 @@ dict_stats_analyze_index_level( ulint matched_fields; prev_rec_offsets = rec_get_offsets( - prev_rec, index, prev_rec_offsets, !level, + prev_rec, index, prev_rec_offsets, + level ? 0 : index->n_core_fields, n_uniq, &heap); cmp_rec_rec(prev_rec, rec, @@ -1331,7 +1333,7 @@ be big enough) @param[in] index index of the page @param[in] page the page to scan @param[in] n_prefix look at the first n_prefix columns -@param[in] is_leaf whether this is the leaf page +@param[in] n_core 0, or index->n_core_fields for leaf @param[out] n_diff number of distinct records encountered @param[out] n_external_pages if this is non-NULL then it will be set to the number of externally stored pages which were encountered @@ -1346,7 +1348,7 @@ dict_stats_scan_page( const dict_index_t* index, const page_t* page, ulint n_prefix, - bool is_leaf, + ulint n_core, ib_uint64_t* n_diff, ib_uint64_t* n_external_pages) { @@ -1358,9 +1360,9 @@ dict_stats_scan_page( Because offsets1,offsets2 should be big enough, this memory heap should never be used. */ mem_heap_t* heap = NULL; - ut_ad(is_leaf == page_is_leaf(page)); + ut_ad(!!n_core == page_is_leaf(page)); const rec_t* (*get_next)(const rec_t*) - = !is_leaf || srv_stats_include_delete_marked + = !n_core || srv_stats_include_delete_marked ? page_rec_get_next_const : page_rec_get_next_non_del_marked; @@ -1379,7 +1381,7 @@ dict_stats_scan_page( return(NULL); } - offsets_rec = rec_get_offsets(rec, index, offsets_rec, is_leaf, + offsets_rec = rec_get_offsets(rec, index, offsets_rec, n_core, ULINT_UNDEFINED, &heap); if (should_count_external_pages) { @@ -1396,7 +1398,7 @@ dict_stats_scan_page( ulint matched_fields; offsets_next_rec = rec_get_offsets(next_rec, index, - offsets_next_rec, is_leaf, + offsets_next_rec, n_core, ULINT_UNDEFINED, &heap); @@ -1410,7 +1412,7 @@ dict_stats_scan_page( (*n_diff)++; - if (!is_leaf) { + if (!n_core) { break; } } @@ -1497,7 +1499,7 @@ dict_stats_analyze_index_below_cur( page = page_align(rec); ut_ad(!page_rec_is_leaf(rec)); - offsets_rec = rec_get_offsets(rec, index, offsets1, false, + offsets_rec = rec_get_offsets(rec, index, offsets1, 0, ULINT_UNDEFINED, &heap); page_id_t page_id(index->table->space_id, @@ -1533,7 +1535,7 @@ dict_stats_analyze_index_below_cur( /* search for the first non-boring record on the page */ offsets_rec = dict_stats_scan_page( &rec, offsets1, offsets2, index, page, n_prefix, - false, n_diff, NULL); + 0, n_diff, NULL); /* pages on level > 0 are not allowed to be empty */ ut_a(offsets_rec != NULL); @@ -1578,7 +1580,7 @@ dict_stats_analyze_index_below_cur( offsets_rec = dict_stats_scan_page( &rec, offsets1, offsets2, index, page, n_prefix, - true, n_diff, + index->n_core_fields, n_diff, n_external_pages); #if 0 diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc index bd7ae83b53a..afeb8ef6c77 100644 --- a/storage/innobase/dict/dict0stats_bg.cc +++ b/storage/innobase/dict/dict0stats_bg.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2012, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -146,9 +146,24 @@ schedule new estimates for table and index statistics to be calculated. void dict_stats_update_if_needed_func(dict_table_t *table) #endif { - ut_ad(table->stat_initialized); ut_ad(!mutex_own(&dict_sys.mutex)); + if (UNIV_UNLIKELY(!table->stat_initialized)) { + /* The table may have been evicted from dict_sys + and reloaded internally by InnoDB for FOREIGN KEY + processing, but not reloaded by the SQL layer. + + We can (re)compute the transient statistics when the + table is actually loaded by the SQL layer. + + Note: If InnoDB persistent statistics are enabled, + we will skip the updates. We must do this, because + dict_table_get_n_rows() below assumes that the + statistics have been initialized. The DBA may have + to execute ANALYZE TABLE. */ + return; + } + ulonglong counter = table->stat_modified_counter++; ulonglong n_rows = dict_table_get_n_rows(table); diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index d35da0fe843..cc0a41042af 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2020, MariaDB Corporation. +Copyright (c) 2016, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -2505,7 +2505,8 @@ fts_get_max_cache_size( } } else { ib::error() << "(" << error << ") reading max" - " cache config value from config table"; + " cache config value from config table " + << fts_table->table->name; } ut_free(value.f_str); @@ -2678,7 +2679,8 @@ func_exit: } else { *doc_id = 0; - ib::error() << "(" << error << ") while getting next doc id."; + ib::error() << "(" << error << ") while getting next doc id " + "for table " << table->name; fts_sql_rollback(trx); if (error == DB_DEADLOCK) { @@ -2758,7 +2760,8 @@ fts_update_sync_doc_id( cache->synced_doc_id = doc_id; } else { ib::error() << "(" << error << ") while" - " updating last doc id."; + " updating last doc id for table" + << table->name; fts_sql_rollback(trx); } @@ -3469,7 +3472,8 @@ fts_add_doc_by_id( } - offsets = rec_get_offsets(clust_rec, clust_index, NULL, true, + offsets = rec_get_offsets(clust_rec, clust_index, NULL, + clust_index->n_core_fields, ULINT_UNDEFINED, &heap); for (ulint i = 0; i < num_idx; ++i) { @@ -3983,7 +3987,8 @@ fts_sync_write_words( if (UNIV_UNLIKELY(error != DB_SUCCESS) && !print_error) { ib::error() << "(" << error << ") writing" - " word node to FTS auxiliary index table."; + " word node to FTS auxiliary index table " + << table->name; print_error = TRUE; } } @@ -4138,7 +4143,8 @@ fts_sync_commit( fts_sql_commit(trx); } else { fts_sql_rollback(trx); - ib::error() << "(" << error << ") during SYNC."; + ib::error() << "(" << error << ") during SYNC of " + "table " << sync->table->name; } if (UNIV_UNLIKELY(fts_enable_diag_print) && elapsed_time) { @@ -4901,7 +4907,8 @@ fts_get_rows_count( trx->error_state = DB_SUCCESS; } else { ib::error() << "(" << error - << ") while reading FTS table."; + << ") while reading FTS table " + << table_name; break; /* Exit the loop. */ } diff --git a/storage/innobase/gis/gis0rtree.cc b/storage/innobase/gis/gis0rtree.cc index 2e50d1b2cad..22e6e08f139 100644 --- a/storage/innobase/gis/gis0rtree.cc +++ b/storage/innobase/gis/gis0rtree.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2018, 2020, MariaDB Corporation. +Copyright (c) 2018, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -87,8 +87,9 @@ rtr_page_split_initialize_nodes( stop = task + n_recs; rec = page_rec_get_next(page_get_infimum_rec(page)); - const bool is_leaf = page_is_leaf(page); - *offsets = rec_get_offsets(rec, cursor->index, *offsets, is_leaf, + const ulint n_core = page_is_leaf(page) + ? cursor->index->n_core_fields : 0; + *offsets = rec_get_offsets(rec, cursor->index, *offsets, n_core, n_uniq, &heap); source_cur = rec_get_nth_field(rec, *offsets, 0, &len); @@ -101,7 +102,7 @@ rtr_page_split_initialize_nodes( rec = page_rec_get_next(rec); *offsets = rec_get_offsets(rec, cursor->index, *offsets, - is_leaf, n_uniq, &heap); + n_core, n_uniq, &heap); source_cur = rec_get_nth_field(rec, *offsets, 0, &len); } @@ -230,7 +231,8 @@ rtr_update_mbr_field( ut_ad(page == buf_block_get_frame(block)); child = btr_node_ptr_get_child_page_no(rec, offsets); - const bool is_leaf = page_is_leaf(block->frame); + const ulint n_core = page_is_leaf(block->frame) + ? index->n_core_fields : 0; if (new_rec) { child_rec = new_rec; @@ -246,7 +248,7 @@ rtr_update_mbr_field( if (cursor2) { rec_t* del_rec = btr_cur_get_rec(cursor2); offsets2 = rec_get_offsets(btr_cur_get_rec(cursor2), - index, NULL, false, + index, NULL, 0, ULINT_UNDEFINED, &heap); del_page_no = btr_node_ptr_get_child_page_no(del_rec, offsets2); cur2_pos = page_rec_get_n_recs_before(btr_cur_get_rec(cursor2)); @@ -313,7 +315,7 @@ rtr_update_mbr_field( = page_rec_get_nth(page, cur2_pos); } offsets2 = rec_get_offsets(btr_cur_get_rec(cursor2), - index, NULL, false, + index, NULL, 0, ULINT_UNDEFINED, &heap); ut_ad(del_page_no == btr_node_ptr_get_child_page_no( cursor2->page_cur.rec, @@ -351,7 +353,7 @@ rtr_update_mbr_field( ut_ad(old_rec != insert_rec); page_cur_position(old_rec, block, &page_cur); - offsets2 = rec_get_offsets(old_rec, index, NULL, is_leaf, + offsets2 = rec_get_offsets(old_rec, index, NULL, n_core, ULINT_UNDEFINED, &heap); page_cur_delete_rec(&page_cur, index, offsets2, mtr); @@ -381,7 +383,7 @@ update_mbr: cur2_rec = cursor2->page_cur.rec; offsets2 = rec_get_offsets(cur2_rec, index, NULL, - is_leaf, + n_core, ULINT_UNDEFINED, &heap); cur2_rec_info = rec_get_info_bits(cur2_rec, @@ -441,7 +443,7 @@ update_mbr: if (ins_suc) { btr_cur_position(index, insert_rec, block, cursor); offsets = rec_get_offsets(insert_rec, - index, offsets, is_leaf, + index, offsets, n_core, ULINT_UNDEFINED, &heap); } @@ -456,7 +458,7 @@ update_mbr: cur2_rec = btr_cur_get_rec(cursor2); offsets2 = rec_get_offsets(cur2_rec, index, NULL, - is_leaf, + n_core, ULINT_UNDEFINED, &heap); /* If the cursor2 position is on a wrong rec, we @@ -470,7 +472,7 @@ update_mbr: while (!page_rec_is_supremum(cur2_rec)) { offsets2 = rec_get_offsets(cur2_rec, index, NULL, - is_leaf, + n_core, ULINT_UNDEFINED, &heap); cur2_pno = btr_node_ptr_get_child_page_no( @@ -747,7 +749,8 @@ rtr_split_page_move_rec_list( rec_move = static_cast<rtr_rec_move_t*>(mem_heap_alloc( heap, sizeof (*rec_move) * max_to_move)); - const bool is_leaf = page_is_leaf(page); + const ulint n_core = page_is_leaf(page) + ? index->n_core_fields : 0; /* Insert the recs in group 2 to new page. */ for (cur_split_node = node_array; @@ -757,10 +760,10 @@ rtr_split_page_move_rec_list( block, cur_split_node->key); offsets = rec_get_offsets(cur_split_node->key, - index, offsets, is_leaf, + index, offsets, n_core, ULINT_UNDEFINED, &heap); - ut_ad(!is_leaf || cur_split_node->key != first_rec); + ut_ad(!n_core || cur_split_node->key != first_rec); rec = page_cur_insert_rec_low( &new_page_cursor, @@ -792,7 +795,7 @@ rtr_split_page_move_rec_list( same temp-table in parallel. max_trx_id is ignored for temp tables because it not required for MVCC. */ - if (is_leaf && !index->table->is_temporary()) { + if (n_core && !index->table->is_temporary()) { page_update_max_trx_id(new_block, NULL, page_get_max_trx_id(page), mtr); @@ -846,7 +849,7 @@ rtr_split_page_move_rec_list( block, &page_cursor); offsets = rec_get_offsets( page_cur_get_rec(&page_cursor), index, - offsets, is_leaf, ULINT_UNDEFINED, + offsets, n_core, ULINT_UNDEFINED, &heap); page_cur_delete_rec(&page_cursor, index, offsets, mtr); @@ -1050,6 +1053,9 @@ func_start: /* Update the lock table */ lock_rtr_move_rec_list(new_block, block, rec_move, moved); + const ulint n_core = page_level + ? 0 : cursor->index->n_core_fields; + /* Delete recs in first group from the new page. */ for (cur_split_node = rtr_split_node_array; cur_split_node < end_split_node - 1; ++cur_split_node) { @@ -1068,7 +1074,7 @@ func_start: *offsets = rec_get_offsets( page_cur_get_rec(page_cursor), - cursor->index, *offsets, !page_level, + cursor->index, *offsets, n_core, ULINT_UNDEFINED, heap); page_cur_delete_rec(page_cursor, @@ -1085,7 +1091,7 @@ func_start: block, page_cursor); *offsets = rec_get_offsets( page_cur_get_rec(page_cursor), - cursor->index, *offsets, !page_level, + cursor->index, *offsets, n_core, ULINT_UNDEFINED, heap); page_cur_delete_rec(page_cursor, cursor->index, *offsets, mtr); @@ -1313,7 +1319,8 @@ rtr_page_copy_rec_list_end_no_locks( rec_offs offsets_2[REC_OFFS_NORMAL_SIZE]; rec_offs* offsets2 = offsets_2; ulint moved = 0; - bool is_leaf = page_is_leaf(new_page); + const ulint n_core = page_is_leaf(new_page) + ? index->n_core_fields : 0; rec_offs_init(offsets_1); rec_offs_init(offsets_2); @@ -1342,14 +1349,14 @@ rtr_page_copy_rec_list_end_no_locks( cur_rec = page_rec_get_next(cur_rec); } - offsets1 = rec_get_offsets(cur1_rec, index, offsets1, is_leaf, + offsets1 = rec_get_offsets(cur1_rec, index, offsets1, n_core, ULINT_UNDEFINED, &heap); while (!page_rec_is_supremum(cur_rec)) { ulint cur_matched_fields = 0; int cmp; offsets2 = rec_get_offsets(cur_rec, index, offsets2, - is_leaf, + n_core, ULINT_UNDEFINED, &heap); cmp = cmp_rec_rec(cur1_rec, cur_rec, offsets1, offsets2, index, false, @@ -1361,7 +1368,7 @@ rtr_page_copy_rec_list_end_no_locks( /* Skip small recs. */ page_cur_move_to_next(&page_cur); cur_rec = page_cur_get_rec(&page_cur); - } else if (is_leaf) { + } else if (n_core) { if (rec_get_deleted_flag(cur1_rec, dict_table_is_comp(index->table))) { goto next; @@ -1384,7 +1391,7 @@ rtr_page_copy_rec_list_end_no_locks( cur_rec = page_cur_get_rec(&page_cur); - offsets1 = rec_get_offsets(cur1_rec, index, offsets1, is_leaf, + offsets1 = rec_get_offsets(cur1_rec, index, offsets1, n_core, ULINT_UNDEFINED, &heap); ins_rec = page_cur_insert_rec_low(&page_cur, index, @@ -1440,7 +1447,8 @@ rtr_page_copy_rec_list_start_no_locks( rec_offs* offsets2 = offsets_2; page_cur_t page_cur; ulint moved = 0; - bool is_leaf = page_is_leaf(buf_block_get_frame(block)); + const ulint n_core = page_is_leaf(buf_block_get_frame(block)) + ? index->n_core_fields : 0; rec_offs_init(offsets_1); rec_offs_init(offsets_2); @@ -1460,14 +1468,14 @@ rtr_page_copy_rec_list_start_no_locks( cur_rec = page_rec_get_next(cur_rec); } - offsets1 = rec_get_offsets(cur1_rec, index, offsets1, is_leaf, + offsets1 = rec_get_offsets(cur1_rec, index, offsets1, n_core, ULINT_UNDEFINED, &heap); while (!page_rec_is_supremum(cur_rec)) { ulint cur_matched_fields = 0; offsets2 = rec_get_offsets(cur_rec, index, offsets2, - is_leaf, + n_core, ULINT_UNDEFINED, &heap); int cmp = cmp_rec_rec(cur1_rec, cur_rec, offsets1, offsets2, index, false, @@ -1480,7 +1488,7 @@ rtr_page_copy_rec_list_start_no_locks( /* Skip small recs. */ page_cur_move_to_next(&page_cur); cur_rec = page_cur_get_rec(&page_cur); - } else if (is_leaf) { + } else if (n_core) { if (rec_get_deleted_flag( cur1_rec, dict_table_is_comp(index->table))) { @@ -1504,7 +1512,7 @@ rtr_page_copy_rec_list_start_no_locks( cur_rec = page_cur_get_rec(&page_cur); - offsets1 = rec_get_offsets(cur1_rec, index, offsets1, is_leaf, + offsets1 = rec_get_offsets(cur1_rec, index, offsets1, n_core, ULINT_UNDEFINED, &heap); ins_rec = page_cur_insert_rec_low(&page_cur, index, @@ -1655,7 +1663,7 @@ rtr_check_same_block( while (!page_rec_is_supremum(rec)) { offsets = rec_get_offsets( - rec, index, NULL, false, ULINT_UNDEFINED, &heap); + rec, index, NULL, 0, ULINT_UNDEFINED, &heap); if (btr_node_ptr_get_child_page_no(rec, offsets) == page_no) { btr_cur_position(index, rec, parentb, cursor); diff --git a/storage/innobase/gis/gis0sea.cc b/storage/innobase/gis/gis0sea.cc index d9a0ae80c33..1c22aab4d00 100644 --- a/storage/innobase/gis/gis0sea.cc +++ b/storage/innobase/gis/gis0sea.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2016, 2018, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -529,8 +529,7 @@ rtr_compare_cursor_rec( rec = btr_cur_get_rec(cursor); - offsets = rec_get_offsets( - rec, index, NULL, false, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, NULL, 0, ULINT_UNDEFINED, heap); return(btr_node_ptr_get_child_page_no(rec, offsets) == page_no); } @@ -831,7 +830,8 @@ rtr_page_get_father_node_ptr( user_rec = btr_cur_get_rec(cursor); ut_a(page_rec_is_user_rec(user_rec)); - offsets = rec_get_offsets(user_rec, index, offsets, !level, + offsets = rec_get_offsets(user_rec, index, offsets, + level ? 0 : index->n_fields, ULINT_UNDEFINED, &heap); rtr_get_mbr_from_rec(user_rec, offsets, &mbr); @@ -848,7 +848,7 @@ rtr_page_get_father_node_ptr( node_ptr = btr_cur_get_rec(cursor); ut_ad(!page_rec_is_comp(node_ptr) || rec_get_status(node_ptr) == REC_STATUS_NODE_PTR); - offsets = rec_get_offsets(node_ptr, index, offsets, false, + offsets = rec_get_offsets(node_ptr, index, offsets, 0, ULINT_UNDEFINED, &heap); ulint child_page = btr_node_ptr_get_child_page_no(node_ptr, offsets); @@ -866,13 +866,14 @@ rtr_page_get_father_node_ptr( print_rec = page_rec_get_next( page_get_infimum_rec(page_align(user_rec))); offsets = rec_get_offsets(print_rec, index, offsets, - page_rec_is_leaf(user_rec), + page_rec_is_leaf(user_rec) + ? index->n_fields : 0, ULINT_UNDEFINED, &heap); error << "; child "; rec_print(error.m_oss, print_rec, rec_get_info_bits(print_rec, rec_offs_comp(offsets)), offsets); - offsets = rec_get_offsets(node_ptr, index, offsets, false, + offsets = rec_get_offsets(node_ptr, index, offsets, 0, ULINT_UNDEFINED, &heap); error << "; parent "; rec_print(error.m_oss, print_rec, @@ -1304,10 +1305,12 @@ rtr_cur_restore_position( heap = mem_heap_create(256); offsets1 = rec_get_offsets( - r_cursor->old_rec, index, NULL, !level, + r_cursor->old_rec, index, NULL, + level ? 0 : r_cursor->old_n_fields, r_cursor->old_n_fields, &heap); offsets2 = rec_get_offsets( - rec, index, NULL, !level, + rec, index, NULL, + level ? 0 : r_cursor->old_n_fields, r_cursor->old_n_fields, &heap); comp = rec_offs_comp(offsets1); @@ -1374,12 +1377,12 @@ search_again: rec = btr_pcur_get_rec(r_cursor); - offsets1 = rec_get_offsets( - r_cursor->old_rec, index, NULL, !level, - r_cursor->old_n_fields, &heap); - offsets2 = rec_get_offsets( - rec, index, NULL, !level, - r_cursor->old_n_fields, &heap); + offsets1 = rec_get_offsets(r_cursor->old_rec, index, NULL, + level ? 0 : r_cursor->old_n_fields, + r_cursor->old_n_fields, &heap); + offsets2 = rec_get_offsets(rec, index, NULL, + level ? 0 : r_cursor->old_n_fields, + r_cursor->old_n_fields, &heap); comp = rec_offs_comp(offsets1); @@ -1716,7 +1719,7 @@ rtr_cur_search_with_match( page = buf_block_get_frame(block); const ulint level = btr_page_get_level(page); - const bool is_leaf = !level; + const ulint n_core = level ? 0 : index->n_fields; if (mode == PAGE_CUR_RTREE_LOCATE) { ut_ad(level != 0); @@ -1738,7 +1741,7 @@ rtr_cur_search_with_match( ulint new_rec_size = rec_get_converted_size(index, tuple, 0); - offsets = rec_get_offsets(rec, index, offsets, is_leaf, + offsets = rec_get_offsets(rec, index, offsets, n_core, dtuple_get_n_fields_cmp(tuple), &heap); @@ -1759,7 +1762,7 @@ rtr_cur_search_with_match( } while (!page_rec_is_supremum(rec)) { - if (!is_leaf) { + if (!n_core) { switch (mode) { case PAGE_CUR_CONTAIN: case PAGE_CUR_INTERSECT: @@ -1840,7 +1843,7 @@ rtr_cur_search_with_match( to rtr_info->path for non-leaf nodes, or rtr_info->matches for leaf nodes */ if (rtr_info && mode != PAGE_CUR_RTREE_INSERT) { - if (!is_leaf) { + if (!n_core) { uint32_t page_no; node_seq_t new_seq; bool is_loc; @@ -1851,7 +1854,7 @@ rtr_cur_search_with_match( == PAGE_CUR_RTREE_GET_FATHER); offsets = rec_get_offsets( - rec, index, offsets, false, + rec, index, offsets, 0, ULINT_UNDEFINED, &heap); page_no = btr_node_ptr_get_child_page_no( @@ -1904,7 +1907,8 @@ rtr_cur_search_with_match( /* Collect matched records on page */ offsets = rec_get_offsets( - rec, index, offsets, true, + rec, index, offsets, + index->n_fields, ULINT_UNDEFINED, &heap); rtr_leaf_push_match_rec( rec, rtr_info, offsets, @@ -1927,7 +1931,7 @@ rtr_cur_search_with_match( /* All records on page are searched */ if (page_rec_is_supremum(rec)) { - if (!is_leaf) { + if (!n_core) { if (!found) { /* No match case, if it is for insertion, then we select the record that result in @@ -1936,7 +1940,7 @@ rtr_cur_search_with_match( ut_ad(least_inc < DBL_MAX); offsets = rec_get_offsets( best_rec, index, offsets, - false, ULINT_UNDEFINED, &heap); + 0, ULINT_UNDEFINED, &heap); uint32_t child_no = btr_node_ptr_get_child_page_no( best_rec, offsets); @@ -1988,11 +1992,11 @@ rtr_cur_search_with_match( /* Verify the record to be positioned is the same as the last record in matched_rec vector */ offsets2 = rec_get_offsets(test_rec.r_rec, index, - offsets2, true, + offsets2, index->n_fields, ULINT_UNDEFINED, &heap); offsets = rec_get_offsets(last_match_rec, index, - offsets, true, + offsets, index->n_fields, ULINT_UNDEFINED, &heap); ut_ad(cmp_rec_rec(test_rec.r_rec, last_match_rec, @@ -2012,7 +2016,7 @@ rtr_cur_search_with_match( mach_read_from_4(rec + DATA_MBR_LEN), block, rec, 0); - } else if (rtr_info && found && !is_leaf) { + } else if (rtr_info && found && !n_core) { rec = last_match_rec; } @@ -2022,11 +2026,11 @@ rtr_cur_search_with_match( #ifdef UNIV_DEBUG /* Verify that we are positioned at the same child page as pushed in the path stack */ - if (!is_leaf && (!page_rec_is_supremum(rec) || found) + if (!n_core && (!page_rec_is_supremum(rec) || found) && mode != PAGE_CUR_RTREE_INSERT) { ulint page_no; - offsets = rec_get_offsets(rec, index, offsets, false, + offsets = rec_get_offsets(rec, index, offsets, 0, ULINT_UNDEFINED, &heap); page_no = btr_node_ptr_get_child_page_no(rec, offsets); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 7c74d4f8340..454d74d1015 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -8277,26 +8277,24 @@ wsrep_calc_row_hash( dictionary */ row_prebuilt_t* prebuilt) /*!< in: InnoDB prebuilt struct */ { - ulint len; - const byte* ptr; - void *ctx = alloca(my_md5_context_size()); my_md5_init(ctx); for (uint i = 0; i < table->s->fields; i++) { byte null_byte=0; byte true_byte=1; + unsigned is_unsigned; const Field* field = table->field[i]; if (!field->stored_in_db()) { continue; } - ptr = (const byte*) row + get_field_offset(table, field); - len = field->pack_length(); - - switch (prebuilt->table->cols[i].mtype) { + auto ptr = row + get_field_offset(table, field); + ulint len = field->pack_length(); + switch (get_innobase_type_from_mysql_type(&is_unsigned, + field)) { case DATA_BLOB: ptr = row_mysql_read_blob_ref(&len, ptr, len); diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 44e45e19550..dfea7fcde8c 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -1022,13 +1022,6 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx @return whether the table will be rebuilt */ bool need_rebuild () const { return(old_table != new_table); } - /** Clear uncommmitted added indexes after a failed operation. */ - void clear_added_indexes() - { - for (ulint i= 0; i < num_to_add_index; i++) - add_index[i]->detach_columns(true); - } - /** Convert table-rebuilding ALTER to instant ALTER. */ void prepare_instant() { @@ -1126,6 +1119,42 @@ struct ha_innobase_inplace_ctx : public inplace_alter_handler_ctx } } + /** @return whether the given column is being added */ + bool is_new_vcol(const dict_v_col_t &v_col) const + { + for (ulint i= 0; i < num_to_add_vcol; i++) + if (&add_vcol[i] == &v_col) + return true; + return false; + } + + /** During rollback, make newly added indexes point to + newly added virtual columns. */ + void clean_new_vcol_index() + { + ut_ad(old_table == new_table); + const dict_index_t *index= dict_table_get_first_index(old_table); + while ((index= dict_table_get_next_index(index)) != NULL) + { + if (!index->has_virtual() || index->is_committed()) + continue; + ulint n_drop_new_vcol= index->get_new_n_vcol(); + for (ulint i= 0; n_drop_new_vcol && i < index->n_fields; i++) + { + dict_col_t *col= index->fields[i].col; + /* Skip the non-virtual and old virtual columns */ + if (!col->is_virtual()) + continue; + dict_v_col_t *vcol= reinterpret_cast<dict_v_col_t*>(col); + if (!is_new_vcol(*vcol)) + continue; + + index->fields[i].col= &index->new_vcol_info-> + add_drop_v_col(index->heap, vcol, --n_drop_new_vcol)->m_col; + } + } + } + private: // Disable copying ha_innobase_inplace_ctx(const ha_innobase_inplace_ctx&); @@ -3725,9 +3754,11 @@ innobase_fts_check_doc_id_index( for (index = dict_table_get_first_index(table); index; index = dict_table_get_next_index(index)) { + /* Check if there exists a unique index with the name of - FTS_DOC_ID_INDEX_NAME */ - if (innobase_strcasecmp(index->name, FTS_DOC_ID_INDEX_NAME)) { + FTS_DOC_ID_INDEX_NAME and ignore the corrupted index */ + if (index->type & DICT_CORRUPT + || innobase_strcasecmp(index->name, FTS_DOC_ID_INDEX_NAME)) { continue; } @@ -4035,7 +4066,7 @@ online_retry_drop_indexes_low( ut_ad(table->get_ref_count() >= 1); if (table->drop_aborted) { - row_merge_drop_indexes(trx, table, TRUE); + row_merge_drop_indexes(trx, table, true); } } @@ -5895,7 +5926,7 @@ add_all_virtual: offsets = rec_get_offsets( btr_pcur_get_rec(&pcur), index, offsets, - true, ULINT_UNDEFINED, &offsets_heap); + index->n_core_fields, ULINT_UNDEFINED, &offsets_heap); if (big_rec) { if (err == DB_SUCCESS) { err = btr_store_big_rec_extern_fields( @@ -6806,7 +6837,7 @@ new_table_failed: for (ulint a = 0; a < ctx->num_to_add_index; a++) { dict_index_t* index = ctx->add_index[a]; - const bool has_new_v_col = index->has_new_v_col; + const ulint n_v_col = index->get_new_n_vcol(); index = create_index_dict(ctx->trx, index, add_v); error = ctx->trx->error_state; if (error != DB_SUCCESS) { @@ -6836,7 +6867,9 @@ error_handling_drop_uncached_1: goto error_handling_drop_uncached_1; } index->parser = index_defs[a].parser; - index->has_new_v_col = has_new_v_col; + if (n_v_col) { + index->assign_new_v_col(n_v_col); + } /* Note the id of the transaction that created this index, we use it to restrict readers from accessing this index, to ensure read consistency. */ @@ -6907,7 +6940,7 @@ error_handling_drop_uncached_1: for (ulint a = 0; a < ctx->num_to_add_index; a++) { dict_index_t* index = ctx->add_index[a]; - const bool has_new_v_col = index->has_new_v_col; + const ulint n_v_col = index->get_new_n_vcol(); DBUG_EXECUTE_IF( "create_index_metadata_fail", if (a + 1 == ctx->num_to_add_index) { @@ -6939,7 +6972,9 @@ error_handling_drop_uncached: } index->parser = index_defs[a].parser; - index->has_new_v_col = has_new_v_col; + if (n_v_col) { + index->assign_new_v_col(n_v_col); + } /* Note the id of the transaction that created this index, we use it to restrict readers from accessing this index, to ensure read consistency. */ @@ -7168,7 +7203,7 @@ error_handled: online_retry_drop_indexes_with_trx(user_table, ctx->trx); } else { ut_ad(!ctx->need_rebuild()); - row_merge_drop_indexes(ctx->trx, user_table, TRUE); + row_merge_drop_indexes(ctx->trx, user_table, true); trx_commit_for_mysql(ctx->trx); } @@ -8531,7 +8566,6 @@ oom: that we hold at most a shared lock on the table. */ m_prebuilt->trx->error_info = NULL; ctx->trx->error_state = DB_SUCCESS; - ctx->clear_added_indexes(); DBUG_RETURN(true); } @@ -8623,17 +8657,18 @@ temparary index prefix @param table the TABLE @param locked TRUE=table locked, FALSE=may need to do a lazy drop @param trx the transaction -*/ -static MY_ATTRIBUTE((nonnull)) +@param alter_trx transaction which takes S-lock on the table + while creating the index */ +static void innobase_rollback_sec_index( -/*========================*/ - dict_table_t* user_table, - const TABLE* table, - ibool locked, - trx_t* trx) + dict_table_t* user_table, + const TABLE* table, + bool locked, + trx_t* trx, + const trx_t* alter_trx=NULL) { - row_merge_drop_indexes(trx, user_table, locked); + row_merge_drop_indexes(trx, user_table, locked, alter_trx); /* Free the table->fts only if there is no FTS_DOC_ID in the table */ @@ -8761,7 +8796,12 @@ rollback_inplace_alter_table( } innobase_rollback_sec_index( - prebuilt->table, table, FALSE, ctx->trx); + prebuilt->table, table, + (ha_alter_info->alter_info->requested_lock + == Alter_info::ALTER_TABLE_LOCK_EXCLUSIVE), + ctx->trx, prebuilt->trx); + + ctx->clean_new_vcol_index(); } trx_commit_for_mysql(ctx->trx); diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc index 31ed11cd7eb..a3d6ed26cda 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.cc +++ b/storage/innobase/ibuf/ibuf0ibuf.cc @@ -3775,7 +3775,7 @@ dump: row_ins_sec_index_entry_by_modify(BTR_MODIFY_LEAF). */ ut_ad(rec_get_deleted_flag(rec, page_is_comp(page))); - offsets = rec_get_offsets(rec, index, NULL, true, + offsets = rec_get_offsets(rec, index, NULL, index->n_fields, ULINT_UNDEFINED, &heap); update = row_upd_build_sec_rec_difference_binary( rec, index, offsets, entry, heap); @@ -3934,7 +3934,8 @@ ibuf_delete( ut_ad(ibuf_inside(mtr)); ut_ad(dtuple_check_typed(entry)); - ut_ad(!dict_index_is_spatial(index)); + ut_ad(!index->is_spatial()); + ut_ad(!index->is_clust()); low_match = page_cur_search(block, index, entry, &page_cur); @@ -3953,8 +3954,8 @@ ibuf_delete( rec_offs_init(offsets_); - offsets = rec_get_offsets( - rec, index, offsets, true, ULINT_UNDEFINED, &heap); + offsets = rec_get_offsets(rec, index, offsets, index->n_fields, + ULINT_UNDEFINED, &heap); if (page_get_n_recs(page) <= 1 || !(REC_INFO_DELETED_FLAG diff --git a/storage/innobase/include/btr0bulk.h b/storage/innobase/include/btr0bulk.h index 375b7b34fe4..943836f8759 100644 --- a/storage/innobase/include/btr0bulk.h +++ b/storage/innobase/include/btr0bulk.h @@ -314,6 +314,8 @@ public: /** Re-latch all latches */ void latch(); + table_name_t table_name() { return m_index->table->name; } + private: /** Insert a tuple to a page in a level @param[in] tuple tuple to insert diff --git a/storage/innobase/include/btr0pcur.h b/storage/innobase/include/btr0pcur.h index bc7afbf3b67..7facea7b80e 100644 --- a/storage/innobase/include/btr0pcur.h +++ b/storage/innobase/include/btr0pcur.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -497,8 +497,10 @@ struct btr_pcur_t{ /** if cursor position is stored, contains an initial segment of the latest record cursor was positioned either on, before or after */ rec_t* old_rec; + /** btr_cur.index->n_core_fields when old_rec was copied */ + uint16 old_n_core_fields; /** number of fields in old_rec */ - ulint old_n_fields; + uint16 old_n_fields; /** BTR_PCUR_ON, BTR_PCUR_BEFORE, or BTR_PCUR_AFTER, depending on whether cursor was on, before, or after the old_rec record */ enum btr_pcur_pos_t rel_pos; diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 1ad2517c8fb..c96ea8806df 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -2,7 +2,7 @@ Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2020, MariaDB Corporation. +Copyright (c) 2013, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -790,6 +790,35 @@ struct dict_v_col_t{ } }; +/** Data structure for newly added virtual column in a index. +It is used only during rollback_inplace_alter_table() of +addition of index depending on newly added virtual columns +and uses index heap. Should be freed when index is being +removed from cache. */ +struct dict_add_v_col_info +{ + ulint n_v_col; + dict_v_col_t *v_col; + + /** Add the newly added virtual column while rollbacking + the index which contains new virtual columns + @param col virtual column to be duplicated + @param offset offset where to duplicate virtual column */ + dict_v_col_t* add_drop_v_col(mem_heap_t *heap, dict_v_col_t *col, + ulint offset) + { + ut_ad(n_v_col); + ut_ad(offset < n_v_col); + if (!v_col) + v_col= static_cast<dict_v_col_t*> + (mem_heap_alloc(heap, n_v_col * sizeof *v_col)); + new (&v_col[offset]) dict_v_col_t(); + v_col[offset].m_col= col->m_col; + v_col[offset].v_pos= col->v_pos; + return &v_col[offset]; + } +}; + /** Data structure for newly added virtual column in a table */ struct dict_add_v_col_t{ /** number of new virtual column */ @@ -1037,9 +1066,12 @@ struct dict_index_t { dict_field_t* fields; /*!< array of field descriptions */ st_mysql_ftparser* parser; /*!< fulltext parser plugin */ - bool has_new_v_col; - /*!< whether it has a newly added virtual - column in ALTER */ + + /** It just indicates whether newly added virtual column + during alter. It stores column in case of alter failure. + It should use heap from dict_index_t. It should be freed + while removing the index from table. */ + dict_add_v_col_info* new_vcol_info; UT_LIST_NODE_T(dict_index_t) indexes;/*!< list of indexes of the table */ #ifdef BTR_CUR_ADAPT @@ -1199,9 +1231,8 @@ public: /** @return whether the index is corrupted */ inline bool is_corrupted() const; - /** Detach the virtual columns from the index that is to be removed. - @param whether to reset fields[].col */ - void detach_columns(bool clear= false) + /** Detach the virtual columns from the index that is to be removed. */ + void detach_columns() { if (!has_virtual() || !cached) return; @@ -1211,8 +1242,6 @@ public: if (!col || !col->is_virtual()) continue; col->detach(*this); - if (clear) - fields[i].col= nullptr; } } @@ -1275,6 +1304,23 @@ public: bool vers_history_row(const rec_t* rec, bool &history_row); + /** Assign the number of new column to be added as a part + of the index + @param n_vcol number of virtual columns to be added */ + void assign_new_v_col(ulint n_vcol) + { + new_vcol_info= static_cast<dict_add_v_col_info*> + (mem_heap_zalloc(heap, sizeof *new_vcol_info)); + new_vcol_info->n_v_col= n_vcol; + } + + /* @return whether index has new virtual column */ + bool has_new_v_col() const { return new_vcol_info; } + + /* @return number of newly added virtual column */ + ulint get_new_n_vcol() const + { return new_vcol_info ? new_vcol_info->n_v_col : 0; } + /** Reconstruct the clustered index fields. */ inline void reconstruct_fields(); @@ -2316,6 +2362,17 @@ public: /** mysql_row_templ_t for base columns used for compute the virtual columns */ dict_vcol_templ_t* vc_templ; + + /* @return whether the table has any other transcation lock + other than the given transaction */ + bool has_lock_other_than(const trx_t *trx) const + { + for (lock_t *lock= UT_LIST_GET_FIRST(locks); lock; + lock= UT_LIST_GET_NEXT(un_member.tab_lock.locks, lock)) + if (lock->trx != trx) + return true; + return false; + } }; inline void dict_index_t::set_modified(mtr_t& mtr) const diff --git a/storage/innobase/include/gis0rtree.ic b/storage/innobase/include/gis0rtree.ic index 82747bdc95a..1b53caa306b 100644 --- a/storage/innobase/include/gis0rtree.ic +++ b/storage/innobase/include/gis0rtree.ic @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2014, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -57,7 +57,8 @@ rtr_page_cal_mbr( page = buf_block_get_frame(block); rec = page_rec_get_next(page_get_infimum_rec(page)); - offsets = rec_get_offsets(rec, index, offsets, page_is_leaf(page), + offsets = rec_get_offsets(rec, index, offsets, page_is_leaf(page) + ? index->n_fields : 0, ULINT_UNDEFINED, &heap); do { diff --git a/storage/innobase/include/page0cur.ic b/storage/innobase/include/page0cur.ic index e8f7afcaf01..828be6840d2 100644 --- a/storage/innobase/include/page0cur.ic +++ b/storage/innobase/include/page0cur.ic @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1994, 2014, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, 2020, MariaDB Corporation. +Copyright (c) 2015, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -273,7 +273,8 @@ page_cur_tuple_insert( index, tuple, n_ext); *offsets = rec_get_offsets(rec, index, *offsets, - page_is_leaf(cursor->block->frame), + page_is_leaf(cursor->block->frame) + ? index->n_core_fields : 0, ULINT_UNDEFINED, heap); ut_ad(size == rec_offs_size(*offsets)); diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h index cda0d38ba44..dbcff3e6fd6 100644 --- a/storage/innobase/include/rem0rec.h +++ b/storage/innobase/include/rem0rec.h @@ -466,7 +466,7 @@ rec_get_n_extern_new( @param[in] index the index that the record belongs to @param[in,out] offsets array comprising offsets[0] allocated elements, or an array from rec_get_offsets(), or NULL -@param[in] leaf whether this is a leaf-page record +@param[in] n_core 0, or index->n_core_fields for leaf page @param[in] n_fields maximum number of offsets to compute (ULINT_UNDEFINED to compute all offsets) @param[in,out] heap memory heap @@ -476,7 +476,7 @@ rec_get_offsets_func( const rec_t* rec, const dict_index_t* index, rec_offs* offsets, - bool leaf, + ulint n_core, ulint n_fields, #ifdef UNIV_DEBUG const char* file, /*!< in: file name where called */ @@ -1082,7 +1082,9 @@ rec_get_converted_size( The fields are copied into the memory heap. @param[out] tuple data tuple @param[in] rec index record, or a copy thereof -@param[in] is_leaf whether rec is a leaf page record +@param[in] index index of rec +@param[in] n_core index->n_core_fields at the time rec was + copied, or 0 if non-leaf page record @param[in] n_fields number of fields to copy @param[in,out] heap memory heap */ void @@ -1090,7 +1092,7 @@ rec_copy_prefix_to_dtuple( dtuple_t* tuple, const rec_t* rec, const dict_index_t* index, - bool is_leaf, + ulint n_core, ulint n_fields, mem_heap_t* heap) MY_ATTRIBUTE((nonnull)); diff --git a/storage/innobase/include/row0merge.h b/storage/innobase/include/row0merge.h index d9410298c01..1d7f9bb145b 100644 --- a/storage/innobase/include/row0merge.h +++ b/storage/innobase/include/row0merge.h @@ -167,18 +167,20 @@ row_merge_drop_indexes_dict( table_id_t table_id)/*!< in: table identifier */ MY_ATTRIBUTE((nonnull)); -/*********************************************************************//** -Drop those indexes which were created before an error occurred. +/** Drop indexes that were created before an error occurred. The data dictionary must have been locked exclusively by the caller, -because the transaction will not be committed. */ +because the transaction will not be committed. +@param trx dictionary transaction +@param table table containing the indexes +@param locked True if table is locked, + false - may need to do lazy drop +@param alter_trx Alter table transaction */ void row_merge_drop_indexes( -/*===================*/ - trx_t* trx, /*!< in/out: transaction */ - dict_table_t* table, /*!< in/out: table containing the indexes */ - ibool locked) /*!< in: TRUE=table locked, - FALSE=may need to do a lazy drop */ - MY_ATTRIBUTE((nonnull)); + trx_t* trx, + dict_table_t* table, + bool locked, + const trx_t* alter_trx=NULL); /*********************************************************************//** Drop all partially created indexes during crash recovery. */ diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 00da7d5fe82..43e5249a349 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -4368,7 +4368,8 @@ static void lock_rec_print(FILE* file, const lock_t* lock, mtr_t& mtr) ut_ad(!page_rec_is_metadata(rec)); offsets = rec_get_offsets( - rec, lock->index, offsets, true, + rec, lock->index, offsets, + lock->index->n_core_fields, ULINT_UNDEFINED, &heap); putc(' ', file); @@ -4895,8 +4896,8 @@ loop: ut_ad(!lock_rec_get_nth_bit(lock, i) || page_rec_is_leaf(rec)); offsets = rec_get_offsets(rec, lock->index, offsets, - true, ULINT_UNDEFINED, - &heap); + lock->index->n_core_fields, + ULINT_UNDEFINED, &heap); /* If this thread is holding the file space latch (fil_space_t::latch), the following @@ -5207,7 +5208,8 @@ lock_rec_insert_check_and_lock( const rec_offs* offsets; rec_offs_init(offsets_); - offsets = rec_get_offsets(next_rec, index, offsets_, true, + offsets = rec_get_offsets(next_rec, index, offsets_, + index->n_core_fields, ULINT_UNDEFINED, &heap); ut_ad(lock_rec_queue_validate( @@ -5545,7 +5547,8 @@ lock_sec_rec_modify_check_and_lock( const rec_offs* offsets; rec_offs_init(offsets_); - offsets = rec_get_offsets(rec, index, offsets_, true, + offsets = rec_get_offsets(rec, index, offsets_, + index->n_core_fields, ULINT_UNDEFINED, &heap); ut_ad(lock_rec_queue_validate( @@ -5757,7 +5760,7 @@ lock_clust_rec_read_check_and_lock_alt( rec_offs_init(offsets_); ut_ad(page_rec_is_leaf(rec)); - offsets = rec_get_offsets(rec, index, offsets, true, + offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields, ULINT_UNDEFINED, &tmp_heap); err = lock_clust_rec_read_check_and_lock(flags, block, rec, index, offsets, mode, gap_mode, thr); diff --git a/storage/innobase/page/page0cur.cc b/storage/innobase/page/page0cur.cc index 5e751010f44..025d4b9b967 100644 --- a/storage/innobase/page/page0cur.cc +++ b/storage/innobase/page/page0cur.cc @@ -75,7 +75,7 @@ page_cur_try_search_shortcut( ut_ad(page_is_leaf(page)); rec = page_header_get_ptr(page, PAGE_LAST_INSERT); - offsets = rec_get_offsets(rec, index, offsets, true, + offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields, dtuple_get_n_fields(tuple), &heap); ut_ad(rec); @@ -90,7 +90,8 @@ page_cur_try_search_shortcut( next_rec = page_rec_get_next_const(rec); if (!page_rec_is_supremum(next_rec)) { - offsets = rec_get_offsets(next_rec, index, offsets, true, + offsets = rec_get_offsets(next_rec, index, offsets, + index->n_core_fields, dtuple_get_n_fields(tuple), &heap); if (cmp_dtuple_rec_with_match(tuple, next_rec, offsets, @@ -159,7 +160,7 @@ page_cur_try_search_shortcut_bytes( ut_ad(page_is_leaf(page)); rec = page_header_get_ptr(page, PAGE_LAST_INSERT); - offsets = rec_get_offsets(rec, index, offsets, true, + offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields, dtuple_get_n_fields(tuple), &heap); ut_ad(rec); @@ -180,7 +181,8 @@ page_cur_try_search_shortcut_bytes( next_rec = page_rec_get_next_const(rec); if (!page_rec_is_supremum(next_rec)) { - offsets = rec_get_offsets(next_rec, index, offsets, true, + offsets = rec_get_offsets(next_rec, index, offsets, + index->n_core_fields, dtuple_get_n_fields(tuple), &heap); if (cmp_dtuple_rec_with_match_bytes( @@ -321,14 +323,14 @@ page_cur_search_with_match( #endif /* UNIV_ZIP_DEBUG */ ut_d(page_check_dir(page)); - const bool is_leaf = page_is_leaf(page); + const ulint n_core = page_is_leaf(page) ? index->n_core_fields : 0; #ifdef BTR_CUR_HASH_ADAPT - if (is_leaf + if (n_core && page_get_direction(page) == PAGE_RIGHT && page_header_get_offs(page, PAGE_LAST_INSERT) && mode == PAGE_CUR_LE - && !dict_index_is_spatial(index) + && !index->is_spatial() && page_header_get_field(page, PAGE_N_DIRECTION) > 3 && page_cur_try_search_shortcut( block, index, tuple, @@ -344,10 +346,10 @@ page_cur_search_with_match( /* If the mode is for R-tree indexes, use the special MBR related compare functions */ - if (dict_index_is_spatial(index) && mode > PAGE_CUR_LE) { + if (index->is_spatial() && mode > PAGE_CUR_LE) { /* For leaf level insert, we still use the traditional compare function for now */ - if (mode == PAGE_CUR_RTREE_INSERT && is_leaf) { + if (mode == PAGE_CUR_RTREE_INSERT && n_core) { mode = PAGE_CUR_LE; } else { rtr_cur_search_with_match( @@ -392,7 +394,7 @@ page_cur_search_with_match( offsets = offsets_; offsets = rec_get_offsets( - mid_rec, index, offsets, is_leaf, + mid_rec, index, offsets, n_core, dtuple_get_n_fields_cmp(tuple), &heap); cmp = cmp_dtuple_rec_with_match( @@ -446,7 +448,7 @@ up_slot_match: offsets = offsets_; offsets = rec_get_offsets( - mid_rec, index, offsets, is_leaf, + mid_rec, index, offsets, n_core, dtuple_get_n_fields_cmp(tuple), &heap); cmp = cmp_dtuple_rec_with_match( @@ -627,7 +629,7 @@ page_cur_search_with_match_bytes( /* Perform binary search until the lower and upper limit directory slots come to the distance 1 of each other */ - const bool is_leaf = page_is_leaf(page); + const ulint n_core = page_is_leaf(page) ? index->n_core_fields : 0; while (up - low > 1) { mid = (low + up) / 2; @@ -639,7 +641,7 @@ page_cur_search_with_match_bytes( up_matched_fields, up_matched_bytes); offsets = rec_get_offsets( - mid_rec, index, offsets_, is_leaf, + mid_rec, index, offsets_, n_core, dtuple_get_n_fields_cmp(tuple), &heap); cmp = cmp_dtuple_rec_with_match_bytes( @@ -707,7 +709,7 @@ up_slot_match: } offsets = rec_get_offsets( - mid_rec, index, offsets_, is_leaf, + mid_rec, index, offsets_, n_core, dtuple_get_n_fields_cmp(tuple), &heap); cmp = cmp_dtuple_rec_with_match_bytes( @@ -1343,7 +1345,8 @@ page_cur_insert_rec_low( rec_offs_init(foffsets_); rec_offs *foffsets= rec_get_offsets(free_rec, index, foffsets_, - page_is_leaf(block->frame), + page_is_leaf(block->frame) + ? index->n_core_fields : 0, ULINT_UNDEFINED, &heap); const ulint fextra_size= rec_offs_extra_size(foffsets); insert_buf= free_rec - fextra_size; @@ -1838,7 +1841,8 @@ page_cur_insert_rec_zip( rec_offs *foffsets= rec_get_offsets(cursor->block->frame + free_rec, index, foffsets_, - page_is_leaf(cursor->block->frame), + page_is_leaf(cursor->block->frame) + ? index->n_core_fields : 0, ULINT_UNDEFINED, &heap); insert_buf= cursor->block->frame + free_rec - rec_offs_extra_size(foffsets); diff --git a/storage/innobase/page/page0page.cc b/storage/innobase/page/page0page.cc index 5fe029d5b4d..9b83470e65c 100644 --- a/storage/innobase/page/page0page.cc +++ b/storage/innobase/page/page0page.cc @@ -2,7 +2,7 @@ Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -482,7 +482,8 @@ page_copy_rec_list_end_no_locks( ut_a(page_is_comp(new_page) == page_rec_is_comp(rec)); ut_a(mach_read_from_2(new_page + srv_page_size - 10) == (ulint) (page_is_comp(new_page) ? PAGE_NEW_INFIMUM : PAGE_OLD_INFIMUM)); - const bool is_leaf = page_is_leaf(block->frame); + const ulint n_core = page_is_leaf(block->frame) + ? index->n_core_fields : 0; page_cur_set_before_first(new_block, &cur2); @@ -490,7 +491,7 @@ page_copy_rec_list_end_no_locks( while (!page_cur_is_after_last(&cur1)) { rec_t* ins_rec; - offsets = rec_get_offsets(cur1.rec, index, offsets, is_leaf, + offsets = rec_get_offsets(cur1.rec, index, offsets, n_core, ULINT_UNDEFINED, &heap); ins_rec = page_cur_insert_rec_low(&cur2, index, cur1.rec, offsets, mtr); @@ -721,7 +722,7 @@ page_copy_rec_list_start( page_cur_position(ret, new_block, &cur2); - const bool is_leaf = page_rec_is_leaf(rec); + const ulint n_core = page_rec_is_leaf(rec) ? index->n_core_fields : 0; /* Copy records from the original page to the new page */ if (index->is_spatial()) { @@ -743,7 +744,7 @@ page_copy_rec_list_start( } else { while (page_cur_get_rec(&cur1) != rec) { offsets = rec_get_offsets(cur1.rec, index, offsets, - is_leaf, + n_core, ULINT_UNDEFINED, &heap); cur2.rec = page_cur_insert_rec_low(&cur2, index, cur1.rec, offsets, @@ -764,7 +765,7 @@ page_copy_rec_list_start( same temp-table in parallel. max_trx_id is ignored for temp tables because it not required for MVCC. */ - if (is_leaf && dict_index_is_sec_or_ibuf(index) + if (n_core && dict_index_is_sec_or_ibuf(index) && !index->table->is_temporary()) { page_update_max_trx_id(new_block, new_page_zip, @@ -884,10 +885,10 @@ page_delete_rec_list_end( } #endif - /* The page gets invalid for optimistic searches */ + /* The page becomes invalid for optimistic searches */ buf_block_modify_clock_inc(block); - const bool is_leaf= page_is_leaf(block->frame); + const ulint n_core= page_is_leaf(block->frame) ? index->n_core_fields : 0; mem_heap_t *heap= nullptr; rec_offs offsets_[REC_OFFS_NORMAL_SIZE]; rec_offs *offsets= offsets_; @@ -901,7 +902,7 @@ page_delete_rec_list_end( { page_cur_t cur; page_cur_position(rec, block, &cur); - offsets= rec_get_offsets(rec, index, offsets, is_leaf, + offsets= rec_get_offsets(rec, index, offsets, n_core, ULINT_UNDEFINED, &heap); rec= rec_get_next_ptr(rec, TRUE); #ifdef UNIV_ZIP_DEBUG @@ -932,7 +933,7 @@ page_delete_rec_list_end( do { - offsets = rec_get_offsets(rec2, index, offsets, is_leaf, + offsets = rec_get_offsets(rec2, index, offsets, n_core, ULINT_UNDEFINED, &heap); ulint s= rec_offs_size(offsets); ut_ad(ulint(rec2 - block->frame) + s - rec_offs_extra_size(offsets) < @@ -1097,11 +1098,12 @@ page_delete_rec_list_start( page_cur_set_before_first(block, &cur1); page_cur_move_to_next(&cur1); - const bool is_leaf = page_rec_is_leaf(rec); + const ulint n_core = page_rec_is_leaf(rec) + ? index->n_core_fields : 0; while (page_cur_get_rec(&cur1) != rec) { offsets = rec_get_offsets(page_cur_get_rec(&cur1), index, - offsets, is_leaf, + offsets, n_core, ULINT_UNDEFINED, &heap); page_cur_delete_rec(&cur1, index, offsets, mtr); } @@ -2104,9 +2106,10 @@ wrong_page_type: rec = page_get_infimum_rec(page); + const ulint n_core = page_is_leaf(page) ? index->n_core_fields : 0; + for (;;) { - offsets = rec_get_offsets(rec, index, offsets, - page_is_leaf(page), + offsets = rec_get_offsets(rec, index, offsets, n_core, ULINT_UNDEFINED, &heap); if (page_is_comp(page) && page_rec_is_user_rec(rec) @@ -2352,8 +2355,7 @@ n_owned_zero: rec = page_header_get_ptr(page, PAGE_FREE); while (rec != NULL) { - offsets = rec_get_offsets(rec, index, offsets, - page_is_leaf(page), + offsets = rec_get_offsets(rec, index, offsets, n_core, ULINT_UNDEFINED, &heap); if (UNIV_UNLIKELY(!page_rec_validate(rec, offsets))) { ret = FALSE; diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc index 2c8b0cf5136..1ed9efafc69 100644 --- a/storage/innobase/page/page0zip.cc +++ b/storage/innobase/page/page0zip.cc @@ -2,7 +2,7 @@ Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2014, 2020, MariaDB Corporation. +Copyright (c) 2014, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -903,7 +903,7 @@ page_zip_compress_node_ptrs( do { const rec_t* rec = *recs++; - offsets = rec_get_offsets(rec, index, offsets, false, + offsets = rec_get_offsets(rec, index, offsets, 0, ULINT_UNDEFINED, &heap); /* Only leaf nodes may contain externally stored columns. */ ut_ad(!rec_offs_any_extern(offsets)); @@ -1152,7 +1152,7 @@ page_zip_compress_clust( do { const rec_t* rec = *recs++; - offsets = rec_get_offsets(rec, index, offsets, true, + offsets = rec_get_offsets(rec, index, offsets, index->n_fields, ULINT_UNDEFINED, &heap); ut_ad(rec_offs_n_fields(offsets) == dict_index_get_n_fields(index)); @@ -2027,7 +2027,7 @@ page_zip_apply_log( sorted by address (indexed by heap_no - PAGE_HEAP_NO_USER_LOW) */ ulint n_dense,/*!< in: size of recs[] */ - bool is_leaf,/*!< in: whether this is a leaf page */ + ulint n_core, /*!< in: index->n_fields, or 0 for non-leaf */ ulint trx_id_col,/*!< in: column number of trx_id in the index, or ULINT_UNDEFINED if none */ ulint heap_status, @@ -2103,7 +2103,7 @@ page_zip_apply_log( /* Clear the data bytes of the record. */ mem_heap_t* heap = NULL; rec_offs* offs; - offs = rec_get_offsets(rec, index, offsets, is_leaf, + offs = rec_get_offsets(rec, index, offsets, n_core, ULINT_UNDEFINED, &heap); memset(rec, 0, rec_offs_data_size(offs)); @@ -2121,7 +2121,7 @@ page_zip_apply_log( This will be overwritten in page_zip_set_extra_bytes(), called by page_zip_decompress_low(). */ ut_d(rec[-REC_NEW_INFO_BITS] = 0); - rec_offs_make_valid(rec, index, is_leaf, offsets); + rec_offs_make_valid(rec, index, n_core != 0, offsets); /* Copy the extra bytes (backwards). */ { @@ -2301,7 +2301,7 @@ page_zip_decompress_node_ptrs( } /* Read the offsets. The status bits are needed here. */ - offsets = rec_get_offsets(rec, index, offsets, false, + offsets = rec_get_offsets(rec, index, offsets, 0, ULINT_UNDEFINED, &heap); /* Non-leaf nodes should not have any externally @@ -2388,7 +2388,7 @@ zlib_done: const byte* mod_log_ptr; mod_log_ptr = page_zip_apply_log(d_stream->next_in, d_stream->avail_in + 1, - recs, n_dense, false, + recs, n_dense, 0, ULINT_UNDEFINED, heap_status, index, offsets); @@ -2419,7 +2419,7 @@ zlib_done: for (slot = 0; slot < n_dense; slot++) { rec_t* rec = recs[slot]; - offsets = rec_get_offsets(rec, index, offsets, false, + offsets = rec_get_offsets(rec, index, offsets, 0, ULINT_UNDEFINED, &heap); /* Non-leaf nodes should not have any externally stored columns. */ @@ -2541,7 +2541,8 @@ zlib_done: const byte* mod_log_ptr; mod_log_ptr = page_zip_apply_log(d_stream->next_in, d_stream->avail_in + 1, - recs, n_dense, true, + recs, n_dense, + index->n_fields, ULINT_UNDEFINED, heap_status, index, offsets); @@ -2744,7 +2745,7 @@ page_zip_decompress_clust( } /* Read the offsets. The status bits are needed here. */ - offsets = rec_get_offsets(rec, index, offsets, true, + offsets = rec_get_offsets(rec, index, offsets, index->n_fields, ULINT_UNDEFINED, &heap); /* This is a leaf page in a clustered index. */ @@ -2871,7 +2872,8 @@ zlib_done: const byte* mod_log_ptr; mod_log_ptr = page_zip_apply_log(d_stream->next_in, d_stream->avail_in + 1, - recs, n_dense, true, + recs, n_dense, + index->n_fields, trx_id_col, heap_status, index, offsets); @@ -2907,7 +2909,7 @@ zlib_done: rec_t* rec = recs[slot]; bool exists = !page_zip_dir_find_free( page_zip, page_offset(rec)); - offsets = rec_get_offsets(rec, index, offsets, true, + offsets = rec_get_offsets(rec, index, offsets, index->n_fields, ULINT_UNDEFINED, &heap); dst = rec_get_nth_field(rec, offsets, @@ -3430,7 +3432,7 @@ page_zip_validate_low( page + PAGE_NEW_INFIMUM, TRUE); trec = page_rec_get_next_low( temp_page + PAGE_NEW_INFIMUM, TRUE); - const bool is_leaf = page_is_leaf(page); + const ulint n_core = page_is_leaf(page) ? index->n_fields : 0; do { if (page_offset(rec) != page_offset(trec)) { @@ -3445,7 +3447,7 @@ page_zip_validate_low( if (index) { /* Compare the data. */ offsets = rec_get_offsets( - rec, index, offsets, is_leaf, + rec, index, offsets, n_core, ULINT_UNDEFINED, &heap); if (memcmp(rec - rec_offs_extra_size(offsets), diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc index aae621b6f56..419727b4d37 100644 --- a/storage/innobase/rem/rem0rec.cc +++ b/storage/innobase/rem/rem0rec.cc @@ -273,9 +273,9 @@ rec_init_offsets_comp_ordinary( ulint n_fields = n_core; ulint null_mask = 1; - ut_ad(index->n_core_fields >= n_core); ut_ad(n_core > 0); - ut_ad(index->n_fields >= n_core); + ut_ad(index->n_core_fields >= n_core); + ut_ad(index->n_fields >= index->n_core_fields); ut_ad(index->n_core_null_bytes <= UT_BITS_IN_BYTES(index->n_nullable)); ut_ad(format == REC_LEAF_TEMP || format == REC_LEAF_TEMP_INSTANT || dict_table_is_comp(index->table)); @@ -283,6 +283,11 @@ rec_init_offsets_comp_ordinary( || index->n_fields == rec_offs_n_fields(offsets)); ut_d(ulint n_null= 0); + const unsigned n_core_null_bytes = UNIV_UNLIKELY(index->n_core_fields + != n_core) + ? UT_BITS_IN_BYTES(unsigned(index->get_n_nullable(n_core))) + : index->n_core_null_bytes; + if (mblob) { ut_ad(index->table->instant); ut_ad(index->is_instant()); @@ -297,7 +302,7 @@ rec_init_offsets_comp_ordinary( const ulint n_null_bytes = UT_BITS_IN_BYTES(n_nullable); ut_d(n_null = n_nullable); ut_ad(n_null <= index->n_nullable); - ut_ad(n_null_bytes >= index->n_core_null_bytes + ut_ad(n_null_bytes >= n_core_null_bytes || n_core < index->n_core_fields); lens = --nulls - n_null_bytes; goto start; @@ -314,10 +319,10 @@ rec_init_offsets_comp_ordinary( case REC_LEAF_ORDINARY: nulls -= REC_N_NEW_EXTRA_BYTES; ordinary: - lens = --nulls - index->n_core_null_bytes; + lens = --nulls - n_core_null_bytes; - ut_d(n_null = std::min<uint>(index->n_core_null_bytes * 8U, - index->n_nullable)); + ut_d(n_null = std::min(n_core_null_bytes * 8U, + index->n_nullable)); break; case REC_LEAF_INSTANT: nulls -= REC_N_NEW_EXTRA_BYTES; @@ -330,7 +335,7 @@ ordinary: const ulint n_null_bytes = UT_BITS_IN_BYTES(n_nullable); ut_d(n_null = n_nullable); ut_ad(n_null <= index->n_nullable); - ut_ad(n_null_bytes >= index->n_core_null_bytes + ut_ad(n_null_bytes >= n_core_null_bytes || n_core < index->n_core_fields); lens = --nulls - n_null_bytes; } @@ -588,14 +593,14 @@ is (SQL_NULL), the field i is NULL. When the type of the offset at [i+1] is (STORED_OFFPAGE), the field i is stored externally. @param[in] rec record @param[in] index the index that the record belongs in -@param[in] leaf whether the record resides in a leaf page +@param[in] n_core 0, or index->n_core_fields for leaf page @param[in,out] offsets array of offsets, with valid rec_offs_n_fields() */ static void rec_init_offsets( const rec_t* rec, const dict_index_t* index, - bool leaf, + ulint n_core, rec_offs* offsets) { ulint i = 0; @@ -610,6 +615,8 @@ rec_init_offsets( || index->in_instant_init); ut_d(memcpy(&offsets[RECORD_OFFSET], &rec, sizeof(rec))); ut_d(memcpy(&offsets[INDEX_OFFSET], &index, sizeof(index))); + ut_ad(index->n_fields >= n_core); + ut_ad(index->n_core_fields >= n_core); if (dict_table_is_comp(index->table)) { const byte* nulls; @@ -628,23 +635,21 @@ rec_init_offsets( rec_offs_base(offsets)[1] = 8; return; case REC_STATUS_NODE_PTR: - ut_ad(!leaf); + ut_ad(!n_core); n_node_ptr_field = dict_index_get_n_unique_in_tree_nonleaf( index); break; case REC_STATUS_INSTANT: - ut_ad(leaf); ut_ad(index->is_instant()); rec_init_offsets_comp_ordinary(rec, index, offsets, - index->n_core_fields, + n_core, NULL, REC_LEAF_INSTANT); return; case REC_STATUS_ORDINARY: - ut_ad(leaf); rec_init_offsets_comp_ordinary(rec, index, offsets, - index->n_core_fields, + n_core, NULL, REC_LEAF_ORDINARY); return; @@ -806,7 +811,7 @@ resolved: @param[in] index the index that the record belongs to @param[in,out] offsets array comprising offsets[0] allocated elements, or an array from rec_get_offsets(), or NULL -@param[in] leaf whether this is a leaf-page record +@param[in] n_core 0, or index->n_core_fields for leaf page @param[in] n_fields maximum number of offsets to compute (ULINT_UNDEFINED to compute all offsets) @param[in,out] heap memory heap @@ -816,7 +821,7 @@ rec_get_offsets_func( const rec_t* rec, const dict_index_t* index, rec_offs* offsets, - bool leaf, + ulint n_core, ulint n_fields, #ifdef UNIV_DEBUG const char* file, /*!< in: file name where called */ @@ -828,6 +833,15 @@ rec_get_offsets_func( ulint size; bool alter_metadata = false; + ut_ad(index->n_core_fields >= n_core); + /* This assertion was relaxed for the btr_cur_open_at_index_side() + call in btr_cur_instant_init_low(). We cannot invoke + index->is_instant(), because the same assertion would fail there + until btr_cur_instant_init_low() has invoked + dict_table_t::deserialise_columns(). */ + ut_ad(index->n_fields >= index->n_core_fields + || index->in_instant_init); + if (dict_table_is_comp(index->table)) { switch (UNIV_EXPECT(rec_get_status(rec), REC_STATUS_ORDINARY)) { @@ -835,14 +849,14 @@ rec_get_offsets_func( alter_metadata = rec_is_alter_metadata(rec, true); /* fall through */ case REC_STATUS_ORDINARY: - ut_ad(leaf); + ut_ad(n_core); n = dict_index_get_n_fields(index) + alter_metadata; break; case REC_STATUS_NODE_PTR: /* Node pointer records consist of the uniquely identifying fields of the record followed by a child page number field. */ - ut_ad(!leaf); + ut_ad(!n_core); n = dict_index_get_n_unique_in_tree_nonleaf(index) + 1; break; case REC_STATUS_INFIMUM: @@ -871,19 +885,19 @@ rec_get_offsets_func( >= PAGE_HEAP_NO_USER_LOW; /* The infimum and supremum records carry 1 field. */ ut_ad(is_user_rec || n == 1); - ut_ad(!is_user_rec || leaf || index->is_dummy + ut_ad(!is_user_rec || n_core || index->is_dummy || dict_index_is_ibuf(index) || n == n_fields /* dict_stats_analyze_index_level() */ || n - 1 == dict_index_get_n_unique_in_tree_nonleaf(index)); - ut_ad(!is_user_rec || !leaf || index->is_dummy + ut_ad(!is_user_rec || !n_core || index->is_dummy || dict_index_is_ibuf(index) || n == n_fields /* btr_pcur_restore_position() */ || (n + (index->id == DICT_INDEXES_ID) - >= index->n_core_fields && n <= index->n_fields + >= n_core && n <= index->n_fields + unsigned(rec_is_alter_metadata(rec, false)))); - if (is_user_rec && leaf && n < index->n_fields) { + if (is_user_rec && n_core && n < index->n_fields) { ut_ad(!index->is_dummy); ut_ad(!dict_index_is_ibuf(index)); n = index->n_fields; @@ -917,17 +931,17 @@ rec_get_offsets_func( memcpy(&offsets[RECORD_OFFSET], &rec, sizeof rec); memcpy(&offsets[INDEX_OFFSET], &index, sizeof index); #endif /* UNIV_DEBUG */ - ut_ad(leaf); + ut_ad(n_core); ut_ad(index->table->instant); ut_ad(index->is_instant()); ut_ad(rec_offs_n_fields(offsets) <= ulint(index->n_fields) + 1); rec_init_offsets_comp_ordinary<true>(rec, index, offsets, index->n_core_fields, - NULL, + nullptr, REC_LEAF_INSTANT); } else { - rec_init_offsets(rec, index, leaf, offsets); + rec_init_offsets(rec, index, n_core, offsets); } return offsets; } @@ -1850,7 +1864,9 @@ template void rec_convert_dtuple_to_temp<true>( The fields are copied into the memory heap. @param[out] tuple data tuple @param[in] rec index record, or a copy thereof -@param[in] is_leaf whether rec is a leaf page record +@param[in] index index of rec +@param[in] n_core index->n_core_fields at the time rec was + copied, or 0 if non-leaf page record @param[in] n_fields number of fields to copy @param[in,out] heap memory heap */ void @@ -1858,7 +1874,7 @@ rec_copy_prefix_to_dtuple( dtuple_t* tuple, const rec_t* rec, const dict_index_t* index, - bool is_leaf, + ulint n_core, ulint n_fields, mem_heap_t* heap) { @@ -1866,10 +1882,11 @@ rec_copy_prefix_to_dtuple( rec_offs* offsets = offsets_; rec_offs_init(offsets_); - ut_ad(is_leaf || n_fields - 1 + ut_ad(n_core <= index->n_core_fields); + ut_ad(n_core || n_fields - 1 <= dict_index_get_n_unique_in_tree_nonleaf(index)); - offsets = rec_get_offsets(rec, index, offsets, is_leaf, + offsets = rec_get_offsets(rec, index, offsets, n_core, n_fields, &heap); ut_ad(rec_validate(rec, offsets)); @@ -2509,7 +2526,8 @@ rec_print( rec_print_new(file, rec, rec_get_offsets(rec, index, offsets_, - page_rec_is_leaf(rec), + page_rec_is_leaf(rec) + ? index->n_core_fields : 0, ULINT_UNDEFINED, &heap)); if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); @@ -2585,7 +2603,8 @@ operator<<(std::ostream& o, const rec_index_print& r) { mem_heap_t* heap = NULL; rec_offs* offsets = rec_get_offsets( - r.m_rec, r.m_index, NULL, page_rec_is_leaf(r.m_rec), + r.m_rec, r.m_index, NULL, page_rec_is_leaf(r.m_rec) + ? r.m_index->n_core_fields : 0, ULINT_UNDEFINED, &heap); rec_print(o, r.m_rec, rec_get_info_bits(r.m_rec, rec_offs_comp(offsets)), @@ -2624,7 +2643,7 @@ rec_get_trx_id( rec_offs_init(offsets_); rec_offs* offsets = offsets_; - offsets = rec_get_offsets(rec, index, offsets, true, + offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields, index->db_trx_id() + 1, &heap); trx_id = rec_get_nth_field(rec, offsets, index->db_trx_id(), &len); @@ -2675,7 +2694,8 @@ wsrep_rec_get_foreign_key( ut_ad(index_ref); rec_offs_init(offsets_); - offsets = rec_get_offsets(rec, index_for, offsets_, true, + offsets = rec_get_offsets(rec, index_for, offsets_, + index_for->n_core_fields, ULINT_UNDEFINED, &heap); ut_ad(rec_offs_validate(rec, NULL, offsets)); diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc index baf63650347..562395e3e80 100644 --- a/storage/innobase/row/row0ftsort.cc +++ b/storage/innobase/row/row0ftsort.cc @@ -909,7 +909,7 @@ loop: << " records, the sort queue has " << UT_LIST_GET_LEN(psort_info->fts_doc_list) << " records. But sort cannot get the next" - " records"; + " records during alter table " << table->name; goto exit; } } else if (psort_info->state == FTS_PARENT_EXITING) { @@ -1190,7 +1190,9 @@ row_merge_write_fts_word( if (UNIV_UNLIKELY(error != DB_SUCCESS)) { ib::error() << "Failed to write word to FTS auxiliary" - " index table, error " << error; + " index table " + << ins_ctx->btr_bulk->table_name() + << ", error " << error; ret = error; } diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 4e05649c56a..9ffbe41ed11 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -1839,7 +1839,8 @@ PageConverter::update_records( if (deleted || clust_index) { m_offsets = rec_get_offsets( - rec, m_index->m_srv_index, m_offsets, true, + rec, m_index->m_srv_index, m_offsets, + m_index->m_srv_index->n_core_fields, ULINT_UNDEFINED, &m_heap); } diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 4aed14cc059..77d2fdfd171 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2020, MariaDB Corporation. +Copyright (c) 2016, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -881,7 +881,7 @@ row_ins_foreign_fill_virtual( rec_offs offsets_[REC_OFFS_NORMAL_SIZE]; rec_offs_init(offsets_); const rec_offs* offsets = - rec_get_offsets(rec, index, offsets_, true, + rec_get_offsets(rec, index, offsets_, index->n_core_fields, ULINT_UNDEFINED, &cascade->heap); TABLE* mysql_table= NULL; upd_t* update = cascade->update; @@ -1195,7 +1195,8 @@ row_ins_foreign_check_on_constraint( if (table->fts) { doc_id = fts_get_doc_id_from_rec( clust_rec, clust_index, - rec_get_offsets(clust_rec, clust_index, NULL, true, + rec_get_offsets(clust_rec, clust_index, NULL, + clust_index->n_core_fields, ULINT_UNDEFINED, &tmp_heap)); } @@ -1638,7 +1639,8 @@ row_ins_check_foreign_constraint( continue; } - offsets = rec_get_offsets(rec, check_index, offsets, true, + offsets = rec_get_offsets(rec, check_index, offsets, + check_index->n_core_fields, ULINT_UNDEFINED, &heap); if (page_rec_is_supremum(rec)) { @@ -2126,7 +2128,8 @@ row_ins_scan_sec_index_for_duplicate( continue; } - offsets = rec_get_offsets(rec, index, offsets, true, + offsets = rec_get_offsets(rec, index, offsets, + index->n_core_fields, ULINT_UNDEFINED, &offsets_heap); if (flags & BTR_NO_LOCKING_FLAG) { @@ -2263,7 +2266,8 @@ row_ins_duplicate_error_in_clust_online( ut_ad(!cursor->index->is_instant()); if (cursor->low_match >= n_uniq && !page_rec_is_infimum(rec)) { - *offsets = rec_get_offsets(rec, cursor->index, *offsets, true, + *offsets = rec_get_offsets(rec, cursor->index, *offsets, + cursor->index->n_fields, ULINT_UNDEFINED, heap); err = row_ins_duplicate_online(n_uniq, entry, rec, *offsets); if (err != DB_SUCCESS) { @@ -2274,7 +2278,8 @@ row_ins_duplicate_error_in_clust_online( rec = page_rec_get_next_const(btr_cur_get_rec(cursor)); if (cursor->up_match >= n_uniq && !page_rec_is_supremum(rec)) { - *offsets = rec_get_offsets(rec, cursor->index, *offsets, true, + *offsets = rec_get_offsets(rec, cursor->index, *offsets, + cursor->index->n_fields, ULINT_UNDEFINED, heap); err = row_ins_duplicate_online(n_uniq, entry, rec, *offsets); } @@ -2330,7 +2335,7 @@ row_ins_duplicate_error_in_clust( if (!page_rec_is_infimum(rec)) { offsets = rec_get_offsets(rec, cursor->index, offsets, - true, + cursor->index->n_core_fields, ULINT_UNDEFINED, &heap); /* We set a lock on the possible duplicate: this @@ -2396,7 +2401,7 @@ duplicate: if (!page_rec_is_supremum(rec)) { offsets = rec_get_offsets(rec, cursor->index, offsets, - true, + cursor->index->n_core_fields, ULINT_UNDEFINED, &heap); if (trx->duplicates) { @@ -2513,7 +2518,7 @@ row_ins_index_entry_big_rec( btr_pcur_open(index, entry, PAGE_CUR_LE, BTR_MODIFY_TREE, &pcur, &mtr); rec = btr_pcur_get_rec(&pcur); - offsets = rec_get_offsets(rec, index, offsets, true, + offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields, ULINT_UNDEFINED, heap); DEBUG_SYNC_C_IF_THD(thd, "before_row_ins_extern"); @@ -3068,7 +3073,8 @@ row_ins_sec_index_entry_low( prefix, we must convert the insert into a modify of an existing record */ offsets = rec_get_offsets( - btr_cur_get_rec(&cursor), index, offsets, true, + btr_cur_get_rec(&cursor), index, offsets, + index->n_core_fields, ULINT_UNDEFINED, &offsets_heap); err = row_ins_sec_index_entry_by_modify( diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index 699c9d80694..336b5a27cc2 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -1258,7 +1258,8 @@ row_log_table_get_pk( if (!offsets) { offsets = rec_get_offsets( - rec, index, NULL, true, + rec, index, nullptr, + index->n_core_fields, index->db_trx_id() + 1, heap); } @@ -1308,7 +1309,8 @@ row_log_table_get_pk( } if (!offsets) { - offsets = rec_get_offsets(rec, index, NULL, true, + offsets = rec_get_offsets(rec, index, nullptr, + index->n_core_fields, ULINT_UNDEFINED, heap); } @@ -1985,7 +1987,8 @@ all_done: return(DB_SUCCESS); } - offsets = rec_get_offsets(btr_pcur_get_rec(&pcur), index, NULL, true, + offsets = rec_get_offsets(btr_pcur_get_rec(&pcur), index, nullptr, + index->n_core_fields, ULINT_UNDEFINED, &offsets_heap); #if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG ut_a(!rec_offs_any_null_extern(btr_pcur_get_rec(&pcur), offsets)); @@ -2182,7 +2185,7 @@ func_exit_committed: /* Prepare to update (or delete) the record. */ rec_offs* cur_offsets = rec_get_offsets( - btr_pcur_get_rec(&pcur), index, NULL, true, + btr_pcur_get_rec(&pcur), index, nullptr, index->n_core_fields, ULINT_UNDEFINED, &offsets_heap); if (!log->same_pk) { diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 44ab3e8d791..26f3a9debb7 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2005, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2020, MariaDB Corporation. +Copyright (c) 2014, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -2022,7 +2022,8 @@ end_of_index: rec = page_cur_get_rec(cur); if (online) { - offsets = rec_get_offsets(rec, clust_index, NULL, true, + offsets = rec_get_offsets(rec, clust_index, NULL, + clust_index->n_core_fields, ULINT_UNDEFINED, &row_heap); rec_trx_id = row_get_rec_trx_id(rec, clust_index, offsets); @@ -2114,7 +2115,8 @@ end_of_index: duplicate keys. */ continue; } else { - offsets = rec_get_offsets(rec, clust_index, NULL, true, + offsets = rec_get_offsets(rec, clust_index, NULL, + clust_index->n_core_fields, ULINT_UNDEFINED, &row_heap); /* This is a locking ALTER TABLE. @@ -3782,17 +3784,20 @@ row_merge_drop_indexes_dict( trx->op_info = ""; } -/*********************************************************************//** -Drop indexes that were created before an error occurred. +/** Drop indexes that were created before an error occurred. The data dictionary must have been locked exclusively by the caller, -because the transaction will not be committed. */ +because the transaction will not be committed. +@param trx dictionary transaction +@param table table containing the indexes +@param locked True if table is locked, + false - may need to do lazy drop +@param alter_trx Alter table transaction */ void row_merge_drop_indexes( -/*===================*/ - trx_t* trx, /*!< in/out: dictionary transaction */ - dict_table_t* table, /*!< in/out: table containing the indexes */ - ibool locked) /*!< in: TRUE=table locked, - FALSE=may need to do a lazy drop */ + trx_t* trx, + dict_table_t* table, + bool locked, + const trx_t* alter_trx) { dict_index_t* index; dict_index_t* next_index; @@ -3817,7 +3822,7 @@ row_merge_drop_indexes( A concurrent purge will be prevented by dict_sys.latch. */ if (!locked && (table->get_ref_count() > 1 - || UT_LIST_GET_FIRST(table->locks))) { + || table->has_lock_other_than(alter_trx))) { /* We will have to drop the indexes later, when the table is guaranteed to be no longer in use. Mark the indexes as incomplete and corrupted, so that other @@ -4246,6 +4251,7 @@ row_merge_create_index( dict_index_t* index; ulint n_fields = index_def->n_fields; ulint i; + ulint n_add_vcol = 0; DBUG_ENTER("row_merge_create_index"); @@ -4270,7 +4276,7 @@ row_merge_create_index( ut_ad(ifield->col_no >= table->n_v_def); name = add_v->v_col_name[ ifield->col_no - table->n_v_def]; - index->has_new_v_col = true; + n_add_vcol++; } else { name = dict_table_get_v_col_name( table, ifield->col_no); @@ -4282,6 +4288,10 @@ row_merge_create_index( dict_mem_index_add_field(index, name, ifield->prefix_len); } + if (n_add_vcol) { + index->assign_new_v_col(n_add_vcol); + } + DBUG_RETURN(index); } diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 9e374ab5c6e..ce0746f20c6 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -688,6 +688,7 @@ row_mysql_handle_errors( dberr_t err; DBUG_ENTER("row_mysql_handle_errors"); + DEBUG_SYNC_C("row_mysql_handle_errors"); handle_new_error: err = trx->error_state; @@ -1800,12 +1801,11 @@ row_update_for_mysql(row_prebuilt_t* prebuilt) clust_index = dict_table_get_first_index(table); - if (prebuilt->pcur->btr_cur.index == clust_index) { - btr_pcur_copy_stored_position(node->pcur, prebuilt->pcur); - } else { - btr_pcur_copy_stored_position(node->pcur, - prebuilt->clust_pcur); - } + btr_pcur_copy_stored_position(node->pcur, + prebuilt->pcur->btr_cur.index + == clust_index + ? prebuilt->pcur + : prebuilt->clust_pcur); ut_a(node->pcur->rel_pos == BTR_PCUR_ON); @@ -2014,7 +2014,8 @@ row_unlock_for_mysql( rec_offs* offsets = offsets_; rec_offs_init(offsets_); - offsets = rec_get_offsets(rec, index, offsets, true, + offsets = rec_get_offsets(rec, index, offsets, + index->n_core_fields, ULINT_UNDEFINED, &heap); rec_trx_id = row_get_rec_trx_id(rec, index, offsets); @@ -4789,7 +4790,7 @@ func_exit: rec = buf + mach_read_from_4(buf); - offsets = rec_get_offsets(rec, index, offsets_, true, + offsets = rec_get_offsets(rec, index, offsets_, index->n_core_fields, ULINT_UNDEFINED, &heap); if (prev_entry != NULL) { diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc index cad70a2c6eb..7a2971493f6 100644 --- a/storage/innobase/row/row0purge.cc +++ b/storage/innobase/row/row0purge.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -136,8 +136,9 @@ row_purge_remove_clust_if_poss_low( rec_offs offsets_[REC_OFFS_NORMAL_SIZE]; rec_offs_init(offsets_); mem_heap_t* heap = NULL; - rec_offs* offsets = rec_get_offsets( - rec, index, offsets_, true, ULINT_UNDEFINED, &heap); + rec_offs* offsets = rec_get_offsets(rec, index, offsets_, + index->n_core_fields, + ULINT_UNDEFINED, &heap); bool success = true; if (node->roll_ptr != row_get_rec_roll_ptr(rec, index, offsets)) { @@ -616,7 +617,7 @@ row_purge_skip_uncommitted_virtual_index( not support LOCK=NONE when adding an index on newly added virtual column.*/ while (index != NULL && dict_index_has_virtual(index) - && !index->is_committed() && index->has_new_v_col) { + && !index->is_committed() && index->has_new_v_col()) { index = dict_table_get_next_index(index); } } @@ -682,7 +683,8 @@ static void row_purge_reset_trx_id(purge_node_t* node, mtr_t* mtr) rec_offs offsets_[REC_OFFS_HEADER_SIZE + MAX_REF_PARTS + 2]; rec_offs_init(offsets_); rec_offs* offsets = rec_get_offsets( - rec, index, offsets_, true, trx_id_pos + 2, &heap); + rec, index, offsets_, index->n_core_fields, + trx_id_pos + 2, &heap); ut_ad(heap == NULL); ut_ad(dict_index_get_nth_field(index, trx_id_pos) @@ -1214,7 +1216,7 @@ purge_node_t::validate_pcur() dict_index_t* clust_index = pcur.btr_cur.index; rec_offs* offsets = rec_get_offsets( - pcur.old_rec, clust_index, NULL, true, + pcur.old_rec, clust_index, NULL, pcur.old_n_core_fields, pcur.old_n_fields, &heap); /* Here we are comparing the purge ref record and the stored initial diff --git a/storage/innobase/row/row0row.cc b/storage/innobase/row/row0row.cc index 39cefb463e4..7e70341a20e 100644 --- a/storage/innobase/row/row0row.cc +++ b/storage/innobase/row/row0row.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2018, 2020, MariaDB Corporation. +Copyright (c) 2018, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -440,7 +440,8 @@ row_build_low( ut_ad(!col_map || col_table); if (!offsets) { - offsets = rec_get_offsets(rec, index, offsets_, true, + offsets = rec_get_offsets(rec, index, offsets_, + index->n_core_fields, ULINT_UNDEFINED, &tmp_heap); } else { ut_ad(rec_offs_validate(rec, index, offsets)); @@ -1004,7 +1005,7 @@ row_build_row_ref( ut_ad(heap != NULL); ut_ad(!dict_index_is_clust(index)); - offsets = rec_get_offsets(rec, index, offsets, true, + offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields, ULINT_UNDEFINED, &tmp_heap); /* Secondary indexes must not contain externally stored columns. */ ut_ad(!rec_offs_any_extern(offsets)); @@ -1113,7 +1114,8 @@ row_build_row_ref_in_tuple( ut_ad(clust_index); if (!offsets) { - offsets = rec_get_offsets(rec, index, offsets_, true, + offsets = rec_get_offsets(rec, index, offsets_, + index->n_core_fields, ULINT_UNDEFINED, &heap); } else { ut_ad(rec_offs_validate(rec, index, offsets)); diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index 99e8cce1572..aaac86c93e2 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -203,9 +203,11 @@ row_sel_sec_rec_is_for_clust_rec( ib_vcol_row vc(heap); clust_offs = rec_get_offsets(clust_rec, clust_index, clust_offs, - true, ULINT_UNDEFINED, &heap); + clust_index->n_core_fields, + ULINT_UNDEFINED, &heap); sec_offs = rec_get_offsets(sec_rec, sec_index, sec_offs, - true, ULINT_UNDEFINED, &heap); + sec_index->n_fields, + ULINT_UNDEFINED, &heap); n = dict_index_get_n_ordering_defined_by_user(sec_index); @@ -908,7 +910,9 @@ row_sel_get_clust_rec( offsets = rec_get_offsets(rec, btr_pcur_get_btr_cur(&plan->pcur)->index, - offsets, true, ULINT_UNDEFINED, &heap); + offsets, + btr_pcur_get_btr_cur(&plan->pcur)->index + ->n_core_fields, ULINT_UNDEFINED, &heap); row_build_row_ref_fast(plan->clust_ref, plan->clust_map, rec, offsets); @@ -943,7 +947,8 @@ row_sel_get_clust_rec( goto err_exit; } - offsets = rec_get_offsets(clust_rec, index, offsets, true, + offsets = rec_get_offsets(clust_rec, index, offsets, + index->n_core_fields, ULINT_UNDEFINED, &heap); if (!node->read_view) { @@ -1153,7 +1158,8 @@ re_scan: rec = btr_pcur_get_rec(pcur); my_offsets = offsets_; - my_offsets = rec_get_offsets(rec, index, my_offsets, true, + my_offsets = rec_get_offsets(rec, index, my_offsets, + index->n_fields, ULINT_UNDEFINED, &heap); /* No match record */ @@ -1176,7 +1182,7 @@ re_scan: rtr_rec_t* rtr_rec = &(*it); my_offsets = rec_get_offsets( - rtr_rec->r_rec, index, my_offsets, true, + rtr_rec->r_rec, index, my_offsets, index->n_fields, ULINT_UNDEFINED, &heap); err = lock_sec_rec_read_check_and_lock( @@ -1483,7 +1489,7 @@ exhausted: rec_offs offsets_[REC_OFFS_NORMAL_SIZE]; rec_offs* offsets = offsets_; rec_offs_init(offsets_); - offsets = rec_get_offsets(rec, index, offsets, true, + offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields, ULINT_UNDEFINED, &heap); if (dict_index_is_clust(index)) { @@ -1699,7 +1705,7 @@ rec_loop: trx = thr_get_trx(thr); offsets = rec_get_offsets(next_rec, index, offsets, - true, + index->n_core_fields, ULINT_UNDEFINED, &heap); /* At READ UNCOMMITTED or READ COMMITTED @@ -1759,7 +1765,8 @@ skip_lock: unsigned lock_type; trx_t* trx; - offsets = rec_get_offsets(rec, index, offsets, true, + offsets = rec_get_offsets(rec, index, offsets, + index->n_core_fields, ULINT_UNDEFINED, &heap); trx = thr_get_trx(thr); @@ -1844,7 +1851,7 @@ skip_lock: /* PHASE 3: Get previous version in a consistent read */ cons_read_requires_clust_rec = FALSE; - offsets = rec_get_offsets(rec, index, offsets, true, + offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields, ULINT_UNDEFINED, &heap); if (consistent_read) { @@ -1875,7 +1882,8 @@ skip_lock: exhausted. */ offsets = rec_get_offsets( - rec, index, offsets, true, + rec, index, offsets, + index->n_core_fields, ULINT_UNDEFINED, &heap); /* Fetch the columns needed in @@ -3179,7 +3187,8 @@ class Row_sel_get_clust_rec_for_mysql ut_ad(rec_offs_validate(cached_clust_rec, index, offsets)); ut_ad(index->first_user_field() <= rec_offs_n_fields(offsets)); - ut_ad(vers_offs == rec_get_offsets(cached_old_vers, index, vers_offs, true, + ut_ad(vers_offs == rec_get_offsets(cached_old_vers, index, vers_offs, + index->n_core_fields, index->db_trx_id(), &heap)); ut_ad(!heap); for (auto n= index->db_trx_id(); n--; ) @@ -3366,7 +3375,8 @@ Row_sel_get_clust_rec_for_mysql::operator()( goto func_exit; } - *offsets = rec_get_offsets(clust_rec, clust_index, *offsets, true, + *offsets = rec_get_offsets(clust_rec, clust_index, *offsets, + clust_index->n_core_fields, ULINT_UNDEFINED, offset_heap); if (prebuilt->select_lock_type != LOCK_NONE) { @@ -3437,7 +3447,8 @@ Row_sel_get_clust_rec_for_mysql::operator()( ut_d(check_eq(clust_index, *offsets)); *offsets = rec_get_offsets( old_vers, clust_index, *offsets, - true, ULINT_UNDEFINED, offset_heap); + clust_index->n_core_fields, + ULINT_UNDEFINED, offset_heap); } } @@ -3866,7 +3877,7 @@ exhausted: /* This is a non-locking consistent read: if necessary, fetch a previous version of the record */ - *offsets = rec_get_offsets(rec, index, *offsets, true, + *offsets = rec_get_offsets(rec, index, *offsets, index->n_core_fields, ULINT_UNDEFINED, heap); if (!lock_clust_rec_cons_read_sees(rec, index, *offsets, @@ -4032,7 +4043,7 @@ row_sel_fill_vrow( ut_ad(!index->is_instant()); ut_ad(page_rec_is_leaf(rec)); - offsets = rec_get_offsets(rec, index, offsets, true, + offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields, ULINT_UNDEFINED, &heap); *vrow = dtuple_create_with_vcol( @@ -4665,7 +4676,7 @@ wait_table_again: const rec_t* next_rec = page_rec_get_next_const(rec); offsets = rec_get_offsets(next_rec, index, offsets, - true, + index->n_core_fields, ULINT_UNDEFINED, &heap); err = sel_set_rec_lock(pcur, next_rec, index, offsets, @@ -4746,7 +4757,8 @@ rec_loop: we do not lock gaps. Supremum record is really a gap and therefore we do not set locks there. */ - offsets = rec_get_offsets(rec, index, offsets, true, + offsets = rec_get_offsets(rec, index, offsets, + index->n_core_fields, ULINT_UNDEFINED, &heap); err = sel_set_rec_lock(pcur, rec, index, offsets, @@ -4848,7 +4860,7 @@ wrong_offs: ut_ad(fil_page_index_page_check(btr_pcur_get_page(pcur))); ut_ad(btr_page_get_index_id(btr_pcur_get_page(pcur)) == index->id); - offsets = rec_get_offsets(rec, index, offsets, true, + offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields, ULINT_UNDEFINED, &heap); if (UNIV_UNLIKELY(srv_force_recovery > 0)) { @@ -5091,7 +5103,8 @@ no_gap_lock: Do a normal locking read. */ offsets = rec_get_offsets( - rec, index, offsets, true, + rec, index, offsets, + index->n_core_fields, ULINT_UNDEFINED, &heap); goto locks_ok; case DB_DEADLOCK: @@ -5461,7 +5474,7 @@ use_covering_index: /* We used 'offsets' for the clust rec, recalculate them for 'rec' */ offsets = rec_get_offsets(rec, index, offsets, - true, + index->n_core_fields, ULINT_UNDEFINED, &heap); result_rec = rec; @@ -5920,7 +5933,7 @@ row_search_autoinc_read_column( rec_offs_init(offsets_); ut_ad(page_rec_is_leaf(rec)); - offsets = rec_get_offsets(rec, index, offsets, true, + offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields, col_no + 1, &heap); if (rec_offs_nth_sql_null(offsets, col_no)) { diff --git a/storage/innobase/row/row0uins.cc b/storage/innobase/row/row0uins.cc index 0ce136c5906..d4e09431aae 100644 --- a/storage/innobase/row/row0uins.cc +++ b/storage/innobase/row/row0uins.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -120,7 +120,8 @@ row_undo_ins_remove_clust_rec( if (online && dict_index_is_online_ddl(index)) { mem_heap_t* heap = NULL; const rec_offs* offsets = rec_get_offsets( - rec, index, NULL, true, ULINT_UNDEFINED, &heap); + rec, index, NULL, index->n_core_fields, + ULINT_UNDEFINED, &heap); row_log_table_delete(rec, index, offsets, NULL); mem_heap_free(heap); } else { diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc index e52ca5815f3..a7af11bacb9 100644 --- a/storage/innobase/row/row0umod.cc +++ b/storage/innobase/row/row0umod.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -189,8 +189,9 @@ static ulint row_trx_id_offset(const rec_t* rec, const dict_index_t* index) rec_offs_init(offsets_); mem_heap_t* heap = NULL; const ulint trx_id_pos = index->n_uniq ? index->n_uniq : 1; - rec_offs* offsets = rec_get_offsets(rec, index, offsets_, true, - trx_id_pos + 1, &heap); + rec_offs* offsets = rec_get_offsets(rec, index, offsets_, + index->n_core_fields, + trx_id_pos + 1, &heap); ut_ad(!heap); ulint len; trx_id_offset = rec_get_nth_field_offs( @@ -457,9 +458,9 @@ row_undo_mod_clust( } else { ut_ad(index->n_uniq <= MAX_REF_PARTS); rec_offs_init(offsets_); - offsets = rec_get_offsets( - rec, index, offsets_, true, trx_id_pos + 2, - &heap); + offsets = rec_get_offsets(rec, index, offsets_, + index->n_core_fields, + trx_id_pos + 2, &heap); ulint len; trx_id_offset = rec_get_nth_field_offs( offsets, trx_id_pos, &len); @@ -845,7 +846,8 @@ try_again: offsets_heap = NULL; offsets = rec_get_offsets( btr_cur_get_rec(btr_cur), - index, NULL, true, ULINT_UNDEFINED, &offsets_heap); + index, nullptr, index->n_core_fields, ULINT_UNDEFINED, + &offsets_heap); update = row_upd_build_sec_rec_difference_binary( btr_cur_get_rec(btr_cur), index, offsets, entry, heap); if (upd_get_n_fields(update) == 0) { diff --git a/storage/innobase/row/row0undo.cc b/storage/innobase/row/row0undo.cc index 375de331255..6aaa8266316 100644 --- a/storage/innobase/row/row0undo.cc +++ b/storage/innobase/row/row0undo.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -187,7 +187,8 @@ row_undo_search_clust_to_pcur( rec = btr_pcur_get_rec(&node->pcur); - offsets = rec_get_offsets(rec, clust_index, offsets, true, + offsets = rec_get_offsets(rec, clust_index, offsets, + clust_index->n_core_fields, ULINT_UNDEFINED, &heap); found = row_get_rec_roll_ptr(rec, clust_index, offsets) diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index e8fdd7b249a..975e917a585 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -693,7 +693,8 @@ row_upd_build_difference_binary( n_diff = 0; if (!offsets) { - offsets = rec_get_offsets(rec, index, offsets_, true, + offsets = rec_get_offsets(rec, index, offsets_, + index->n_core_fields, ULINT_UNDEFINED, &heap); } else { ut_ad(rec_offs_validate(rec, index, offsets)); @@ -1894,7 +1895,8 @@ row_upd_store_row( rec = btr_pcur_get_rec(node->pcur); - offsets = rec_get_offsets(rec, clust_index, offsets_, true, + offsets = rec_get_offsets(rec, clust_index, offsets_, + clust_index->n_core_fields, ULINT_UNDEFINED, &heap); if (dict_table_has_atomic_blobs(node->table)) { @@ -2133,7 +2135,7 @@ row_upd_sec_index_entry( && !wsrep_thd_is_BF(trx->mysql_thd, FALSE)) { rec_offs* offsets = rec_get_offsets( - rec, index, NULL, true, + rec, index, NULL, index->n_core_fields, ULINT_UNDEFINED, &heap); err = wsrep_row_upd_check_foreign_constraints( @@ -2176,12 +2178,9 @@ row_upd_sec_index_entry( ut_ad(err == DB_SUCCESS); if (referenced) { - - rec_offs* offsets; - - offsets = rec_get_offsets( - rec, index, NULL, true, ULINT_UNDEFINED, - &heap); + rec_offs* offsets = rec_get_offsets( + rec, index, NULL, index->n_core_fields, + ULINT_UNDEFINED, &heap); /* NOTE that the following call loses the position of pcur ! */ @@ -2432,7 +2431,8 @@ row_upd_clust_rec_by_insert( we update the primary key. Delete-mark the old record in the clustered index and prepare to insert a new entry. */ rec = btr_cur_get_rec(btr_cur); - offsets = rec_get_offsets(rec, index, offsets, true, + offsets = rec_get_offsets(rec, index, offsets, + index->n_core_fields, ULINT_UNDEFINED, &heap); ut_ad(page_rec_is_user_rec(rec)); @@ -2821,7 +2821,7 @@ row_upd_clust_step( } rec = btr_pcur_get_rec(pcur); - offsets = rec_get_offsets(rec, index, offsets_, true, + offsets = rec_get_offsets(rec, index, offsets_, index->n_core_fields, ULINT_UNDEFINED, &heap); if (!flags && !node->has_clust_rec_x_lock) { diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc index 7f410487b9a..f096149b0aa 100644 --- a/storage/innobase/row/row0vers.cc +++ b/storage/innobase/row/row0vers.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -116,7 +116,8 @@ row_vers_impl_x_locked_low( heap = mem_heap_create(1024); clust_offsets = rec_get_offsets(clust_rec, clust_index, clust_offsets_, - true, ULINT_UNDEFINED, &heap); + clust_index->n_core_fields, + ULINT_UNDEFINED, &heap); trx_id = row_get_rec_trx_id(clust_rec, clust_index, clust_offsets); if (trx_id == 0) { @@ -239,7 +240,8 @@ not_locked: } clust_offsets = rec_get_offsets( - prev_version, clust_index, clust_offsets_, true, + prev_version, clust_index, clust_offsets_, + clust_index->n_core_fields, ULINT_UNDEFINED, &heap); vers_del = rec_get_deleted_flag(prev_version, comp); @@ -553,7 +555,8 @@ row_vers_build_cur_vrow_low( clust_offsets = rec_get_offsets(prev_version, clust_index, NULL, - true, ULINT_UNDEFINED, &heap); + clust_index->n_core_fields, + ULINT_UNDEFINED, &heap); ulint entry_len = dict_index_get_n_fields(index); @@ -694,7 +697,8 @@ row_vers_vc_matches_cluster( clust_offsets = rec_get_offsets(prev_version, clust_index, NULL, - true, ULINT_UNDEFINED, &heap); + clust_index->n_core_fields, + ULINT_UNDEFINED, &heap); ulint entry_len = dict_index_get_n_fields(index); @@ -821,7 +825,8 @@ row_vers_build_cur_vrow( index, roll_ptr, trx_id, v_heap, &cur_vrow, mtr); } - *clust_offsets = rec_get_offsets(rec, clust_index, NULL, true, + *clust_offsets = rec_get_offsets(rec, clust_index, NULL, + clust_index->n_core_fields, ULINT_UNDEFINED, &heap); return(cur_vrow); } @@ -873,7 +878,8 @@ row_vers_old_has_index_entry( comp = page_rec_is_comp(rec); ut_ad(!dict_table_is_comp(index->table) == !comp); heap = mem_heap_create(1024); - clust_offsets = rec_get_offsets(rec, clust_index, NULL, true, + clust_offsets = rec_get_offsets(rec, clust_index, NULL, + clust_index->n_core_fields, ULINT_UNDEFINED, &heap); if (dict_index_has_virtual(index)) { @@ -951,7 +957,8 @@ row_vers_old_has_index_entry( } } clust_offsets = rec_get_offsets(rec, clust_index, NULL, - true, + clust_index + ->n_core_fields, ULINT_UNDEFINED, &heap); } else { @@ -1026,7 +1033,8 @@ unsafe_to_purge: } clust_offsets = rec_get_offsets(prev_version, clust_index, - NULL, true, + NULL, + clust_index->n_core_fields, ULINT_UNDEFINED, &heap); if (dict_index_has_virtual(index)) { @@ -1167,7 +1175,7 @@ row_vers_build_for_consistent_read( *offsets = rec_get_offsets( prev_version, index, *offsets, - true, ULINT_UNDEFINED, offset_heap); + index->n_core_fields, ULINT_UNDEFINED, offset_heap); #if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG ut_a(!rec_offs_any_null_extern(prev_version, *offsets)); @@ -1283,11 +1291,10 @@ committed_version_trx: semi-consistent read. */ version = rec; - *offsets = rec_get_offsets(version, - index, *offsets, - true, - ULINT_UNDEFINED, - offset_heap); + *offsets = rec_get_offsets( + version, index, *offsets, + index->n_core_fields, ULINT_UNDEFINED, + offset_heap); } buf = static_cast<byte*>( @@ -1330,7 +1337,8 @@ committed_version_trx: } version = prev_version; - *offsets = rec_get_offsets(version, index, *offsets, true, + *offsets = rec_get_offsets(version, index, *offsets, + index->n_core_fields, ULINT_UNDEFINED, offset_heap); #if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG ut_a(!rec_offs_any_null_extern(version, *offsets)); diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 3b6a63a3251..261e50285b7 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -1598,7 +1598,7 @@ file_checked: to the data files and truncate or delete the log. Unless --export is specified, no further change to InnoDB files is needed. */ - ut_ad(!srv_force_recovery); + ut_ad(srv_force_recovery <= SRV_FORCE_IGNORE_CORRUPT); ut_ad(recv_no_log_write); err = fil_write_flushed_lsn(log_sys.get_lsn()); DBUG_ASSERT(!buf_pool.any_io_pending()); diff --git a/storage/innobase/trx/trx0i_s.cc b/storage/innobase/trx/trx0i_s.cc index 22a0926a6de..d49fcb4f52d 100644 --- a/storage/innobase/trx/trx0i_s.cc +++ b/storage/innobase/trx/trx0i_s.cc @@ -651,7 +651,8 @@ fill_lock_data( ut_a(n_fields > 0); heap = NULL; - offsets = rec_get_offsets(rec, index, offsets, true, n_fields, &heap); + offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields, + n_fields, &heap); /* format and store the data */ diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc index 1df61ac5b56..714e527b259 100644 --- a/storage/innobase/trx/trx0rec.cc +++ b/storage/innobase/trx/trx0rec.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2019, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -2472,7 +2472,8 @@ trx_undo_prev_version_build( rec_offs offsets_dbg[REC_OFFS_NORMAL_SIZE]; rec_offs_init(offsets_dbg); ut_a(!rec_offs_any_null_extern( - *old_vers, rec_get_offsets(*old_vers, index, offsets_dbg, true, + *old_vers, rec_get_offsets(*old_vers, index, offsets_dbg, + index->n_core_fields, ULINT_UNDEFINED, &heap))); #endif // defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc index 9011ca8f2e1..3064645f556 100644 --- a/storage/innobase/trx/trx0sys.cc +++ b/storage/innobase/trx/trx0sys.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/storage/innobase/ut/ut0ut.cc b/storage/innobase/ut/ut0ut.cc index fa04af6de13..1dd1cff6ece 100644 --- a/storage/innobase/ut/ut0ut.cc +++ b/storage/innobase/ut/ut0ut.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1994, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -637,7 +637,7 @@ const char * dbug_print_rec(const rec_t* rec, dict_index_t* index) rec_offs* offsets = offsets_; rec_offs_init(offsets_); mem_heap_t* tmp_heap = NULL; - offsets = rec_get_offsets(rec, index, offsets, true, + offsets = rec_get_offsets(rec, index, offsets, index->n_core_fields, ULINT_UNDEFINED, &tmp_heap); rec_printer r(rec, offsets); strmake(dbug_print_buf, r.str().c_str(), sizeof(dbug_print_buf) - 1); |