diff options
author | unknown <marko@hundin.mysql.fi> | 2004-12-09 15:29:55 +0200 |
---|---|---|
committer | unknown <marko@hundin.mysql.fi> | 2004-12-09 15:29:55 +0200 |
commit | 7945222c28e3a6a4e6087c7c99ea34c3a990e46f (patch) | |
tree | 6765ffbcdc2b26af7abb9ec1f19b58356912d9bc | |
parent | f9bd116c297f80613ed0e51750e20e5fcb623f75 (diff) | |
download | mariadb-git-7945222c28e3a6a4e6087c7c99ea34c3a990e46f.tar.gz |
InnoDB: Changed interface to rec_get_offsets(), to reduce the use of
memory heaps. This changeset plugs also a few memory leaks that
were introduced with the compact InnoDB table format.
innobase/btr/btr0btr.c:
Changed interface to rec_get_offsets()
innobase/btr/btr0cur.c:
Changed interface to rec_get_offsets()
innobase/btr/btr0pcur.c:
Changed interface to rec_get_offsets()
innobase/btr/btr0sea.c:
Changed interface to rec_get_offsets()
innobase/include/rem0rec.h:
Changed interface to rec_get_offsets()
innobase/include/rem0rec.ic:
Changed interface to rec_get_offsets()
innobase/lock/lock0lock.c:
Changed interface to rec_get_offsets()
innobase/page/page0cur.c:
Changed interface to rec_get_offsets()
innobase/page/page0page.c:
Changed interface to rec_get_offsets()
innobase/rem/rem0rec.c:
Changed interface to rec_get_offsets()
innobase/row/row0ins.c:
Changed interface to rec_get_offsets()
innobase/row/row0mysql.c:
Changed interface to rec_get_offsets()
innobase/row/row0purge.c:
Changed interface to rec_get_offsets()
innobase/row/row0row.c:
Changed interface to rec_get_offsets()
innobase/row/row0sel.c:
Changed interface to rec_get_offsets()
innobase/row/row0umod.c:
Changed interface to rec_print()
innobase/row/row0undo.c:
Changed interface to rec_get_offsets()
innobase/row/row0upd.c:
Changed interface to rec_get_offsets()
innobase/row/row0vers.c:
Changed interface to rec_get_offsets()
innobase/trx/trx0rec.c:
Changed interface to rec_get_offsets()
-rw-r--r-- | innobase/btr/btr0btr.c | 163 | ||||
-rw-r--r-- | innobase/btr/btr0cur.c | 182 | ||||
-rw-r--r-- | innobase/btr/btr0pcur.c | 9 | ||||
-rw-r--r-- | innobase/btr/btr0sea.c | 171 | ||||
-rw-r--r-- | innobase/include/rem0rec.h | 73 | ||||
-rw-r--r-- | innobase/include/rem0rec.ic | 83 | ||||
-rw-r--r-- | innobase/lock/lock0lock.c | 66 | ||||
-rw-r--r-- | innobase/page/page0cur.c | 138 | ||||
-rw-r--r-- | innobase/page/page0page.c | 72 | ||||
-rw-r--r-- | innobase/rem/rem0rec.c | 164 | ||||
-rw-r--r-- | innobase/row/row0ins.c | 140 | ||||
-rw-r--r-- | innobase/row/row0mysql.c | 17 | ||||
-rw-r--r-- | innobase/row/row0purge.c | 14 | ||||
-rw-r--r-- | innobase/row/row0row.c | 49 | ||||
-rw-r--r-- | innobase/row/row0sel.c | 252 | ||||
-rw-r--r-- | innobase/row/row0umod.c | 6 | ||||
-rw-r--r-- | innobase/row/row0undo.c | 12 | ||||
-rw-r--r-- | innobase/row/row0upd.c | 92 | ||||
-rw-r--r-- | innobase/row/row0vers.c | 33 | ||||
-rw-r--r-- | innobase/trx/trx0rec.c | 32 |
20 files changed, 940 insertions, 828 deletions
diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c index c911124e705..9da422e927f 100644 --- a/innobase/btr/btr0btr.c +++ b/innobase/btr/btr0btr.c @@ -567,7 +567,8 @@ btr_page_get_father_for_rec( btr_cur_t cursor; rec_t* node_ptr; dict_index_t* index; - ulint* offsets; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree), MTR_MEMO_X_LOCK)); @@ -591,7 +592,8 @@ btr_page_get_father_for_rec( BTR_CONT_MODIFY_TREE, &cursor, 0, mtr); node_ptr = btr_cur_get_rec(&cursor); - offsets = rec_get_offsets(node_ptr, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(node_ptr, index, offsets, + ULINT_UNDEFINED, &heap); if (btr_node_ptr_get_child_page_no(node_ptr, offsets) != buf_frame_get_page_no(page)) { @@ -609,13 +611,13 @@ btr_page_get_father_for_rec( (ulong) btr_node_ptr_get_child_page_no(node_ptr, offsets), (ulong) buf_frame_get_page_no(page)); - offsets = rec_reget_offsets(page_rec_get_next( + offsets = rec_get_offsets(page_rec_get_next( page_get_infimum_rec(page)), index, - offsets, ULINT_UNDEFINED, heap); + offsets, ULINT_UNDEFINED, &heap); page_rec_print(page_rec_get_next(page_get_infimum_rec(page)), offsets); - offsets = rec_reget_offsets(node_ptr, index, offsets, - ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(node_ptr, index, offsets, + ULINT_UNDEFINED, &heap); page_rec_print(node_ptr, offsets); fputs( @@ -1231,7 +1233,7 @@ btr_page_get_sure_split_rec( ins_rec = btr_cur_get_rec(cursor); rec = page_get_infimum_rec(page); - heap = mem_heap_create(100); + heap = NULL; offsets = NULL; /* We start to include records to the left half, and when the @@ -1256,8 +1258,8 @@ btr_page_get_sure_split_rec( /* Include tuple */ incl_data += insert_size; } else { - offsets = rec_reget_offsets(rec, cursor->index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, cursor->index, + offsets, ULINT_UNDEFINED, &heap); incl_data += rec_offs_size(offsets); } @@ -1280,12 +1282,16 @@ btr_page_get_sure_split_rec( next_rec = page_rec_get_next(rec); } if (next_rec != page_get_supremum_rec(page)) { - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(next_rec); } } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(rec); } } @@ -1367,8 +1373,8 @@ btr_page_insert_fits( /* In this loop we calculate the amount of reserved space after rec is removed from page. */ - offs = rec_reget_offsets(rec, cursor->index, offs, - ULINT_UNDEFINED, heap); + offs = rec_get_offsets(rec, cursor->index, offs, + ULINT_UNDEFINED, &heap); total_data -= rec_offs_size(offs); total_n_recs--; @@ -1459,7 +1465,7 @@ btr_attach_half_pages( ut_a(page_is_comp(page) == page_is_comp(new_page)); /* Create a memory heap where the data tuple is stored */ - heap = mem_heap_create(100); + heap = mem_heap_create(1024); /* Based on split direction, decide upper and lower pages */ if (direction == FSP_DOWN) { @@ -1478,7 +1484,7 @@ btr_attach_half_pages( btr_node_ptr_set_child_page_no(node_ptr, rec_get_offsets(node_ptr, UT_LIST_GET_FIRST(tree->tree_indexes), - ULINT_UNDEFINED, heap), + NULL, ULINT_UNDEFINED, &heap), lower_page_no, mtr); mem_heap_empty(heap); } else { @@ -1656,8 +1662,8 @@ func_start: thus reducing the tree latch contention. */ if (split_rec) { - offsets = rec_reget_offsets(split_rec, cursor->index, - offsets, n_uniq, heap); + offsets = rec_get_offsets(split_rec, cursor->index, offsets, + n_uniq, &heap); insert_will_fit = btr_page_insert_fits(cursor, split_rec, offsets, tuple, heap); @@ -1700,8 +1706,8 @@ func_start: insert_page = right_page; } else { - offsets = rec_reget_offsets(first_rec, cursor->index, - offsets, n_uniq, heap); + offsets = rec_get_offsets(first_rec, cursor->index, + offsets, n_uniq, &heap); if (cmp_dtuple_rec(tuple, first_rec, offsets) >= 0) { @@ -2091,14 +2097,18 @@ btr_compress( if (is_left) { btr_node_ptr_delete(tree, page, mtr); } else { - mem_heap_t* heap = mem_heap_create(100); + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; /* Replace the address of the old child node (= page) with the address of the merge page to the right */ btr_node_ptr_set_child_page_no(node_ptr, rec_get_offsets(node_ptr, cursor->index, - ULINT_UNDEFINED, heap), right_page_no, mtr); - mem_heap_free(heap); + offsets_, ULINT_UNDEFINED, &heap), + right_page_no, mtr); + if (heap) { + mem_heap_free(heap); + } btr_node_ptr_delete(tree, merge_page, mtr); } @@ -2312,8 +2322,8 @@ btr_print_recursive( page_t* page, /* in: index page */ ulint width, /* in: print this many entries from start and end */ - mem_heap_t* heap, /* in: heap for rec_reget_offsets() */ - ulint** offsets,/* in/out: buffer for rec_reget_offsets() */ + mem_heap_t** heap, /* in/out: heap for rec_get_offsets() */ + ulint** offsets,/* in/out: buffer for rec_get_offsets() */ mtr_t* mtr) /* in: mtr */ { page_cur_t cursor; @@ -2350,8 +2360,8 @@ btr_print_recursive( node_ptr = page_cur_get_rec(&cursor); - *offsets = rec_reget_offsets(node_ptr, index, - *offsets, ULINT_UNDEFINED, heap); + *offsets = rec_get_offsets(node_ptr, index, *offsets, + ULINT_UNDEFINED, heap); child = btr_node_ptr_get_child(node_ptr, *offsets, &mtr2); btr_print_recursive(tree, child, width, @@ -2362,8 +2372,6 @@ btr_print_recursive( page_cur_move_to_next(&cursor); i++; } - - mem_heap_free(heap); } /****************************************************************** @@ -2378,8 +2386,10 @@ btr_print_tree( { mtr_t mtr; page_t* root; - mem_heap_t* heap = mem_heap_create(100); - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] + = { 100, }; + ulint* offsets = offsets_; fputs("--------------------------\n" "INDEX TREE PRINT\n", stderr); @@ -2388,8 +2398,10 @@ btr_print_tree( root = btr_root_get(tree, &mtr); - btr_print_recursive(tree, root, width, heap, &offsets, &mtr); - mem_heap_free(heap); + btr_print_recursive(tree, root, width, &heap, &offsets, &mtr); + if (heap) { + mem_heap_free(heap); + } mtr_commit(&mtr); @@ -2435,7 +2447,7 @@ btr_check_node_ptr( ut_a(cmp_dtuple_rec(node_ptr_tuple, node_ptr, rec_get_offsets(node_ptr, dict_tree_find_index(tree, node_ptr), - ULINT_UNDEFINED, heap)) == 0); + NULL, ULINT_UNDEFINED, &heap)) == 0); mem_heap_free(heap); @@ -2476,8 +2488,10 @@ btr_index_rec_validate( ulint n; ulint i; page_t* page; - mem_heap_t* heap; - ulint* offsets; + mem_heap_t* heap = NULL; + ulint offsets_[100] + = { 100, }; + ulint* offsets = offsets_; page = buf_frame_align(rec); @@ -2496,22 +2510,17 @@ btr_index_rec_validate( fprintf(stderr, "InnoDB: has %lu fields, should have %lu\n", (ulong) rec_get_n_fields_old(rec), (ulong) n); - if (!dump_on_error) { + if (dump_on_error) { + buf_page_print(page); - return(FALSE); + fputs("InnoDB: corrupt record ", stderr); + rec_print_old(stderr, rec); + putc('\n', stderr); } - - buf_page_print(page); - - fputs("InnoDB: corrupt record ", stderr); - rec_print_old(stderr, rec); - putc('\n', stderr); - return(FALSE); } - heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); for (i = 0; i < n; i++) { dtype_t* type = dict_index_get_nth_type(index, i); @@ -2536,23 +2545,23 @@ btr_index_rec_validate( "InnoDB: field %lu len is %lu, should be %lu\n", (ulong) i, (ulong) len, (ulong) dtype_get_fixed_size(type)); - if (!dump_on_error) { + if (dump_on_error) { + buf_page_print(page); + + fputs("InnoDB: corrupt record ", stderr); + rec_print_new(stderr, rec, offsets); + putc('\n', stderr); + } + if (heap) { mem_heap_free(heap); - return(FALSE); } - - buf_page_print(page); - - fputs("InnoDB: corrupt record ", stderr); - rec_print(stderr, rec, offsets); - putc('\n', stderr); - - mem_heap_free(heap); return(FALSE); } } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(TRUE); } @@ -2677,8 +2686,8 @@ btr_validate_level( page_cur_move_to_next(&cursor); node_ptr = page_cur_get_rec(&cursor); - offsets = rec_reget_offsets(node_ptr, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(node_ptr, index, offsets, + ULINT_UNDEFINED, &heap); page = btr_node_ptr_get_child(node_ptr, offsets, &mtr); } @@ -2722,10 +2731,10 @@ loop: rec = page_rec_get_prev(page_get_supremum_rec(page)); right_rec = page_rec_get_next( page_get_infimum_rec(right_page)); - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); - offsets2 = rec_reget_offsets(right_rec, index, - offsets2, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, + offsets, ULINT_UNDEFINED, &heap); + offsets2 = rec_get_offsets(right_rec, index, + offsets2, ULINT_UNDEFINED, &heap); if (cmp_rec_rec(rec, right_rec, offsets, offsets2, dict_index_get_n_fields(index), index) >= 0) { @@ -2740,16 +2749,12 @@ loop: fputs("InnoDB: record ", stderr); rec = page_rec_get_prev(page_get_supremum_rec(page)); - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); - rec_print(stderr, rec, offsets); + rec_print(stderr, rec, index); putc('\n', stderr); fputs("InnoDB: record ", stderr); rec = page_rec_get_next(page_get_infimum_rec( right_page)); - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); - rec_print(stderr, rec, offsets); + rec_print(stderr, rec, index); putc('\n', stderr); ret = FALSE; @@ -2768,8 +2773,8 @@ loop: node_ptr = btr_page_get_father_node_ptr(tree, page, &mtr); father_page = buf_frame_align(node_ptr); - offsets = rec_reget_offsets(node_ptr, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(node_ptr, index, + offsets, ULINT_UNDEFINED, &heap); if (btr_node_ptr_get_child_page_no(node_ptr, offsets) != buf_frame_get_page_no(page) @@ -2785,7 +2790,7 @@ loop: buf_page_print(page); fputs("InnoDB: node ptr ", stderr); - rec_print(stderr, node_ptr, offsets); + rec_print_new(stderr, node_ptr, offsets); fprintf(stderr, "\n" "InnoDB: node ptr child page n:o %lu\n", @@ -2796,9 +2801,7 @@ loop: rec = btr_page_get_father_for_rec(tree, page, page_rec_get_prev(page_get_supremum_rec(page)), &mtr); - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); - rec_print(stderr, rec, offsets); + rec_print(stderr, rec, index); putc('\n', stderr); ret = FALSE; @@ -2806,8 +2809,8 @@ loop: } if (btr_page_get_level(page, &mtr) > 0) { - offsets = rec_reget_offsets(node_ptr, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(node_ptr, index, + offsets, ULINT_UNDEFINED, &heap); node_ptr_tuple = dict_tree_build_node_ptr( tree, @@ -2829,11 +2832,9 @@ loop: fputs("InnoDB: Error: node ptrs differ" " on levels > 0\n" "InnoDB: node ptr ", stderr); - rec_print(stderr, node_ptr, offsets); + rec_print_new(stderr, node_ptr, offsets); fputs("InnoDB: first rec ", stderr); - offsets = rec_reget_offsets(first_rec, index, - offsets, ULINT_UNDEFINED, heap); - rec_print(stderr, first_rec, offsets); + rec_print(stderr, first_rec, index); putc('\n', stderr); ret = FALSE; diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c index f5e146172ed..a3083e0e545 100644 --- a/innobase/btr/btr0cur.c +++ b/innobase/btr/btr0cur.c @@ -274,8 +274,9 @@ btr_cur_search_to_nth_level( #ifdef BTR_CUR_ADAPT btr_search_t* info; #endif - mem_heap_t* heap; - ulint* offsets; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; /* Currently, PAGE_CUR_LE is the only search mode used for searches ending to upper levels */ @@ -395,8 +396,6 @@ btr_cur_search_to_nth_level( break; } - heap = mem_heap_create(100); - offsets = NULL; /* Loop and search until we arrive at the desired level */ for (;;) { @@ -431,7 +430,9 @@ retry_page_get: cursor->thr)) { /* Insertion to the insert buffer succeeded */ cursor->flag = BTR_CUR_INSERT_TO_IBUF; - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return; } @@ -517,13 +518,15 @@ retry_page_get: guess = NULL; node_ptr = page_cur_get_rec(page_cursor); - offsets = rec_reget_offsets(node_ptr, cursor->index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(node_ptr, cursor->index, offsets, + ULINT_UNDEFINED, &heap); /* Go to the child node */ page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets); } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } if (level == 0) { cursor->low_match = low_match; @@ -574,8 +577,9 @@ btr_cur_open_at_index_side( rec_t* node_ptr; ulint estimate; ulint savepoint; - mem_heap_t* heap; - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; estimate = latch_mode & BTR_ESTIMATE; latch_mode = latch_mode & ~BTR_ESTIMATE; @@ -600,7 +604,6 @@ btr_cur_open_at_index_side( page_no = dict_tree_get_page(tree); height = ULINT_UNDEFINED; - heap = mem_heap_create(100); for (;;) { page = buf_page_get_gen(space, page_no, RW_NO_LATCH, NULL, @@ -670,13 +673,15 @@ btr_cur_open_at_index_side( height--; node_ptr = page_cur_get_rec(page_cursor); - offsets = rec_reget_offsets(node_ptr, cursor->index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(node_ptr, cursor->index, offsets, + ULINT_UNDEFINED, &heap); /* Go to the child node */ page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets); } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } /************************************************************************** @@ -697,8 +702,9 @@ btr_cur_open_at_rnd_pos( ulint space; ulint height; rec_t* node_ptr; - mem_heap_t* heap = mem_heap_create(100); - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; tree = index->tree; @@ -747,13 +753,15 @@ btr_cur_open_at_rnd_pos( height--; node_ptr = page_cur_get_rec(page_cursor); - offsets = rec_reget_offsets(node_ptr, cursor->index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(node_ptr, cursor->index, offsets, + ULINT_UNDEFINED, &heap); /* Go to the child node */ page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets); } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } /*==================== B-TREE INSERT =========================*/ @@ -1242,11 +1250,14 @@ btr_cur_upd_lock_and_undo( err = DB_SUCCESS; if (!(flags & BTR_NO_LOCKING_FLAG)) { - mem_heap_t* heap = mem_heap_create(100); + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; err = lock_clust_rec_modify_check_and_lock(flags, rec, index, - rec_get_offsets(rec, index, ULINT_UNDEFINED, heap), - thr); - mem_heap_free(heap); + rec_get_offsets(rec, index, offsets_, + ULINT_UNDEFINED, &heap), thr); + if (heap) { + mem_heap_free(heap); + } if (err != DB_SUCCESS) { return(err); @@ -1374,7 +1385,7 @@ btr_cur_parse_update_in_place( /* We do not need to reserve btr_search_latch, as the page is only being recovered, and there cannot be a hash index to it. */ - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap); if (!(flags & BTR_KEEP_SYS_FLAG)) { row_upd_rec_sys_fields_in_recovery(rec, offsets, @@ -1413,18 +1424,19 @@ btr_cur_update_in_place( dulint roll_ptr = ut_dulint_zero; trx_t* trx; ibool was_delete_marked; - mem_heap_t* heap; - const ulint* offsets; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; rec = btr_cur_get_rec(cursor); index = cursor->index; trx = thr_get_trx(thr); heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); if (btr_cur_print_record_ops && thr) { btr_cur_trx_report(trx, index, "update "); - rec_print(stderr, rec, offsets); + rec_print_new(stderr, rec, offsets); } /* Do lock checking and undo logging */ @@ -1432,7 +1444,9 @@ btr_cur_update_in_place( thr, &roll_ptr); if (err != DB_SUCCESS) { - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(err); } @@ -1477,7 +1491,9 @@ btr_cur_update_in_place( btr_cur_unmark_extern_fields(rec, mtr, offsets); } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(DB_SUCCESS); } @@ -1526,11 +1542,11 @@ btr_cur_optimistic_update( index = cursor->index; heap = mem_heap_create(1024); - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap); if (btr_cur_print_record_ops && thr) { btr_cur_trx_report(thr_get_trx(thr), index, "update "); - rec_print(stderr, rec, offsets); + rec_print_new(stderr, rec, offsets); } ut_ad(mtr_memo_contains(mtr, buf_block_align(page), @@ -1646,8 +1662,8 @@ btr_cur_optimistic_update( /* The new inserted record owns its possible externally stored fields */ - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); btr_cur_unmark_extern_fields(rec, mtr, offsets); } @@ -1801,7 +1817,7 @@ btr_cur_pessimistic_update( } heap = mem_heap_create(1024); - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap); trx = thr_get_trx(thr); @@ -1836,8 +1852,8 @@ btr_cur_pessimistic_update( ext_vect = mem_heap_alloc(heap, sizeof(ulint) * dict_index_get_n_fields(index)); ut_ad(!cursor->index->table->comp || !rec_get_node_ptr_flag(rec)); - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); n_ext_vect = btr_push_update_extern_fields(ext_vect, offsets, update); if (rec_get_converted_size(index, new_entry) >= @@ -1877,8 +1893,8 @@ btr_cur_pessimistic_update( ut_a(rec || optim_err != DB_UNDERFLOW); if (rec) { - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); lock_rec_restore_from_page_infimum(rec, page); rec_set_field_extern_bits(rec, index, @@ -1918,8 +1934,7 @@ btr_cur_pessimistic_update( ut_a(dummy_big_rec == NULL); rec_set_field_extern_bits(rec, index, ext_vect, n_ext_vect, mtr); - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); if (!rec_get_deleted_flag(rec, rec_offs_comp(offsets))) { /* The new inserted record owns its possible externally @@ -2048,12 +2063,15 @@ btr_cur_parse_del_mark_set_clust_rec( rec = page + offset; if (!(flags & BTR_KEEP_SYS_FLAG)) { - mem_heap_t* heap = mem_heap_create(100); + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; row_upd_rec_sys_fields_in_recovery(rec, - rec_get_offsets(rec, index, - ULINT_UNDEFINED, heap), + rec_get_offsets(rec, index, offsets_, + ULINT_UNDEFINED, &heap), pos, trx_id, roll_ptr); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } /* We do not need to reserve btr_search_latch, as the page @@ -2089,17 +2107,17 @@ btr_cur_del_mark_set_clust_rec( ulint err; rec_t* rec; trx_t* trx; - mem_heap_t* heap; - const ulint* offsets; - + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; + rec = btr_cur_get_rec(cursor); index = cursor->index; - heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); if (btr_cur_print_record_ops && thr) { btr_cur_trx_report(thr_get_trx(thr), index, "del mark "); - rec_print(stderr, rec, offsets); + rec_print_new(stderr, rec, offsets); } ut_ad(index->type & DICT_CLUSTERED); @@ -2110,7 +2128,9 @@ btr_cur_del_mark_set_clust_rec( if (err != DB_SUCCESS) { - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(err); } @@ -2119,7 +2139,9 @@ btr_cur_del_mark_set_clust_rec( &roll_ptr); if (err != DB_SUCCESS) { - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(err); } @@ -2143,7 +2165,9 @@ btr_cur_del_mark_set_clust_rec( btr_cur_del_mark_set_clust_rec_log(flags, rec, index, val, trx, roll_ptr, mtr); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(DB_SUCCESS); } @@ -2246,12 +2270,9 @@ btr_cur_del_mark_set_sec_rec( rec = btr_cur_get_rec(cursor); if (btr_cur_print_record_ops && thr) { - mem_heap_t* heap = mem_heap_create(100); btr_cur_trx_report(thr_get_trx(thr), cursor->index, "del mark "); - rec_print(stderr, rec, rec_get_offsets(rec, cursor->index, - ULINT_UNDEFINED, heap)); - mem_heap_free(heap); + rec_print(stderr, rec, cursor->index); } err = lock_sec_rec_modify_check_and_lock(flags, rec, cursor->index, @@ -2375,9 +2396,10 @@ btr_cur_optimistic_delete( { page_t* page; ulint max_ins_size; - mem_heap_t* heap; rec_t* rec; - const ulint* offsets; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_ad(mtr_memo_contains(mtr, buf_block_align(btr_cur_get_page(cursor)), MTR_MEMO_PAGE_X_FIX)); @@ -2387,9 +2409,9 @@ btr_cur_optimistic_delete( ut_ad(btr_page_get_level(page, mtr) == 0); - heap = mem_heap_create(100); rec = btr_cur_get_rec(cursor); - offsets = rec_get_offsets(rec, cursor->index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, cursor->index, offsets, + ULINT_UNDEFINED, &heap); if (!rec_offs_any_extern(offsets) && btr_cur_can_delete_without_compress( @@ -2406,11 +2428,15 @@ btr_cur_optimistic_delete( ibuf_update_free_bits_low(cursor->index, page, max_ins_size, mtr); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(TRUE); } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(FALSE); } @@ -2487,8 +2513,9 @@ btr_cur_pessimistic_delete( : !rec_get_1byte_offs_flag(rec)) { btr_rec_free_externally_stored_fields(cursor->index, rec, rec_get_offsets(rec, cursor->index, - ULINT_UNDEFINED, heap), + NULL, ULINT_UNDEFINED, &heap), in_rollback, mtr); + mem_heap_empty(heap); } if ((page_get_n_recs(page) < 2) @@ -2772,13 +2799,14 @@ btr_estimate_number_of_different_key_vals( ulint j; ulint add_on; mtr_t mtr; - mem_heap_t* heap; - ulint* offsets1 = 0; - ulint* offsets2 = 0; + mem_heap_t* heap = NULL; + ulint offsets1_[100] = { 100, }; + ulint offsets2_[100] = { 100, }; + ulint* offsets1 = offsets1_; + ulint* offsets2 = offsets2_; n_cols = dict_index_get_n_unique(index); - heap = mem_heap_create(100); n_diff = mem_alloc((n_cols + 1) * sizeof(ib_longlong)); for (j = 0; j <= n_cols; j++) { @@ -2813,10 +2841,10 @@ btr_estimate_number_of_different_key_vals( rec_t* next_rec = page_rec_get_next(rec); matched_fields = 0; matched_bytes = 0; - offsets1 = rec_reget_offsets(rec, index, - offsets1, ULINT_UNDEFINED, heap); - offsets2 = rec_reget_offsets(next_rec, index, - offsets2, n_cols, heap); + offsets1 = rec_get_offsets(rec, index, offsets1, + ULINT_UNDEFINED, &heap); + offsets2 = rec_get_offsets(next_rec, index, offsets2, + n_cols, &heap); cmp_rec_rec_with_match(rec, next_rec, offsets1, offsets2, @@ -2856,8 +2884,8 @@ btr_estimate_number_of_different_key_vals( } } - offsets1 = rec_reget_offsets(rec, index, - offsets1, ULINT_UNDEFINED, heap); + offsets1 = rec_get_offsets(rec, index, offsets1, + ULINT_UNDEFINED, &heap); total_external_size += btr_rec_get_externally_stored_len(rec, offsets1); @@ -2901,7 +2929,9 @@ btr_estimate_number_of_different_key_vals( } mem_free(n_diff); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } /*================== EXTERNAL STORAGE OF BIG FIELDS ===================*/ diff --git a/innobase/btr/btr0pcur.c b/innobase/btr/btr0pcur.c index 7df8e53cd07..ad7613e0655 100644 --- a/innobase/btr/btr0pcur.c +++ b/innobase/btr/btr0pcur.c @@ -262,9 +262,10 @@ btr_pcur_restore_position( heap = mem_heap_create(256); offsets1 = rec_get_offsets(cursor->old_rec, - index, ULINT_UNDEFINED, heap); - offsets2 = rec_get_offsets(rec, - index, ULINT_UNDEFINED, heap); + index, NULL, + cursor->old_n_fields, &heap); + offsets2 = rec_get_offsets(rec, index, NULL, + cursor->old_n_fields, &heap); ut_ad(cmp_rec_rec(cursor->old_rec, rec, offsets1, offsets2, @@ -310,7 +311,7 @@ btr_pcur_restore_position( && 0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor), rec_get_offsets(btr_pcur_get_rec(cursor), btr_pcur_get_btr_cur(cursor)->index, - ULINT_UNDEFINED, heap))) { + NULL, ULINT_UNDEFINED, &heap))) { /* We have to store the NEW value for the modify clock, since the cursor can now be on a different page! But we can retain diff --git a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c index c18fa9a923d..dc712f650e7 100644 --- a/innobase/btr/btr0sea.c +++ b/innobase/btr/btr0sea.c @@ -419,7 +419,9 @@ btr_search_update_hash_ref( && (block->curr_n_fields == info->n_fields) && (block->curr_n_bytes == info->n_bytes) && (block->curr_side == info->side)) { - mem_heap_t* heap; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + rec = btr_cur_get_rec(cursor); if (!page_rec_is_user_rec(rec)) { @@ -428,11 +430,13 @@ btr_search_update_hash_ref( } tree_id = ((cursor->index)->tree)->id; - heap = mem_heap_create(100); fold = rec_fold(rec, rec_get_offsets(rec, cursor->index, - ULINT_UNDEFINED, heap), block->curr_n_fields, + offsets_, ULINT_UNDEFINED, &heap), + block->curr_n_fields, block->curr_n_bytes, tree_id); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } #ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX)); #endif /* UNIV_SYNC_DEBUG */ @@ -547,8 +551,10 @@ btr_search_check_guess( ulint match; ulint bytes; int cmp; - mem_heap_t* heap = mem_heap_create(100); - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; + ibool success = FALSE; n_unique = dict_index_get_n_unique_in_tree(cursor->index); @@ -560,47 +566,43 @@ btr_search_check_guess( match = 0; bytes = 0; - offsets = rec_get_offsets(rec, cursor->index, n_unique, heap); + offsets = rec_get_offsets(rec, cursor->index, offsets, + n_unique, &heap); cmp = page_cmp_dtuple_rec_with_match(tuple, rec, offsets, &match, &bytes); if (mode == PAGE_CUR_GE) { if (cmp == 1) { - mem_heap_free(heap); - return(FALSE); + goto exit_func; } cursor->up_match = match; if (match >= n_unique) { - mem_heap_free(heap); - return(TRUE); + success = TRUE; + goto exit_func; } } else if (mode == PAGE_CUR_LE) { if (cmp == -1) { - mem_heap_free(heap); - return(FALSE); + goto exit_func; } cursor->low_match = match; } else if (mode == PAGE_CUR_G) { if (cmp != -1) { - mem_heap_free(heap); - return(FALSE); + goto exit_func; } } else if (mode == PAGE_CUR_L) { if (cmp != 1) { - mem_heap_free(heap); - return(FALSE); + goto exit_func; } } if (can_only_compare_to_cursor_rec) { /* Since we could not determine if our guess is right just by looking at the record under the cursor, return FALSE */ - mem_heap_free(heap); - return(FALSE); + goto exit_func; } match = 0; @@ -613,28 +615,21 @@ btr_search_check_guess( prev_rec = page_rec_get_prev(rec); if (prev_rec == page_get_infimum_rec(page)) { - mem_heap_free(heap); - return(btr_page_get_prev(page, mtr) == FIL_NULL); + success = btr_page_get_prev(page, mtr) == FIL_NULL; + goto exit_func; } - offsets = rec_reget_offsets(prev_rec, cursor->index, - offsets, n_unique, heap); + offsets = rec_get_offsets(prev_rec, cursor->index, offsets, + n_unique, &heap); cmp = page_cmp_dtuple_rec_with_match(tuple, prev_rec, offsets, &match, &bytes); - mem_heap_free(heap); if (mode == PAGE_CUR_GE) { - if (cmp != 1) { - - return(FALSE); - } + success = cmp == 1; } else { - if (cmp == -1) { - - return(FALSE); - } + success = cmp != -1; } - return(TRUE); + goto exit_func; } ut_ad(rec != page_get_supremum_rec(page)); @@ -642,39 +637,30 @@ btr_search_check_guess( next_rec = page_rec_get_next(rec); if (next_rec == page_get_supremum_rec(page)) { - mem_heap_free(heap); - if (btr_page_get_next(page, mtr) == FIL_NULL) { cursor->up_match = 0; - - return(TRUE); + success = TRUE; } - return(FALSE); + goto exit_func; } - offsets = rec_reget_offsets(next_rec, cursor->index, - offsets, n_unique, heap); + offsets = rec_get_offsets(next_rec, cursor->index, offsets, + n_unique, &heap); cmp = page_cmp_dtuple_rec_with_match(tuple, next_rec, offsets, &match, &bytes); - mem_heap_free(heap); - if (mode == PAGE_CUR_LE) { - if (cmp != -1) { - - return(FALSE); - } - + success = cmp == -1; cursor->up_match = match; } else { - if (cmp == 1) { - - return(FALSE); - } + success = cmp != 1; } - - return(TRUE); +exit_func: + if (heap) { + mem_heap_free(heap); + } + return(success); } /********************************************************************** @@ -997,14 +983,14 @@ btr_search_drop_page_hash_index( prev_fold = 0; - heap = mem_heap_create(100); + heap = NULL; offsets = NULL; while (rec != sup) { /* FIXME: in a mixed tree, not all records may have enough ordering fields: */ - offsets = rec_reget_offsets(rec, block->index, - offsets, n_fields + (n_bytes > 0), heap); + offsets = rec_get_offsets(rec, block->index, + offsets, n_fields + (n_bytes > 0), &heap); fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id); if (fold == prev_fold && prev_fold != 0) { @@ -1022,7 +1008,9 @@ next_rec: prev_fold = fold; } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } rw_lock_x_lock(&btr_search_latch); @@ -1109,8 +1097,9 @@ btr_search_build_page_hash_index( ulint* folds; rec_t** recs; ulint i; - mem_heap_t* heap; - ulint* offsets; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_ad(index); @@ -1161,7 +1150,6 @@ btr_search_build_page_hash_index( folds = mem_alloc(n_recs * sizeof(ulint)); recs = mem_alloc(n_recs * sizeof(rec_t*)); - heap = mem_heap_create(100); n_cached = 0; @@ -1172,7 +1160,8 @@ btr_search_build_page_hash_index( rec = page_get_infimum_rec(page); rec = page_rec_get_next(rec); - offsets = rec_get_offsets(rec, index, n_fields + (n_bytes > 0), heap); + offsets = rec_get_offsets(rec, index, offsets, + n_fields + (n_bytes > 0), &heap); if (rec != sup) { ut_a(n_fields <= rec_offs_n_fields(offsets)); @@ -1208,8 +1197,8 @@ btr_search_build_page_hash_index( break; } - offsets = rec_reget_offsets(next_rec, index, - offsets, n_fields + (n_bytes > 0), heap); + offsets = rec_get_offsets(next_rec, index, offsets, + n_fields + (n_bytes > 0), &heap); next_fold = rec_fold(next_rec, offsets, n_fields, n_bytes, tree_id); @@ -1260,7 +1249,9 @@ exit_func: mem_free(folds); mem_free(recs); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } /************************************************************************ @@ -1350,7 +1341,8 @@ btr_search_update_hash_on_delete( ulint fold; dulint tree_id; ibool found; - mem_heap_t* heap; + ulint offsets_[100] = { 100, }; + mem_heap_t* heap = NULL; rec = btr_cur_get_rec(cursor); @@ -1371,11 +1363,12 @@ btr_search_update_hash_on_delete( table = btr_search_sys->hash_index; tree_id = cursor->index->tree->id; - heap = mem_heap_create(100); - fold = rec_fold(rec, rec_get_offsets(rec, cursor->index, - ULINT_UNDEFINED, heap), block->curr_n_fields, + fold = rec_fold(rec, rec_get_offsets(rec, cursor->index, offsets_, + ULINT_UNDEFINED, &heap), block->curr_n_fields, block->curr_n_bytes, tree_id); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } rw_lock_x_lock(&btr_search_latch); found = ha_search_and_delete_if_found(table, fold, rec); @@ -1457,9 +1450,10 @@ btr_search_update_hash_on_insert( ulint n_fields; ulint n_bytes; ulint side; - ibool locked = FALSE; - mem_heap_t* heap; - ulint* offsets; + ibool locked = FALSE; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; table = btr_search_sys->hash_index; @@ -1490,21 +1484,20 @@ btr_search_update_hash_on_insert( next_rec = page_rec_get_next(ins_rec); page = buf_frame_align(rec); - heap = mem_heap_create(100); - offsets = rec_get_offsets(ins_rec, cursor->index, - ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(ins_rec, cursor->index, offsets, + ULINT_UNDEFINED, &heap); ins_fold = rec_fold(ins_rec, offsets, n_fields, n_bytes, tree_id); if (next_rec != page_get_supremum_rec(page)) { - offsets = rec_reget_offsets(next_rec, cursor->index, - offsets, n_fields + (n_bytes > 0), heap); + offsets = rec_get_offsets(next_rec, cursor->index, offsets, + n_fields + (n_bytes > 0), &heap); next_fold = rec_fold(next_rec, offsets, n_fields, n_bytes, tree_id); } if (rec != page_get_infimum_rec(page)) { - offsets = rec_reget_offsets(rec, cursor->index, - offsets, n_fields + (n_bytes > 0), heap); + offsets = rec_get_offsets(rec, cursor->index, offsets, + n_fields + (n_bytes > 0), &heap); fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id); } else { if (side == BTR_SEARCH_LEFT_SIDE) { @@ -1575,7 +1568,9 @@ check_next_rec: } function_exit: - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } if (locked) { rw_lock_x_unlock(&btr_search_latch); } @@ -1595,8 +1590,9 @@ btr_search_validate(void) ulint n_page_dumps = 0; ibool ok = TRUE; ulint i; - mem_heap_t* heap = mem_heap_create(100); - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; rw_lock_x_lock(&btr_search_latch); @@ -1606,10 +1602,10 @@ btr_search_validate(void) while (node != NULL) { block = buf_block_align(node->data); page = buf_frame_align(node->data); - offsets = rec_reget_offsets((rec_t*) node->data, + offsets = rec_get_offsets((rec_t*) node->data, block->index, offsets, block->curr_n_fields - + (block->curr_n_bytes > 0), heap); + + (block->curr_n_bytes > 0), &heap); if (!block->is_hashed || node->fold != rec_fold((rec_t*)(node->data), @@ -1635,7 +1631,8 @@ btr_search_validate(void) btr_page_get_index_id(page))); fputs("InnoDB: Record ", stderr); - rec_print(stderr, (rec_t*)node->data, offsets); + rec_print_new(stderr, (rec_t*)node->data, + offsets); fprintf(stderr, "\nInnoDB: on that page." "Page mem address %p, is hashed %lu, n fields %lu, n bytes %lu\n" "side %lu\n", @@ -1659,7 +1656,9 @@ btr_search_validate(void) } rw_lock_x_unlock(&btr_search_latch); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(ok); } diff --git a/innobase/include/rem0rec.h b/innobase/include/rem0rec.h index d450df82311..ab89b912523 100644 --- a/innobase/include/rem0rec.h +++ b/innobase/include/rem0rec.h @@ -67,6 +67,16 @@ rec_get_n_fields_old( /* out: number of data fields */ rec_t* rec); /* in: physical record */ /********************************************************** +The following function is used to get the number of fields +in a record. */ +UNIV_INLINE +ulint +rec_get_n_fields( +/*=============*/ + /* out: number of data fields */ + rec_t* rec, /* in: physical record */ + dict_index_t* index); /* in: record descriptor */ +/********************************************************** The following function is used to get the number of records owned by the previous directory record. */ UNIV_INLINE @@ -188,45 +198,28 @@ rec_get_1byte_offs_flag( rec_t* rec); /* in: physical record */ /********************************************************** The following function determines the offsets to each field -in the record. The offsets are returned in an array of -ulint, with [0] being the number of fields (n), [1] being the -extra size (if REC_OFFS_COMPACT is set, the record is in the new -format), and [2]..[n+1] being the offsets past the end of -fields 0..n, or to the beginning of fields 1..n+1. When the -high-order bit of the offset at [n+1] is set (REC_OFFS_SQL_NULL), -the field n is NULL. When the second high-order bit of the offset -at [n+1] is set (REC_OFFS_EXTERNAL), the field n is being stored -externally. */ - -ulint* -rec_get_offsets( -/*============*/ - /* out: the offsets */ - rec_t* rec, /* in: physical record */ - dict_index_t* index, /* in: record descriptor */ - ulint n_fields,/* in: maximum number of initialized fields - (ULINT_UNDEFINED if all fields) */ - mem_heap_t* heap); /* in: memory heap */ -/********************************************************** -The following function determines the offsets to each field -in the record. It differs from rec_get_offsets() by trying to -reuse a previously returned array. */ +in the record. It can reuse a previously allocated array. */ ulint* -rec_reget_offsets( -/*==============*/ +rec_get_offsets_func( +/*=================*/ /* out: the new offsets */ rec_t* rec, /* in: physical record */ dict_index_t* index, /* in: record descriptor */ - ulint* offsets,/* in: array of offsets - from rec_get_offsets() - or rec_reget_offsets(), or NULL */ + ulint* offsets,/* in: array consisting of offsets[0] + allocated elements, or an array from + rec_get_offsets(), or NULL */ ulint n_fields,/* in: maximum number of initialized fields (ULINT_UNDEFINED if all fields) */ - mem_heap_t* heap); /* in: memory heap */ + mem_heap_t** heap, /* in/out: memory heap */ + const char* file, /* in: file name where called */ + ulint line); /* in: line number where called */ + +#define rec_get_offsets(rec,index,offsets,n,heap) \ + rec_get_offsets_func(rec,index,offsets,n,heap,__FILE__,__LINE__) /**************************************************************** -Validates offsets returned by rec_get_offsets() or rec_reget_offsets(). */ +Validates offsets returned by rec_get_offsets(). */ UNIV_INLINE ibool rec_offs_validate( @@ -234,8 +227,7 @@ rec_offs_validate( /* out: TRUE if valid */ rec_t* rec, /* in: record or NULL */ dict_index_t* index, /* in: record descriptor or NULL */ - const ulint* offsets);/* in: array returned by rec_get_offsets() - or rec_reget_offsets() */ + const ulint* offsets);/* in: array returned by rec_get_offsets() */ /**************************************************************** Updates debug data in offsets, in order to avoid bogus rec_offs_validate() failures. */ @@ -243,10 +235,9 @@ UNIV_INLINE void rec_offs_make_valid( /*================*/ - const rec_t* rec, /* in: record */ - const dict_index_t* index,/* in: record descriptor */ - ulint* offsets);/* in: array returned by rec_get_offsets() - or rec_reget_offsets() */ + rec_t* rec, /* in: record */ + dict_index_t* index,/* in: record descriptor */ + ulint* offsets);/* in: array returned by rec_get_offsets() */ /**************************************************************** The following function is used to get a pointer to the nth @@ -551,7 +542,15 @@ rec_print_old( /*==========*/ FILE* file, /* in: file where to print */ rec_t* rec); /* in: physical record */ +/******************************************************************* +Prints a physical record. */ +void +rec_print_new( +/*==========*/ + FILE* file, /* in: file where to print */ + rec_t* rec, /* in: physical record */ + const ulint* offsets);/* in: array returned by rec_get_offsets() */ /******************************************************************* Prints a physical record. */ @@ -560,7 +559,7 @@ rec_print( /*======*/ FILE* file, /* in: file where to print */ rec_t* rec, /* in: physical record */ - const ulint* offsets);/* in: array returned by rec_get_offsets() */ + dict_index_t* index); /* in: record descriptor */ #define REC_INFO_BITS 6 /* This is single byte bit-field */ diff --git a/innobase/include/rem0rec.ic b/innobase/include/rem0rec.ic index 8443b5fa07d..db938aa9fa5 100644 --- a/innobase/include/rem0rec.ic +++ b/innobase/include/rem0rec.ic @@ -681,9 +681,11 @@ rec_2_get_field_end_info( } #ifdef UNIV_DEBUG -# define REC_OFFS_HEADER_SIZE 3 +/* Length of the rec_get_offsets() header */ +# define REC_OFFS_HEADER_SIZE 4 #else /* UNIV_DEBUG */ -# define REC_OFFS_HEADER_SIZE 1 +/* Length of the rec_get_offsets() header */ +# define REC_OFFS_HEADER_SIZE 2 #endif /* UNIV_DEBUG */ /* Get the base address of offsets. The extra_size is stored at @@ -691,8 +693,40 @@ this position, and following positions hold the end offsets of the fields. */ #define rec_offs_base(offsets) (offsets + REC_OFFS_HEADER_SIZE) +/************************************************************** +The following function returns the number of allocated elements +for an array of offsets. */ +UNIV_INLINE +ulint +rec_offs_get_n_alloc( +/*=================*/ + /* out: number of elements */ + const ulint* offsets)/* in: array for rec_get_offsets() */ +{ + ulint n_alloc; + ut_ad(offsets); + n_alloc = offsets[0]; + ut_ad(n_alloc > 0); + return(n_alloc); +} + +/************************************************************** +The following function sets the number of allocated elements +for an array of offsets. */ +UNIV_INLINE +void +rec_offs_set_n_alloc( +/*=================*/ + ulint* offsets, /* in: array for rec_get_offsets() */ + ulint n_alloc) /* in: number of elements */ +{ + ut_ad(offsets); + ut_ad(n_alloc > 0); + offsets[0] = n_alloc; +} + /**************************************************************** -Validates offsets returned by rec_get_offsets() or rec_reget_offsets(). */ +Validates offsets returned by rec_get_offsets(). */ UNIV_INLINE ibool rec_offs_validate( @@ -705,16 +739,16 @@ rec_offs_validate( ulint i = rec_offs_n_fields(offsets); ulint last = ULINT_MAX; ibool comp = (*rec_offs_base(offsets) & REC_OFFS_COMPACT) != 0; - ut_a(offsets); + if (rec) { - ut_ad((ulint) rec == offsets[1]); + ut_ad((ulint) rec == offsets[2]); if (!comp) { ut_a(rec_get_n_fields_old(rec) >= i); } } if (index) { ulint max_n_fields; - ut_ad((ulint) index == offsets[2]); + ut_ad((ulint) index == offsets[3]); max_n_fields = ut_max( dict_index_get_n_fields(index), dict_index_get_n_unique_in_tree(index) + 1); @@ -734,7 +768,9 @@ rec_offs_validate( ut_error; } } - ut_a(i <= max_n_fields); + /* index->n_def == 0 for dummy indexes if !comp */ + ut_a(!comp || index->n_def); + ut_a(!index->n_def || i <= max_n_fields); } while (i--) { ulint curr = rec_offs_base(offsets)[1 + i] & REC_OFFS_MASK; @@ -750,17 +786,17 @@ UNIV_INLINE void rec_offs_make_valid( /*================*/ - const rec_t* rec __attribute__((unused)), + rec_t* rec __attribute__((unused)), /* in: record */ - const dict_index_t* index __attribute__((unused)), + dict_index_t* index __attribute__((unused)), /* in: record descriptor */ ulint* offsets __attribute__((unused))) - /* in: array returned by rec_get_offsets() - or rec_reget_offsets() */ + /* in: array returned by rec_get_offsets() */ { #ifdef UNIV_DEBUG - offsets[1] = (ulint) rec; - offsets[2] = (ulint) index; + ut_ad(rec_get_n_fields(rec, index) >= rec_offs_n_fields(offsets)); + offsets[2] = (ulint) rec; + offsets[3] = (ulint) index; #endif /* UNIV_DEBUG */ } @@ -1146,12 +1182,31 @@ rec_offs_n_fields( { ulint n_fields; ut_ad(offsets); - n_fields = offsets[0]; + n_fields = offsets[1]; ut_ad(n_fields > 0); ut_ad(n_fields <= REC_MAX_N_FIELDS); + ut_ad(n_fields + REC_OFFS_HEADER_SIZE + <= rec_offs_get_n_alloc(offsets)); return(n_fields); } +/************************************************************** +The following function sets the number of fields in offsets. */ +UNIV_INLINE +void +rec_offs_set_n_fields( +/*==================*/ + ulint* offsets, /* in: array returned by rec_get_offsets() */ + ulint n_fields) /* in: number of fields */ +{ + ut_ad(offsets); + ut_ad(n_fields > 0); + ut_ad(n_fields <= REC_MAX_N_FIELDS); + ut_ad(n_fields + REC_OFFS_HEADER_SIZE + <= rec_offs_get_n_alloc(offsets)); + offsets[1] = n_fields; +} + /************************************************************** The following function returns the data size of a physical record, that is the sum of field lengths. SQL null fields diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index d2d16a1ae4e..961210dbd06 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -424,7 +424,7 @@ lock_check_trx_id_sanity( /* out: TRUE if ok */ dulint trx_id, /* in: trx id */ rec_t* rec, /* in: user record */ - dict_index_t* index, /* in: clustered index */ + dict_index_t* index, /* in: index */ const ulint* offsets, /* in: rec_get_offsets(rec, index) */ ibool has_kernel_mutex)/* in: TRUE if the caller owns the kernel mutex */ @@ -445,7 +445,7 @@ lock_check_trx_id_sanity( fputs(" InnoDB: Error: transaction id associated" " with record\n", stderr); - rec_print(stderr, rec, offsets); + rec_print_new(stderr, rec, offsets); fputs("InnoDB: in ", stderr); dict_index_name_print(stderr, NULL, index); fprintf(stderr, "\n" @@ -4073,10 +4073,9 @@ lock_rec_print( ulint page_no; ulint i; mtr_t mtr; - mem_heap_t* heap; - ulint* offsets = NULL; - - heap = mem_heap_create(100); + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); @@ -4157,9 +4156,9 @@ lock_rec_print( if (page) { rec_t* rec = page_find_rec_with_heap_no(page, i); - offsets = rec_reget_offsets(rec, lock->index, - offsets, ULINT_UNDEFINED, heap); - rec_print(file, rec, offsets); + offsets = rec_get_offsets(rec, lock->index, + offsets, ULINT_UNDEFINED, &heap); + rec_print_new(file, rec, offsets); } putc('\n', file); @@ -4167,9 +4166,11 @@ lock_rec_print( } mtr_commit(&mtr); - mem_heap_free(heap); -} - + if (heap) { + mem_heap_free(heap); + } +} + /************************************************************************* Calculates the number of record lock structs in the record lock hash table. */ static @@ -4562,12 +4563,13 @@ lock_rec_validate_page( page_t* page; lock_t* lock; rec_t* rec; - ulint nth_lock = 0; - ulint nth_bit = 0; + ulint nth_lock = 0; + ulint nth_bit = 0; ulint i; mtr_t mtr; - mem_heap_t* heap = mem_heap_create(100); - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; #ifdef UNIV_SYNC_DEBUG ut_ad(!mutex_own(&kernel_mutex)); @@ -4607,8 +4609,8 @@ loop: index = lock->index; rec = page_find_rec_with_heap_no(page, i); - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); fprintf(stderr, "Validating %lu %lu\n", (ulong) space, (ulong) page_no); @@ -4635,7 +4637,9 @@ function_exit: mtr_commit(&mtr); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(TRUE); } @@ -4811,11 +4815,15 @@ lock_rec_insert_check_and_lock( #ifdef UNIV_DEBUG { - mem_heap_t* heap = mem_heap_create(100); - const ulint* offsets = rec_get_offsets(next_rec, index, - ULINT_UNDEFINED, heap); + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + const ulint* offsets = rec_get_offsets( + next_rec, index, offsets_, + ULINT_UNDEFINED, &heap); ut_ad(lock_rec_queue_validate(next_rec, index, offsets)); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } #endif /* UNIV_DEBUG */ @@ -4954,11 +4962,14 @@ lock_sec_rec_modify_check_and_lock( #ifdef UNIV_DEBUG { - mem_heap_t* heap = mem_heap_create(100); - const ulint* offsets = rec_get_offsets(rec, index, - ULINT_UNDEFINED, heap); + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + const ulint* offsets = rec_get_offsets( + rec, index, offsets_, ULINT_UNDEFINED, &heap); ut_ad(lock_rec_queue_validate(rec, index, offsets)); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } #endif /* UNIV_DEBUG */ @@ -5067,7 +5078,6 @@ lock_clust_rec_read_check_and_lock( ut_ad(page_rec_is_user_rec(rec) || page_rec_is_supremum(rec)); ut_ad(gap_mode == LOCK_ORDINARY || gap_mode == LOCK_GAP || gap_mode == LOCK_REC_NOT_GAP); - ut_ad(index->type & DICT_CLUSTERED); ut_ad(rec_offs_validate(rec, index, offsets)); if (flags & BTR_NO_LOCKING_FLAG) { diff --git a/innobase/page/page0cur.c b/innobase/page/page0cur.c index 8def8474d9a..53c3c573b8e 100644 --- a/innobase/page/page0cur.c +++ b/innobase/page/page0cur.c @@ -29,6 +29,7 @@ UNIV_INLINE ibool page_cur_try_search_shortcut( /*=========================*/ + /* out: TRUE on success */ page_t* page, /* in: index page */ dict_index_t* index, /* in: record descriptor */ dtuple_t* tuple, /* in: data tuple */ @@ -56,14 +57,15 @@ page_cur_try_search_shortcut( #ifdef UNIV_SEARCH_DEBUG page_cur_t cursor2; #endif - mem_heap_t* heap; - ulint* offsets; + ibool success = FALSE; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_ad(dtuple_check_typed(tuple)); rec = page_header_get_ptr(page, PAGE_LAST_INSERT); - heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, index, - dtuple_get_n_fields(tuple), heap); + offsets = rec_get_offsets(rec, index, offsets, + dtuple_get_n_fields(tuple), &heap); ut_ad(rec); ut_ad(page_rec_is_user_rec(rec)); @@ -78,21 +80,17 @@ page_cur_try_search_shortcut( cmp = page_cmp_dtuple_rec_with_match(tuple, rec, offsets, &low_match, &low_bytes); if (cmp == -1) { - - mem_heap_free(heap); - return(FALSE); + goto exit_func; } next_rec = page_rec_get_next(rec); - offsets = rec_reget_offsets(next_rec, index, offsets, - dtuple_get_n_fields(tuple), heap); + offsets = rec_get_offsets(next_rec, index, offsets, + dtuple_get_n_fields(tuple), &heap); cmp = page_cmp_dtuple_rec_with_match(tuple, next_rec, offsets, &up_match, &up_bytes); if (cmp != -1) { - - mem_heap_free(heap); - return(FALSE); + goto exit_func; } cursor->rec = rec; @@ -127,8 +125,12 @@ page_cur_try_search_shortcut( #ifdef UNIV_SEARCH_PERF_STAT page_cur_short_succ++; #endif - mem_heap_free(heap); - return(TRUE); + success = TRUE; +exit_func: + if (heap) { + mem_heap_free(heap); + } + return(success); } #endif @@ -226,8 +228,9 @@ page_cur_search_with_match( ulint dbg_matched_fields; ulint dbg_matched_bytes; #endif - mem_heap_t* heap; - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_ad(page && tuple && iup_matched_fields && iup_matched_bytes && ilow_matched_fields && ilow_matched_bytes && cursor); @@ -262,8 +265,6 @@ page_cur_search_with_match( /*#endif */ #endif - heap = mem_heap_create(100); - /* The following flag does not work for non-latin1 char sets because cmp_full_field does not tell how many bytes matched */ ut_a(mode != PAGE_CUR_LE_OR_EXTENDS); @@ -298,8 +299,8 @@ page_cur_search_with_match( low_matched_fields, low_matched_bytes, up_matched_fields, up_matched_bytes); - offsets = rec_reget_offsets(mid_rec, index, offsets, - dtuple_get_n_fields_cmp(tuple), heap); + offsets = rec_get_offsets(mid_rec, index, offsets, + dtuple_get_n_fields_cmp(tuple), &heap); cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets, &cur_matched_fields, @@ -310,8 +311,8 @@ page_cur_search_with_match( low_matched_bytes = cur_matched_bytes; } else if (cmp == -1) { - offsets = rec_reget_offsets(mid_rec, index, - offsets, dtuple_get_n_fields_cmp(tuple), heap); + offsets = rec_get_offsets(mid_rec, index, offsets, + dtuple_get_n_fields_cmp(tuple), &heap); if (mode == PAGE_CUR_LE_OR_EXTENDS && page_cur_rec_field_extends(tuple, mid_rec, @@ -353,8 +354,8 @@ page_cur_search_with_match( low_matched_fields, low_matched_bytes, up_matched_fields, up_matched_bytes); - offsets = rec_reget_offsets(mid_rec, index, - offsets, dtuple_get_n_fields_cmp(tuple), heap); + offsets = rec_get_offsets(mid_rec, index, offsets, + dtuple_get_n_fields_cmp(tuple), &heap); cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets, &cur_matched_fields, @@ -365,8 +366,8 @@ page_cur_search_with_match( low_matched_bytes = cur_matched_bytes; } else if (cmp == -1) { - offsets = rec_reget_offsets(mid_rec, index, - offsets, dtuple_get_n_fields_cmp(tuple), heap); + offsets = rec_get_offsets(mid_rec, index, offsets, + dtuple_get_n_fields_cmp(tuple), &heap); if (mode == PAGE_CUR_LE_OR_EXTENDS && page_cur_rec_field_extends(tuple, mid_rec, @@ -398,8 +399,8 @@ page_cur_search_with_match( dbg_matched_fields = 0; dbg_matched_bytes = 0; - offsets = rec_reget_offsets(low_rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(low_rec, index, offsets, + ULINT_UNDEFINED, &heap); dbg_cmp = page_cmp_dtuple_rec_with_match(tuple, low_rec, offsets, &dbg_matched_fields, &dbg_matched_bytes); @@ -422,8 +423,8 @@ page_cur_search_with_match( dbg_matched_fields = 0; dbg_matched_bytes = 0; - offsets = rec_reget_offsets(up_rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(up_rec, index, offsets, + ULINT_UNDEFINED, &heap); dbg_cmp = page_cmp_dtuple_rec_with_match(tuple, up_rec, offsets, &dbg_matched_fields, &dbg_matched_bytes); @@ -453,7 +454,9 @@ page_cur_search_with_match( *iup_matched_bytes = up_matched_bytes; *ilow_matched_fields = low_matched_fields; *ilow_matched_bytes = low_matched_bytes; - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } /*************************************************************** @@ -519,22 +522,26 @@ page_cur_insert_rec_write_log( ut_a(rec_size < UNIV_PAGE_SIZE); { - mem_heap_t* heap; + mem_heap_t* heap = NULL; + ulint cur_offs_[100] = { 100, }; + ulint ins_offs_[100] = { 100, }; + ulint* cur_offs; ulint* ins_offs; - heap = mem_heap_create(100); - cur_offs = rec_get_offsets(cursor_rec, index, - ULINT_UNDEFINED, heap); - ins_offs = rec_get_offsets(insert_rec, index, - ULINT_UNDEFINED, heap); + cur_offs = rec_get_offsets(cursor_rec, index, cur_offs_, + ULINT_UNDEFINED, &heap); + ins_offs = rec_get_offsets(insert_rec, index, ins_offs_, + ULINT_UNDEFINED, &heap); extra_size = rec_offs_extra_size(ins_offs); cur_extra_size = rec_offs_extra_size(cur_offs); ut_ad(rec_size == rec_offs_size(ins_offs)); cur_rec_size = rec_offs_size(cur_offs); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } ins_ptr = insert_rec - extra_size; @@ -668,8 +675,9 @@ page_cur_parse_insert_rec( byte* ptr2 = ptr; ulint info_bits = 0; /* remove warning */ page_cur_t cursor; - mem_heap_t* heap; - ulint* offsets; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; if (!is_short) { /* Read the cursor rec offset as a 2-byte ulint */ @@ -756,8 +764,8 @@ page_cur_parse_insert_rec( cursor_rec = page + offset; } - heap = mem_heap_create(100); - offsets = rec_get_offsets(cursor_rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(cursor_rec, index, offsets, + ULINT_UNDEFINED, &heap); if (extra_info_yes == 0) { info_bits = rec_get_info_bits(cursor_rec, index->table->comp); @@ -816,6 +824,10 @@ page_cur_parse_insert_rec( mem_free(buf); } + if (heap) { + mem_heap_free(heap); + } + return(ptr + end_seg_len); } @@ -850,8 +862,9 @@ page_cur_insert_rec_low( inserted record */ rec_t* owner_rec; ulint n_owned; - mem_heap_t* heap; - ulint* offsets; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ibool comp = index->table->comp; ut_ad(cursor && mtr); @@ -865,14 +878,12 @@ page_cur_insert_rec_low( ut_ad(cursor->rec != page_get_supremum_rec(page)); - heap = mem_heap_create(100); - /* 1. Get the size of the physical record in the page */ if (tuple != NULL) { - offsets = NULL; rec_size = rec_get_converted_size(index, tuple); } else { - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); rec_size = rec_offs_size(offsets); } @@ -880,7 +891,9 @@ page_cur_insert_rec_low( insert_buf = page_mem_alloc(page, rec_size, index, &heap_no); if (insert_buf == NULL) { - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(NULL); } @@ -888,13 +901,15 @@ page_cur_insert_rec_low( if (tuple != NULL) { insert_rec = rec_convert_dtuple_to_rec(insert_buf, index, tuple); + offsets = rec_get_offsets(insert_rec, index, offsets, + ULINT_UNDEFINED, &heap); } else { insert_rec = rec_copy(insert_buf, rec, offsets); + ut_ad(rec_offs_validate(rec, index, offsets)); + rec_offs_make_valid(insert_rec, index, offsets); } ut_ad(insert_rec); - offsets = rec_reget_offsets(insert_rec, index, - offsets, ULINT_UNDEFINED, heap); ut_ad(rec_size == rec_offs_size(offsets)); /* 4. Insert the record in the linked list of records */ @@ -966,7 +981,9 @@ page_cur_insert_rec_low( page_cur_insert_rec_write_log(insert_rec, rec_size, current_rec, index, mtr); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(insert_rec); } @@ -1068,9 +1085,10 @@ page_copy_rec_list_end_to_created_page( ulint log_mode; byte* log_ptr; ulint log_data_len; - ibool comp = page_is_comp(page); - mem_heap_t* heap; - ulint* offsets = NULL; + ibool comp = page_is_comp(page); + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_ad(page_dir_get_n_heap(new_page) == 2); ut_ad(page != new_page); @@ -1117,8 +1135,8 @@ page_copy_rec_list_end_to_created_page( /* should be do ... until, comment by Jani */ while (rec != page_get_supremum_rec(page)) { - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); insert_rec = rec_copy(heap_top, rec, offsets); rec_set_next_offs(prev_rec, comp, insert_rec - new_page); @@ -1170,7 +1188,9 @@ page_copy_rec_list_end_to_created_page( slot_index--; } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } log_data_len = dyn_array_get_data_size(&(mtr->log)) - log_data_len; diff --git a/innobase/page/page0page.c b/innobase/page/page0page.c index 38b1e503c8f..67c7bd936d1 100644 --- a/innobase/page/page0page.c +++ b/innobase/page/page0page.c @@ -227,10 +227,12 @@ page_mem_alloc( rec = page_header_get_ptr(page, PAGE_FREE); if (rec) { - mem_heap_t* heap - = mem_heap_create(100); - const ulint* offsets - = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; + + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); if (rec_offs_size(offsets) >= need) { page_header_set_ptr(page, PAGE_FREE, @@ -245,11 +247,15 @@ page_mem_alloc( *heap_no = rec_get_heap_no(rec, page_is_comp(page)); block = rec_get_start(rec, offsets); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(block); } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } /* Could not find space from the free list, try top of heap */ @@ -374,7 +380,8 @@ page_create( rec_set_n_owned(infimum_rec, comp, 1); rec_set_heap_no(infimum_rec, comp, 0); - offsets = rec_get_offsets(infimum_rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(infimum_rec, index, NULL, + ULINT_UNDEFINED, &heap); heap_top = rec_get_end(infimum_rec, offsets); @@ -396,8 +403,8 @@ page_create( rec_set_n_owned(supremum_rec, comp, 1); rec_set_heap_no(supremum_rec, comp, 1); - offsets = rec_reget_offsets(supremum_rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(supremum_rec, index, offsets, + ULINT_UNDEFINED, &heap); heap_top = rec_get_end(supremum_rec, offsets); ut_ad(heap_top == @@ -711,8 +718,9 @@ page_delete_rec_list_end( last_rec = page_rec_get_prev(sup); if ((size == ULINT_UNDEFINED) || (n_recs == ULINT_UNDEFINED)) { - mem_heap_t* heap = mem_heap_create(100); - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; /* Calculate the sum of sizes and the number of records */ size = 0; n_recs = 0; @@ -720,8 +728,8 @@ page_delete_rec_list_end( while (rec2 != sup) { ulint s; - offsets = rec_reget_offsets(rec2, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec2, index, offsets, + ULINT_UNDEFINED, &heap); s = rec_offs_size(offsets); ut_ad(rec2 - page + s - rec_offs_extra_size(offsets) < UNIV_PAGE_SIZE); @@ -732,7 +740,9 @@ page_delete_rec_list_end( rec2 = page_rec_get_next(rec2); } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } ut_ad(size < UNIV_PAGE_SIZE); @@ -1213,7 +1223,7 @@ page_rec_print( ibool comp = page_is_comp(buf_frame_align(rec)); ut_a(comp == rec_offs_comp(offsets)); - rec_print(stderr, rec, offsets); + rec_print_new(stderr, rec, offsets); fprintf(stderr, " n_owned: %lu; heap_no: %lu; next rec: %lu\n", (ulong) rec_get_n_owned(rec, comp), @@ -1276,11 +1286,11 @@ page_print_list( page_cur_t cur; ulint count; ulint n_recs; - mem_heap_t* heap; - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_a(page_is_comp(page) == index->table->comp); - heap = mem_heap_create(100); fprintf(stderr, "--------------------------------\n" @@ -1292,8 +1302,8 @@ page_print_list( page_cur_set_before_first(page, &cur); count = 0; for (;;) { - offsets = rec_reget_offsets(cur.rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(cur.rec, index, offsets, + ULINT_UNDEFINED, &heap); page_rec_print(cur.rec, offsets); if (count == pr_n) { @@ -1314,8 +1324,8 @@ page_print_list( page_cur_move_to_next(&cur); if (count + pr_n >= n_recs) { - offsets = rec_reget_offsets(cur.rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(cur.rec, index, offsets, + ULINT_UNDEFINED, &heap); page_rec_print(cur.rec, offsets); } count++; @@ -1326,7 +1336,9 @@ page_print_list( "--------------------------------\n", (ulong) (count + 1)); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } /******************************************************************* @@ -1680,7 +1692,7 @@ page_validate( goto func_exit2; } - heap = mem_heap_create(UNIV_PAGE_SIZE); + heap = mem_heap_create(UNIV_PAGE_SIZE + 200); /* The following buffer is used to check that the records in the page record heap do not overlap */ @@ -1720,8 +1732,8 @@ page_validate( for (;;) { rec = cur.rec; - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); if (comp && page_rec_is_user_rec(rec) && rec_get_node_ptr_flag(rec) @@ -1744,9 +1756,9 @@ page_validate( (ulong) buf_frame_get_page_no(page)); dict_index_name_print(stderr, NULL, index); fputs("\nInnoDB: previous record ", stderr); - rec_print(stderr, old_rec, old_offsets); + rec_print_new(stderr, old_rec, old_offsets); fputs("\nInnoDB: record ", stderr); - rec_print(stderr, rec, offsets); + rec_print_new(stderr, rec, offsets); putc('\n', stderr); goto func_exit; @@ -1852,8 +1864,8 @@ page_validate( rec = page_header_get_ptr(page, PAGE_FREE); while (rec != NULL) { - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); if (!page_rec_validate(rec, offsets)) { goto func_exit; diff --git a/innobase/rem/rem0rec.c b/innobase/rem/rem0rec.c index e4fa213480f..74876ad9402 100644 --- a/innobase/rem/rem0rec.c +++ b/innobase/rem/rem0rec.c @@ -284,28 +284,25 @@ rec_init_offsets( /********************************************************** The following function determines the offsets to each field -in the record. The offsets are returned in an array of -ulint, with [0] being the number of fields (n), [1] being the -extra size (if REC_OFFS_COMPACT is set, the record is in the new -format), and [2]..[n+1] being the offsets past the end of -fields 0..n, or to the beginning of fields 1..n+1. When the -high-order bit of the offset at [n+1] is set (REC_OFFS_SQL_NULL), -the field n is NULL. When the second high-order bit of the offset -at [n+1] is set (REC_OFFS_EXTERNAL), the field n is being stored -externally. */ +in the record. It can reuse a previously returned array. */ ulint* -rec_get_offsets( -/*============*/ - /* out: the offsets */ +rec_get_offsets_func( +/*=================*/ + /* out: the new offsets */ rec_t* rec, /* in: physical record */ dict_index_t* index, /* in: record descriptor */ + ulint* offsets,/* in: array consisting of offsets[0] + allocated elements, or an array from + rec_get_offsets(), or NULL */ ulint n_fields,/* in: maximum number of initialized fields (ULINT_UNDEFINED if all fields) */ - mem_heap_t* heap) /* in: memory heap */ + mem_heap_t** heap, /* in/out: memory heap */ + const char* file, /* in: file name where called */ + ulint line) /* in: line number where called */ { - ulint* offsets; ulint n; + ulint size; ut_ad(rec); ut_ad(index); @@ -336,71 +333,18 @@ rec_get_offsets( n = n_fields; } - offsets = mem_heap_alloc(heap, - (n + (1 + REC_OFFS_HEADER_SIZE)) * sizeof(ulint)); - - offsets[0] = n; - - rec_init_offsets(rec, index, offsets); - return(offsets); -} - -/********************************************************** -The following function determines the offsets to each field -in the record. It differs from rec_get_offsets() by trying to -reuse a previously returned array. */ - -ulint* -rec_reget_offsets( -/*==============*/ - /* out: the new offsets */ - rec_t* rec, /* in: physical record */ - dict_index_t* index, /* in: record descriptor */ - ulint* offsets,/* in: array of offsets - from rec_get_offsets() - or rec_reget_offsets(), or NULL */ - ulint n_fields,/* in: maximum number of initialized fields - (ULINT_UNDEFINED if all fields) */ - mem_heap_t* heap) /* in: memory heap */ -{ - ulint n; - - ut_ad(rec); - ut_ad(index); - ut_ad(heap); + size = (n + (1 + REC_OFFS_HEADER_SIZE)) * sizeof(ulint); - if (index->table->comp) { - switch (rec_get_status(rec)) { - case REC_STATUS_ORDINARY: - n = dict_index_get_n_fields(index); - break; - case REC_STATUS_NODE_PTR: - n = dict_index_get_n_unique_in_tree(index) + 1; - break; - case REC_STATUS_INFIMUM: - case REC_STATUS_SUPREMUM: - /* infimum or supremum record */ - n = 1; - break; - default: - ut_error; - return(NULL); + if (!offsets || rec_offs_get_n_alloc(offsets) < size) { + if (!*heap) { + *heap = mem_heap_create_func(size, + NULL, MEM_HEAP_DYNAMIC, file, line); } - } else { - n = rec_get_n_fields_old(rec); + offsets = mem_heap_alloc(*heap, size); + rec_offs_set_n_alloc(offsets, size); } - if (n_fields < n) { - n = n_fields; - } - - if (!offsets || rec_offs_n_fields(offsets) < n) { - offsets = mem_heap_alloc(heap, - (n + (1 + REC_OFFS_HEADER_SIZE)) * sizeof(ulint)); - } - - offsets[0] = n; - + rec_offs_set_n_fields(offsets, n); rec_init_offsets(rec, index, offsets); return(offsets); } @@ -722,14 +666,16 @@ rec_get_size( rec_t* rec, /* in: physical record */ dict_index_t* index) /* in: record descriptor */ { - mem_heap_t* heap - = mem_heap_create(100); - ulint* offsets - = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); - ulint size - = rec_offs_size(offsets); - - mem_heap_free(heap); + mem_heap_t* heap = NULL; + ulint offsets_[100 + REC_OFFS_HEADER_SIZE] + = { 100, }; + ulint* offsets = rec_get_offsets(rec, index, offsets_, + ULINT_UNDEFINED, &heap); + ulint size = rec_offs_size(offsets); + + if (heap) { + mem_heap_free(heap); + } return(size); } @@ -1032,10 +978,15 @@ rec_convert_dtuple_to_rec( #ifdef UNIV_DEBUG { - mem_heap_t* heap = mem_heap_create(100); - ut_ad(rec_validate(rec, - rec_get_offsets(rec, index, ULINT_UNDEFINED, heap))); - mem_heap_free(heap); + mem_heap_t* heap = NULL; + ulint offsets_[100 + REC_OFFS_HEADER_SIZE] + = { 100, }; + const ulint* offsets = rec_get_offsets(rec, index, + offsets_, ULINT_UNDEFINED, &heap); + ut_ad(rec_validate(rec, offsets)); + if (heap) { + mem_heap_free(heap); + } } #endif /* UNIV_DEBUG */ return(rec); @@ -1059,9 +1010,11 @@ rec_copy_prefix_to_dtuple( ulint len; byte* buf = NULL; ulint i; - ulint* offsets; + ulint offsets_[100 + REC_OFFS_HEADER_SIZE] + = { 100, }; + ulint* offsets = offsets_; - offsets = rec_get_offsets(rec, index, n_fields, heap); + offsets = rec_get_offsets(rec, index, offsets, n_fields, &heap); ut_ad(rec_validate(rec, offsets)); ut_ad(dtuple_check_typed(tuple)); @@ -1406,8 +1359,8 @@ rec_print_old( Prints a physical record. */ void -rec_print( -/*======*/ +rec_print_new( +/*==========*/ FILE* file, /* in: file where to print */ rec_t* rec, /* in: physical record */ const ulint* offsets)/* in: array returned by rec_get_offsets() */ @@ -1416,6 +1369,8 @@ rec_print( ulint len; ulint i; + ut_ad(rec_offs_validate(rec, NULL, offsets)); + if (!rec_offs_comp(offsets)) { rec_print_old(file, rec); return; @@ -1453,3 +1408,30 @@ rec_print( rec_validate(rec, offsets); } + +/******************************************************************* +Prints a physical record. */ + +void +rec_print( +/*======*/ + FILE* file, /* in: file where to print */ + rec_t* rec, /* in: physical record */ + dict_index_t* index) /* in: record descriptor */ +{ + ut_ad(index); + + if (!index->table->comp) { + rec_print_old(file, rec); + return; + } else { + mem_heap_t* heap = NULL; + ulint offsets_[100 + REC_OFFS_HEADER_SIZE] + = { 100, }; + rec_print_new(file, rec, rec_get_offsets(rec, index, offsets_, + ULINT_UNDEFINED, &heap)); + if (heap) { + mem_heap_free(heap); + } + } +} diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index a87a08fa3fe..969c3341be3 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -590,16 +590,8 @@ row_ins_foreign_report_err( fputs(", in index ", ef); ut_print_name(ef, trx, foreign->foreign_index->name); if (rec) { - mem_heap_t* heap; - ulint* offsets; - - heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, foreign->foreign_index, - ULINT_UNDEFINED, heap); - fputs(", there is a record:\n", ef); - rec_print(ef, rec, offsets); - mem_heap_free(heap); + rec_print(ef, rec, foreign->foreign_index); } else { fputs(", the record is not available\n", ef); } @@ -654,16 +646,7 @@ row_ins_foreign_report_add_err( } if (rec) { - mem_heap_t* heap; - ulint* offsets; - - heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, foreign->foreign_index, - ULINT_UNDEFINED, heap); - - rec_print(ef, rec, offsets); - - mem_heap_free(heap); + rec_print(ef, rec, foreign->foreign_index); } putc('\n', ef); @@ -734,7 +717,8 @@ row_ins_foreign_check_on_constraint( ulint i; trx_t* trx; mem_heap_t* tmp_heap = NULL; - ulint* offsets; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_a(thr && foreign && pcur && mtr); @@ -880,14 +864,10 @@ row_ins_foreign_check_on_constraint( fputs("\n" "InnoDB: record ", stderr); - offsets = rec_get_offsets(rec, index, - ULINT_UNDEFINED, tmp_heap); - rec_print(stderr, rec, offsets); + rec_print(stderr, rec, index); fputs("\n" "InnoDB: clustered record ", stderr); - offsets = rec_reget_offsets(clust_rec, clust_index, - offsets, ULINT_UNDEFINED, tmp_heap); - rec_print(stderr, clust_rec, offsets); + rec_print(stderr, clust_rec, clust_index); fputs("\n" "InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr); @@ -906,11 +886,8 @@ row_ins_foreign_check_on_constraint( we already have a normal shared lock on the appropriate gap if the search criterion was not unique */ - if (!tmp_heap) { - tmp_heap = mem_heap_create(256); - } - offsets = rec_get_offsets(clust_rec, clust_index, - ULINT_UNDEFINED, tmp_heap); + offsets = rec_get_offsets(clust_rec, clust_index, offsets, + ULINT_UNDEFINED, &tmp_heap); err = lock_clust_rec_read_check_and_lock(0, clust_rec, clust_index, offsets, LOCK_X, LOCK_REC_NOT_GAP, thr); } @@ -1152,11 +1129,10 @@ row_ins_check_foreign_constraint( ulint err; ulint i; mtr_t mtr; - trx_t* trx = thr_get_trx(thr); - mem_heap_t* heap; - ulint* offsets = NULL; - - heap = mem_heap_create(100); + trx_t* trx = thr_get_trx(thr); + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; run_again: #ifdef UNIV_SYNC_DEBUG @@ -1168,8 +1144,7 @@ run_again: if (trx->check_foreigns == FALSE) { /* The user has suppressed foreign key checks currently for this session */ - mem_heap_free(heap); - return(DB_SUCCESS); + goto exit_func; } /* If any of the foreign key fields in entry is SQL NULL, we @@ -1180,8 +1155,7 @@ run_again: if (UNIV_SQL_NULL == dfield_get_len( dtuple_get_nth_field(entry, i))) { - mem_heap_free(heap); - return(DB_SUCCESS); + goto exit_func; } } @@ -1205,8 +1179,7 @@ run_again: another, and the user has problems predicting in which order they are performed. */ - mem_heap_free(heap); - return(DB_SUCCESS); + goto exit_func; } } @@ -1219,8 +1192,6 @@ run_again: } if (check_table == NULL) { - mem_heap_free(heap); - if (check_ref) { FILE* ef = dict_foreign_err_file; mutex_enter(&dict_foreign_err_mutex); @@ -1242,10 +1213,10 @@ run_again: fputs(" does not currently exist!\n", ef); mutex_exit(&dict_foreign_err_mutex); - return(DB_NO_REFERENCED_ROW); + err = DB_NO_REFERENCED_ROW; } - return(DB_SUCCESS); + goto exit_func; } ut_a(check_table && check_index); @@ -1291,8 +1262,8 @@ run_again: goto next_rec; } - offsets = rec_reget_offsets(rec, check_index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, check_index, + offsets, ULINT_UNDEFINED, &heap); if (rec == page_get_supremum_rec(buf_frame_align(rec))) { @@ -1424,7 +1395,10 @@ do_possible_lock_wait: err = trx->error_state; } - mem_heap_free(heap); +exit_func: + if (heap) { + mem_heap_free(heap); + } return(err); } @@ -1565,8 +1539,9 @@ row_ins_scan_sec_index_for_duplicate( ibool moved; mtr_t mtr; trx_t* trx; - mem_heap_t* heap; - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; n_unique = dict_index_get_n_unique(index); @@ -1582,7 +1557,6 @@ row_ins_scan_sec_index_for_duplicate( } } - heap = mem_heap_create(100); mtr_start(&mtr); /* Store old value on n_fields_cmp */ @@ -1608,8 +1582,8 @@ row_ins_scan_sec_index_for_duplicate( trx = thr_get_trx(thr); ut_ad(trx); - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); if (innobase_query_is_replace()) { @@ -1662,7 +1636,9 @@ next_rec: } } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } mtr_commit(&mtr); /* Restore old value */ @@ -1692,7 +1668,11 @@ row_ins_duplicate_error_in_clust( rec_t* rec; page_t* page; ulint n_unique; - trx_t* trx = thr_get_trx(thr); + trx_t* trx = thr_get_trx(thr); + mem_heap_t*heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; + UT_NOT_USED(mtr); @@ -1720,12 +1700,8 @@ row_ins_duplicate_error_in_clust( page = buf_frame_align(rec); if (rec != page_get_infimum_rec(page)) { - mem_heap_t* heap; - ulint* offsets; - - heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, cursor->index, - ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, cursor->index, offsets, + ULINT_UNDEFINED, &heap); /* We set a lock on the possible duplicate: this is needed in logical logging of MySQL to make @@ -1750,17 +1726,15 @@ row_ins_duplicate_error_in_clust( } if (err != DB_SUCCESS) { - mem_heap_free(heap); - return(err); + goto func_exit; } if (row_ins_dupl_error_with_rec(rec, entry, cursor->index, offsets)) { trx->error_info = cursor->index; - mem_heap_free(heap); - return(DB_DUPLICATE_KEY); + err = DB_DUPLICATE_KEY; + goto func_exit; } - mem_heap_free(heap); } } @@ -1770,12 +1744,8 @@ row_ins_duplicate_error_in_clust( page = buf_frame_align(rec); if (rec != page_get_supremum_rec(page)) { - mem_heap_t* heap; - ulint* offsets; - - heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, cursor->index, - ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, cursor->index, offsets, + ULINT_UNDEFINED, &heap); /* The manual defines the REPLACE semantics that it is either an INSERT or DELETE(s) for duplicate key @@ -1795,15 +1765,14 @@ row_ins_duplicate_error_in_clust( } if (err != DB_SUCCESS) { - mem_heap_free(heap); - return(err); + goto func_exit; } if (row_ins_dupl_error_with_rec(rec, entry, cursor->index, offsets)) { trx->error_info = cursor->index; - mem_heap_free(heap); - return(DB_DUPLICATE_KEY); + err = DB_DUPLICATE_KEY; + goto func_exit; } mem_heap_free(heap); } @@ -1812,7 +1781,9 @@ row_ins_duplicate_error_in_clust( /* This should never happen */ } - return(DB_SUCCESS); + err = DB_SUCCESS; +func_exit: + return(err); } /******************************************************************* @@ -1894,8 +1865,9 @@ row_ins_index_entry_low( ulint n_unique; big_rec_t* big_rec = NULL; mtr_t mtr; - mem_heap_t* heap = mem_heap_create(100); - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; log_free_check(); @@ -2023,8 +1995,8 @@ function_exit: btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE, BTR_MODIFY_TREE, &cursor, 0, &mtr); rec = btr_cur_get_rec(&cursor); - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); err = btr_store_big_rec_extern_fields(index, rec, offsets, big_rec, &mtr); @@ -2038,7 +2010,9 @@ function_exit: mtr_commit(&mtr); } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(err); } diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index fa584df15db..4a65cbff8b5 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -3215,18 +3215,19 @@ row_scan_and_check_index( ulint* n_rows) /* out: number of entries seen in the current consistent read */ { - mem_heap_t* heap; - dtuple_t* prev_entry = NULL; + dtuple_t* prev_entry = NULL; ulint matched_fields; ulint matched_bytes; byte* buf; ulint ret; rec_t* rec; - ibool is_ok = TRUE; + ibool is_ok = TRUE; int cmp; ibool contains_null; ulint i; - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; *n_rows = 0; @@ -3268,8 +3269,8 @@ loop: matched_fields = 0; matched_bytes = 0; - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); cmp = cmp_dtuple_rec_with_match(prev_entry, rec, offsets, &matched_fields, &matched_bytes); @@ -3299,7 +3300,7 @@ loop: dtuple_print(stderr, prev_entry); fputs("\n" "InnoDB: record ", stderr); - rec_print(stderr, rec, offsets); + rec_print_new(stderr, rec, offsets); putc('\n', stderr); is_ok = FALSE; } else if ((index->type & DICT_UNIQUE) @@ -3313,7 +3314,7 @@ loop: } mem_heap_empty(heap); - offsets = NULL; + offsets = offsets_; prev_entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap); diff --git a/innobase/row/row0purge.c b/innobase/row/row0purge.c index 109d0f3b976..8897a1a872f 100644 --- a/innobase/row/row0purge.c +++ b/innobase/row/row0purge.c @@ -100,7 +100,8 @@ row_purge_remove_clust_if_poss_low( ulint err; mtr_t mtr; rec_t* rec; - mem_heap_t* heap; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; index = dict_table_get_first_index(node->table); @@ -120,19 +121,22 @@ row_purge_remove_clust_if_poss_low( } rec = btr_pcur_get_rec(pcur); - heap = mem_heap_create(100); if (0 != ut_dulint_cmp(node->roll_ptr, row_get_rec_roll_ptr(rec, index, rec_get_offsets( - rec, index, ULINT_UNDEFINED, heap)))) { - mem_heap_free(heap); + rec, index, offsets_, ULINT_UNDEFINED, &heap)))) { + if (heap) { + mem_heap_free(heap); + } /* Someone else has modified the record later: do not remove */ btr_pcur_commit_specify_mtr(pcur, &mtr); return(TRUE); } - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } if (mode == BTR_MODIFY_LEAF) { success = btr_cur_optimistic_delete(btr_cur, &mtr); diff --git a/innobase/row/row0row.c b/innobase/row/row0row.c index 9cf285a519d..43d0cd41b0a 100644 --- a/innobase/row/row0row.c +++ b/innobase/row/row0row.c @@ -202,17 +202,16 @@ row_build( ulint row_len; byte* buf; ulint i; - mem_heap_t* tmp_heap; + mem_heap_t* tmp_heap = NULL; + ulint offsets_[100] = { 100, }; ut_ad(index && rec && heap); ut_ad(index->type & DICT_CLUSTERED); if (!offsets) { - tmp_heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, index, - ULINT_UNDEFINED, tmp_heap); + offsets = rec_get_offsets(rec, index, offsets_, + ULINT_UNDEFINED, &tmp_heap); } else { - tmp_heap = NULL; ut_ad(rec_offs_validate(rec, index, offsets)); } @@ -296,13 +295,14 @@ row_rec_to_index_entry( ulint len; ulint rec_len; byte* buf; - mem_heap_t* tmp_heap; - ulint* offsets; + mem_heap_t* tmp_heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_ad(rec && heap && index); - tmp_heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, tmp_heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &tmp_heap); if (type == ROW_COPY_DATA) { /* Take a copy of rec to heap */ @@ -334,7 +334,9 @@ row_rec_to_index_entry( } ut_ad(dtuple_check_typed(entry)); - mem_heap_free(tmp_heap); + if (tmp_heap) { + mem_heap_free(tmp_heap); + } return(entry); } @@ -374,13 +376,14 @@ row_build_row_ref( byte* buf; ulint clust_col_prefix_len; ulint i; - mem_heap_t* tmp_heap; - ulint* offsets; - + mem_heap_t* tmp_heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; + ut_ad(index && rec && heap); - tmp_heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, tmp_heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &tmp_heap); if (type == ROW_COPY_DATA) { /* Take a copy of rec to heap */ @@ -433,7 +436,9 @@ row_build_row_ref( } ut_ad(dtuple_check_typed(ref)); - mem_heap_free(tmp_heap); + if (tmp_heap) { + mem_heap_free(tmp_heap); + } return(ref); } @@ -464,8 +469,9 @@ row_build_row_ref_in_tuple( ulint pos; ulint clust_col_prefix_len; ulint i; - mem_heap_t* heap; - ulint* offsets; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_a(ref && index && rec); @@ -486,8 +492,7 @@ row_build_row_ref_in_tuple( goto notfound; } - heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); ref_len = dict_index_get_n_unique(clust_index); @@ -526,7 +531,9 @@ row_build_row_ref_in_tuple( } ut_ad(dtuple_check_typed(ref)); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } /*********************************************************************** diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index 2b40b62e5bc..a3d844d1dac 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -78,14 +78,19 @@ row_sel_sec_rec_is_for_clust_rec( ulint n; ulint i; dtype_t* cur_type; - mem_heap_t* heap; - ulint* clust_offs; - ulint* sec_offs; - - heap = mem_heap_create(100); - clust_offs = rec_get_offsets(clust_rec, clust_index, - ULINT_UNDEFINED, heap); - sec_offs = rec_get_offsets(sec_rec, sec_index, ULINT_UNDEFINED, heap); + mem_heap_t* heap = NULL; + ulint clust_offsets_[100] + = { 100, }; + ulint sec_offsets_[10] + = { 10, }; + ulint* clust_offs = clust_offsets_; + ulint* sec_offs = sec_offsets_; + ibool is_equal = TRUE; + + clust_offs = rec_get_offsets(clust_rec, clust_index, clust_offs, + ULINT_UNDEFINED, &heap); + sec_offs = rec_get_offsets(sec_rec, sec_index, sec_offs, + ULINT_UNDEFINED, &heap); n = dict_index_get_n_ordering_defined_by_user(sec_index); @@ -113,13 +118,16 @@ row_sel_sec_rec_is_for_clust_rec( if (0 != cmp_data_data(dict_col_get_type(col), clust_field, clust_len, sec_field, sec_len)) { - mem_heap_free(heap); - return(FALSE); + is_equal = FALSE; + goto func_exit; } } - mem_heap_free(heap); - return(TRUE); +func_exit: + if (heap) { + mem_heap_free(heap); + } + return(is_equal); } /************************************************************************* @@ -612,13 +620,13 @@ row_sel_get_clust_rec( rec_t* clust_rec; rec_t* old_vers; ulint err; - mem_heap_t* heap; - ulint* offsets; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; - heap = mem_heap_create(100); offsets = rec_get_offsets(rec, btr_pcur_get_btr_cur(&plan->pcur)->index, - ULINT_UNDEFINED, heap); + offsets, ULINT_UNDEFINED, &heap); row_build_row_ref_fast(plan->clust_ref, plan->clust_map, rec, offsets); @@ -654,8 +662,8 @@ row_sel_get_clust_rec( goto func_exit; } - offsets = rec_reget_offsets(clust_rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(clust_rec, index, offsets, + ULINT_UNDEFINED, &heap); if (!node->read_view) { /* Try to place a lock on the index record */ @@ -677,8 +685,7 @@ row_sel_get_clust_rec( if (err != DB_SUCCESS) { - mem_heap_free(heap); - return(err); + goto err_exit; } } else { /* This is a non-locking consistent read: if necessary, fetch @@ -693,8 +700,7 @@ row_sel_get_clust_rec( clust_rec, &old_vers, mtr); if (err != DB_SUCCESS) { - mem_heap_free(heap); - return(err); + goto err_exit; } clust_rec = old_vers; @@ -731,9 +737,12 @@ row_sel_get_clust_rec( UT_LIST_GET_FIRST(plan->columns)); func_exit: *out_rec = clust_rec; - - mem_heap_free(heap); - return(DB_SUCCESS); + err = DB_SUCCESS; +err_exit: + if (heap) { + mem_heap_free(heap); + } + return(err); } /************************************************************************* @@ -975,8 +984,10 @@ row_sel_try_search_shortcut( { dict_index_t* index; rec_t* rec; - mem_heap_t* heap; - ulint* offsets; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; + ulint ret; index = plan->index; @@ -1010,43 +1021,46 @@ row_sel_try_search_shortcut( /* This is a non-locking consistent read: if necessary, fetch a previous version of the record */ - heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); if (index->type & DICT_CLUSTERED) { if (!lock_clust_rec_cons_read_sees(rec, index, offsets, node->read_view)) { - mem_heap_free(heap); - return(SEL_RETRY); + ret = SEL_RETRY; + goto func_exit; } } else if (!lock_sec_rec_cons_read_sees(rec, index, node->read_view)) { - mem_heap_free(heap); - return(SEL_RETRY); + ret = SEL_RETRY; + goto func_exit; } /* Test deleted flag. Fetch the columns needed in test conditions. */ row_sel_fetch_columns(index, rec, offsets, UT_LIST_GET_FIRST(plan->columns)); - mem_heap_free(heap); if (rec_get_deleted_flag(rec, plan->table->comp)) { - return(SEL_EXHAUSTED); + ret = SEL_EXHAUSTED; + goto func_exit; } /* Test the rest of search conditions */ if (!row_sel_test_other_conds(plan)) { - return(SEL_EXHAUSTED); + ret = SEL_EXHAUSTED; + goto func_exit; } ut_ad(plan->pcur.latch_mode == node->latch_mode); plan->n_rows_fetched++; - +func_exit: + if (heap) { + mem_heap_free(heap); + } return(SEL_FOUND); } @@ -1095,8 +1109,9 @@ row_sel( to the next non-clustered record */ ulint found_flag; ulint err; - mem_heap_t* heap = mem_heap_create(100); - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_ad(thr->run_node == node); @@ -1253,8 +1268,8 @@ rec_loop: rec_t* next_rec = page_rec_get_next(rec); ulint lock_type; - offsets = rec_reget_offsets(next_rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(next_rec, index, offsets, + ULINT_UNDEFINED, &heap); if (srv_locks_unsafe_for_binlog) { lock_type = LOCK_REC_NOT_GAP; @@ -1295,8 +1310,8 @@ rec_loop: not used. */ ulint lock_type; - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); if (srv_locks_unsafe_for_binlog) { lock_type = LOCK_REC_NOT_GAP; @@ -1369,8 +1384,7 @@ rec_loop: /* PHASE 3: Get previous version in a consistent read */ cons_read_requires_clust_rec = FALSE; - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); if (consistent_read) { /* This is a non-locking consistent read: if necessary, fetch @@ -1403,8 +1417,8 @@ rec_loop: } rec = old_vers; - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); } } else if (!lock_sec_rec_cons_read_sees(rec, index, node->read_view)) { @@ -1635,8 +1649,8 @@ next_table_no_mtr: rw_lock_s_unlock(&btr_search_latch); } - mem_heap_free(heap); - return(DB_SUCCESS); + err = DB_SUCCESS; + goto func_exit; } node->fetch_table++; @@ -1669,7 +1683,7 @@ table_exhausted: table_exhausted_no_mtr: if (node->fetch_table == 0) { - mem_heap_free(heap); + err = DB_SUCCESS; if (node->is_aggregate && !node->aggregate_already_fetched) { @@ -1683,7 +1697,7 @@ table_exhausted_no_mtr: rw_lock_s_unlock(&btr_search_latch); } - return(DB_SUCCESS); + goto func_exit; } node->state = SEL_NODE_NO_MORE_ROWS; @@ -1694,7 +1708,7 @@ table_exhausted_no_mtr: rw_lock_s_unlock(&btr_search_latch); } - return(DB_SUCCESS); + goto func_exit; } node->fetch_table--; @@ -1718,8 +1732,8 @@ stop_for_a_while: mtr_commit(&mtr); ut_ad(sync_thread_levels_empty_gen(TRUE)); - mem_heap_free(heap); - return(DB_SUCCESS); + err = DB_SUCCESS; + goto func_exit; commit_mtr_for_a_while: /* Stores the cursor position and commits &mtr; this is used if @@ -1754,7 +1768,10 @@ lock_wait_or_error: ut_ad(sync_thread_levels_empty_gen(TRUE)); - mem_heap_free(heap); +func_exit: + if (heap) { + mem_heap_free(heap); + } return(err); } @@ -2197,7 +2214,7 @@ row_sel_store_row_id_to_prebuilt( fprintf(stderr, "\n" "InnoDB: Field number %lu, record:\n", (ulong) dict_index_get_sys_col_pos(index, DATA_ROW_ID)); - rec_print(stderr, index_rec, offsets); + rec_print_new(stderr, index_rec, offsets); putc('\n', stderr); ut_error; } @@ -2496,8 +2513,9 @@ row_sel_get_clust_rec_for_mysql( rec_t* old_vers; ulint err; trx_t* trx; - mem_heap_t* heap = mem_heap_create(100); - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; *out_rec = NULL; trx = thr_get_trx(thr); @@ -2537,14 +2555,10 @@ row_sel_get_clust_rec_for_mysql( dict_index_name_print(stderr, trx, sec_index); fputs("\n" "InnoDB: sec index record ", stderr); - offsets = rec_get_offsets(rec, sec_index, - ULINT_UNDEFINED, heap); - rec_print(stderr, rec, offsets); + rec_print(stderr, rec, sec_index); fputs("\n" "InnoDB: clust index record ", stderr); - offsets = rec_reget_offsets(clust_rec, clust_index, - offsets, ULINT_UNDEFINED, heap); - rec_print(stderr, clust_rec, offsets); + rec_print(stderr, clust_rec, clust_index); putc('\n', stderr); trx_print(stderr, trx); @@ -2557,8 +2571,8 @@ row_sel_get_clust_rec_for_mysql( goto func_exit; } - offsets = rec_get_offsets(clust_rec, clust_index, - ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(clust_rec, clust_index, offsets, + ULINT_UNDEFINED, &heap); if (prebuilt->select_lock_type != LOCK_NONE) { /* Try to place a lock on the index record; we are searching @@ -2571,8 +2585,7 @@ row_sel_get_clust_rec_for_mysql( LOCK_REC_NOT_GAP, thr); if (err != DB_SUCCESS) { - mem_heap_free(heap); - return(err); + goto err_exit; } } else { /* This is a non-locking consistent read: if necessary, fetch @@ -2594,8 +2607,7 @@ row_sel_get_clust_rec_for_mysql( if (err != DB_SUCCESS) { - mem_heap_free(heap); - return(err); + goto err_exit; } clust_rec = old_vers; @@ -2637,8 +2649,12 @@ func_exit: btr_pcur_store_position(prebuilt->clust_pcur, mtr); } - mem_heap_free(heap); - return(DB_SUCCESS); + err = DB_SUCCESS; +err_exit: + if (heap) { + mem_heap_free(heap); + } + return(err); } /************************************************************************ @@ -2809,8 +2825,8 @@ row_sel_try_search_shortcut_for_mysql( /* out: SEL_FOUND, SEL_EXHAUSTED, SEL_RETRY */ rec_t** out_rec,/* out: record if found */ row_prebuilt_t* prebuilt,/* in: prebuilt struct */ - ulint** offsets,/* in/out: for rec_reget_offsets(*out_rec) */ - mem_heap_t* heap, /* in: heap for rec_reget_offsets() */ + ulint** offsets,/* in/out: for rec_get_offsets(*out_rec) */ + mem_heap_t** heap, /* in/out: heap for rec_get_offsets() */ mtr_t* mtr) /* in: started mtr */ { dict_index_t* index = prebuilt->index; @@ -2849,8 +2865,8 @@ row_sel_try_search_shortcut_for_mysql( /* This is a non-locking consistent read: if necessary, fetch a previous version of the record */ - *offsets = rec_reget_offsets(rec, index, - *offsets, ULINT_UNDEFINED, heap); + *offsets = rec_get_offsets(rec, index, *offsets, + ULINT_UNDEFINED, heap); if (!lock_clust_rec_cons_read_sees(rec, index, *offsets, trx->read_view)) { @@ -2915,7 +2931,6 @@ row_search_for_mysql( ibool moved; ibool cons_read_requires_clust_rec; ibool was_lock_wait; - ulint ret; ulint shortcut; ibool unique_search = FALSE; ibool unique_search_from_clust_index = FALSE; @@ -2931,8 +2946,9 @@ row_search_for_mysql( ulint cnt = 0; ulint next_offs; mtr_t mtr; - mem_heap_t* heap; - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_ad(index && pcur && search_tuple); ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); @@ -3023,9 +3039,8 @@ row_search_for_mysql( prebuilt->n_rows_fetched++; srv_n_rows_read++; - trx->op_info = ""; - - return(DB_SUCCESS); + err = DB_SUCCESS; + goto func_exit; } if (prebuilt->fetch_cache_first > 0 @@ -3034,9 +3049,9 @@ row_search_for_mysql( /* The previous returned row was popped from the fetch cache, but the cache was not full at the time of the popping: no more rows can exist in the result set */ - - trx->op_info = ""; - return(DB_RECORD_NOT_FOUND); + + err = DB_RECORD_NOT_FOUND; + goto func_exit; } prebuilt->n_rows_fetched++; @@ -3080,13 +3095,12 @@ row_search_for_mysql( if (direction != 0 && !prebuilt->used_in_HANDLER) { - trx->op_info = ""; - return(DB_RECORD_NOT_FOUND); + err = DB_RECORD_NOT_FOUND; + goto func_exit; } } mtr_start(&mtr); - heap = mem_heap_create(100); /*-------------------------------------------------------------*/ /* PHASE 2: Try fast adaptive hash index search if possible */ @@ -3132,7 +3146,7 @@ row_search_for_mysql( } #endif shortcut = row_sel_try_search_shortcut_for_mysql(&rec, - prebuilt, &offsets, heap, &mtr); + prebuilt, &offsets, &heap, &mtr); if (shortcut == SEL_FOUND) { #ifdef UNIV_SEARCH_DEBUG ut_a(0 == cmp_dtuple_rec(search_tuple, @@ -3163,12 +3177,10 @@ row_search_for_mysql( trx->has_search_latch = FALSE; } - trx->op_info = ""; - /* NOTE that we do NOT store the cursor position */ - mem_heap_free(heap); - return(DB_SUCCESS); + err = DB_SUCCESS; + goto func_exit; } else if (shortcut == SEL_EXHAUSTED) { @@ -3186,13 +3198,11 @@ row_search_for_mysql( trx->has_search_latch = FALSE; } - trx->op_info = ""; - /* NOTE that we do NOT store the cursor position */ - mem_heap_free(heap); - return(DB_RECORD_NOT_FOUND); + err = DB_RECORD_NOT_FOUND; + goto func_exit; } shortcut_fails_too_big_rec: mtr_commit(&mtr); @@ -3334,9 +3344,9 @@ rec_loop: we do not lock gaps. Supremum record is really a gap and therefore we do not set locks there. */ - if (srv_locks_unsafe_for_binlog == FALSE) { - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + if (!srv_locks_unsafe_for_binlog) { + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); err = sel_set_rec_lock(rec, index, offsets, prebuilt->select_lock_type, LOCK_ORDINARY, thr); @@ -3406,8 +3416,7 @@ rec_loop: } } - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); if (srv_force_recovery > 0) { if (!rec_validate(rec, offsets) @@ -3464,7 +3473,7 @@ rec_loop: btr_pcur_store_position(pcur, &mtr); - ret = DB_RECORD_NOT_FOUND; + err = DB_RECORD_NOT_FOUND; /* ut_print_name(stderr, index->name); fputs(" record not found 3\n", stderr); */ @@ -3498,7 +3507,7 @@ rec_loop: btr_pcur_store_position(pcur, &mtr); - ret = DB_RECORD_NOT_FOUND; + err = DB_RECORD_NOT_FOUND; /* ut_print_name(stderr, index->name); fputs(" record not found 4\n", stderr); */ @@ -3644,11 +3653,11 @@ rec_loop: if (prebuilt->need_to_access_clustered) { ut_ad(rec == clust_rec || index == clust_index); - offsets = rec_reget_offsets(rec, clust_index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, clust_index, offsets, + ULINT_UNDEFINED, &heap); } else { - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); } /* We found a qualifying row */ @@ -3694,8 +3703,8 @@ rec_loop: } if (prebuilt->clust_index_was_generated) { - offsets = rec_reget_offsets(index_rec, index, offsets, - ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(index_rec, index, offsets, + ULINT_UNDEFINED, &heap); row_sel_store_row_id_to_prebuilt(prebuilt, index_rec, index, offsets); } @@ -3717,7 +3726,7 @@ got_row: btr_pcur_store_position(pcur, &mtr); } - ret = DB_SUCCESS; + err = DB_SUCCESS; goto normal_return; @@ -3756,9 +3765,9 @@ next_rec: btr_pcur_store_position(pcur, &mtr); if (match_mode != 0) { - ret = DB_RECORD_NOT_FOUND; + err = DB_RECORD_NOT_FOUND; } else { - ret = DB_END_OF_INDEX; + err = DB_END_OF_INDEX; } goto normal_return; @@ -3797,10 +3806,7 @@ lock_wait_or_error: /* fputs("Using ", stderr); dict_index_name_print(stderr, index); fprintf(stderr, " cnt %lu ret value %lu err\n", cnt, err); */ - trx->op_info = ""; - - mem_heap_free(heap); - return(err); + goto func_exit; normal_return: /*-------------------------------------------------------------*/ @@ -3811,20 +3817,22 @@ normal_return: if (prebuilt->n_fetch_cached > 0) { row_sel_pop_cached_row_for_mysql(buf, prebuilt); - ret = DB_SUCCESS; + err = DB_SUCCESS; } /* fputs("Using ", stderr); dict_index_name_print(stderr, index); fprintf(stderr, " cnt %lu ret value %lu err\n", cnt, err); */ - if (ret == DB_SUCCESS) { + if (err == DB_SUCCESS) { srv_n_rows_read++; } +func_exit: trx->op_info = ""; - - mem_heap_free(heap); - return(ret); + if (heap) { + mem_heap_free(heap); + } + return(err); } /*********************************************************************** diff --git a/innobase/row/row0umod.c b/innobase/row/row0umod.c index ee9066a0d6f..1cade0f304f 100644 --- a/innobase/row/row0umod.c +++ b/innobase/row/row0umod.c @@ -430,7 +430,6 @@ row_undo_mod_del_unmark_sec_and_undo_update( found = row_search_index_entry(index, entry, mode, &pcur, &mtr); if (!found) { - heap = mem_heap_create(100); fputs("InnoDB: error in sec index entry del undo in\n" "InnoDB: ", stderr); dict_index_name_print(stderr, trx, index); @@ -439,14 +438,11 @@ row_undo_mod_del_unmark_sec_and_undo_update( dtuple_print(stderr, entry); fputs("\n" "InnoDB: record ", stderr); - rec_print(stderr, btr_pcur_get_rec(&pcur), - rec_get_offsets(btr_pcur_get_rec(&pcur), - index, ULINT_UNDEFINED, heap)); + rec_print(stderr, btr_pcur_get_rec(&pcur), index); putc('\n', stderr); trx_print(stderr, trx); fputs("\n" "InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr); - mem_heap_free(heap); } else { btr_cur_t* btr_cur = btr_pcur_get_btr_cur(&pcur); diff --git a/innobase/row/row0undo.c b/innobase/row/row0undo.c index 42f5ef94854..d994eab9873 100644 --- a/innobase/row/row0undo.c +++ b/innobase/row/row0undo.c @@ -151,8 +151,9 @@ row_undo_search_clust_to_pcur( mtr_t mtr; ibool ret; rec_t* rec; - mem_heap_t* heap; - const ulint* offsets; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; mtr_start(&mtr); @@ -163,8 +164,8 @@ row_undo_search_clust_to_pcur( rec = btr_pcur_get_rec(&(node->pcur)); - heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, clust_index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, clust_index, offsets, + ULINT_UNDEFINED, &heap); if (!found || 0 != ut_dulint_cmp(node->roll_ptr, row_get_rec_roll_ptr(rec, clust_index, offsets))) { @@ -188,6 +189,9 @@ row_undo_search_clust_to_pcur( btr_pcur_commit_specify_mtr(&(node->pcur), &mtr); + if (heap) { + mem_heap_free(heap); + } return(ret); } diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c index e080d0ba577..e4013633bed 100644 --- a/innobase/row/row0upd.c +++ b/innobase/row/row0upd.c @@ -700,6 +700,7 @@ row_upd_build_sec_rec_difference_binary( upd_t* update; ulint n_diff; ulint i; + ulint offsets_[10] = { 10, }; const ulint* offsets; /* This function is used only for a secondary index */ @@ -708,7 +709,8 @@ row_upd_build_sec_rec_difference_binary( update = upd_create(dtuple_get_n_fields(entry), heap); n_diff = 0; - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets_, + ULINT_UNDEFINED, &heap); for (i = 0; i < dtuple_get_n_fields(entry); i++) { @@ -775,6 +777,7 @@ row_upd_build_difference_binary( ulint trx_id_pos; ibool extern_bit; ulint i; + ulint offsets_[100] = { 100, }; const ulint* offsets; /* This function is used only for a clustered index */ @@ -787,7 +790,8 @@ row_upd_build_difference_binary( roll_ptr_pos = dict_index_get_sys_col_pos(index, DATA_ROLL_PTR); trx_id_pos = dict_index_get_sys_col_pos(index, DATA_TRX_ID); - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets_, + ULINT_UNDEFINED, &heap); for (i = 0; i < dtuple_get_n_fields(entry); i++) { @@ -1182,7 +1186,8 @@ row_upd_store_row( dict_index_t* clust_index; upd_t* update; rec_t* rec; - mem_heap_t* heap; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; const ulint* offsets; ut_ad(node->pcur->latch_mode != BTR_NO_LATCHES); @@ -1196,8 +1201,8 @@ row_upd_store_row( rec = btr_pcur_get_rec(node->pcur); - heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, clust_index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, clust_index, offsets_, + ULINT_UNDEFINED, &heap); node->row = row_build(ROW_COPY_DATA, clust_index, rec, offsets, node->heap); node->ext_vec = mem_heap_alloc(node->heap, sizeof(ulint) @@ -1210,7 +1215,9 @@ row_upd_store_row( node->n_ext_vec = btr_push_update_extern_fields(node->ext_vec, offsets, update); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } } /*************************************************************** @@ -1263,8 +1270,7 @@ row_upd_sec_index_entry( dtuple_print(stderr, entry); fputs("\n" "InnoDB: record ", stderr); - rec_print(stderr, rec, - rec_get_offsets(rec, index, ULINT_UNDEFINED, heap)); + rec_print(stderr, rec, index); putc('\n', stderr); trx_print(stderr, trx); @@ -1364,7 +1370,7 @@ row_upd_clust_rec_by_insert( a foreign key constraint */ mtr_t* mtr) /* in: mtr; gets committed here */ { - mem_heap_t* heap; + mem_heap_t* heap = NULL; btr_pcur_t* pcur; btr_cur_t* btr_cur; trx_t* trx; @@ -1379,15 +1385,14 @@ row_upd_clust_rec_by_insert( table = node->table; pcur = node->pcur; btr_cur = btr_pcur_get_btr_cur(pcur); - heap = mem_heap_create(500); if (node->state != UPD_NODE_INSERT_CLUSTERED) { + ulint offsets_[100] = { 100, }; err = btr_cur_del_mark_set_clust_rec(BTR_NO_LOCKING_FLAG, btr_cur, TRUE, thr, mtr); if (err != DB_SUCCESS) { mtr_commit(mtr); - mem_heap_free(heap); return(err); } @@ -1398,8 +1403,8 @@ row_upd_clust_rec_by_insert( btr_cur_mark_extern_inherited_fields(btr_cur_get_rec(btr_cur), rec_get_offsets(btr_cur_get_rec(btr_cur), - dict_table_get_first_index(table), - ULINT_UNDEFINED, heap), node->update, mtr); + dict_table_get_first_index(table), offsets_, + ULINT_UNDEFINED, &heap), node->update, mtr); if (check_ref) { /* NOTE that the following call loses the position of pcur ! */ @@ -1408,7 +1413,9 @@ row_upd_clust_rec_by_insert( index, thr, mtr); if (err != DB_SUCCESS) { mtr_commit(mtr); - + if (heap) { + mem_heap_free(heap); + } return(err); } } @@ -1417,6 +1424,9 @@ row_upd_clust_rec_by_insert( mtr_commit(mtr); + if (!heap) { + heap = mem_heap_create(500); + } node->state = UPD_NODE_INSERT_CLUSTERED; entry = row_build_index_entry(node->row, index, heap); @@ -1516,17 +1526,20 @@ row_upd_clust_rec( mtr_commit(mtr); if (err == DB_SUCCESS && big_rec) { - mem_heap_t* heap; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; rec_t* rec; mtr_start(mtr); - heap = mem_heap_create(100); rec = btr_cur_get_rec(btr_cur); ut_a(btr_pcur_restore_position(BTR_MODIFY_TREE, pcur, mtr)); err = btr_store_big_rec_extern_fields(index, rec, - rec_get_offsets(rec, index, ULINT_UNDEFINED, heap), + rec_get_offsets(rec, index, offsets_, + ULINT_UNDEFINED, &heap), big_rec, mtr); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } mtr_commit(mtr); } @@ -1611,7 +1624,8 @@ row_upd_clust_step( mtr_t* mtr; mtr_t mtr_buf; rec_t* rec; - mem_heap_t* heap; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; const ulint* offsets; index = dict_table_get_first_index(node->table); @@ -1670,33 +1684,31 @@ row_upd_clust_step( } rec = btr_pcur_get_rec(pcur); - heap = mem_heap_create(100); - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets_, + ULINT_UNDEFINED, &heap); if (!node->has_clust_rec_x_lock) { err = lock_clust_rec_modify_check_and_lock(0, rec, index, offsets, thr); if (err != DB_SUCCESS) { mtr_commit(mtr); - mem_heap_free(heap); - return(err); + goto exit_func; } } /* NOTE: the following function calls will also commit mtr */ if (node->is_delete) { - mem_heap_free(heap); err = row_upd_del_mark_clust_rec(node, index, thr, check_ref, mtr); - if (err != DB_SUCCESS) { - - return(err); + if (err == DB_SUCCESS) { + node->state = UPD_NODE_UPDATE_ALL_SEC; + node->index = dict_table_get_next_index(index); + } + exit_func: + if (heap) { + mem_heap_free(heap); } - - node->state = UPD_NODE_UPDATE_ALL_SEC; - node->index = dict_table_get_next_index(index); - return(err); } @@ -1710,13 +1722,14 @@ row_upd_clust_step( UT_LIST_GET_FIRST(node->columns)); row_upd_eval_new_vals(node->update); } - - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } + if (node->cmpl_info & UPD_NODE_NO_ORD_CHANGE) { err = row_upd_clust_rec(node, index, thr, mtr); - return(err); } @@ -1968,7 +1981,8 @@ row_upd_in_place_in_select( btr_pcur_t* pcur; btr_cur_t* btr_cur; ulint err; - mem_heap_t* heap; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; ut_ad(sel_node->select_will_do_update); ut_ad(sel_node->latch_mode == BTR_MODIFY_LEAF); @@ -1984,11 +1998,13 @@ row_upd_in_place_in_select( /* Copy the necessary columns from clust_rec and calculate the new values to set */ - heap = mem_heap_create(100); row_upd_copy_columns(btr_pcur_get_rec(pcur), rec_get_offsets( - btr_pcur_get_rec(pcur), btr_cur->index, ULINT_UNDEFINED, heap), + btr_pcur_get_rec(pcur), btr_cur->index, offsets_, + ULINT_UNDEFINED, &heap), UT_LIST_GET_FIRST(node->columns)); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } row_upd_eval_new_vals(node->update); ut_ad(!rec_get_deleted_flag(btr_pcur_get_rec(pcur), diff --git a/innobase/row/row0vers.c b/innobase/row/row0vers.c index 5281dbd67d7..9ccaf32f2c2 100644 --- a/innobase/row/row0vers.c +++ b/innobase/row/row0vers.c @@ -100,32 +100,25 @@ row_vers_impl_x_locked_off_kernel( } heap = mem_heap_create(1024); - clust_offsets = rec_get_offsets(clust_rec, clust_index, - ULINT_UNDEFINED, heap); + clust_offsets = rec_get_offsets(clust_rec, clust_index, NULL, + ULINT_UNDEFINED, &heap); trx_id = row_get_rec_trx_id(clust_rec, clust_index, clust_offsets); mtr_s_lock(&(purge_sys->latch), &mtr); mutex_enter(&kernel_mutex); + trx = NULL; if (!trx_is_active(trx_id)) { /* The transaction that modified or inserted clust_rec is no longer active: no implicit lock on rec */ - - mem_heap_free(heap); - mtr_commit(&mtr); - - return(NULL); + goto exit_func; } if (!lock_check_trx_id_sanity(trx_id, clust_rec, clust_index, clust_offsets, TRUE)) { /* Corruption noticed: try to avoid a crash by returning */ - - mem_heap_free(heap); - mtr_commit(&mtr); - - return(NULL); + goto exit_func; } comp = index->table->comp; @@ -166,7 +159,8 @@ row_vers_impl_x_locked_off_kernel( if (prev_version) { clust_offsets = rec_get_offsets(prev_version, - clust_index, ULINT_UNDEFINED, heap); + clust_index, NULL, + ULINT_UNDEFINED, &heap); row = row_build(ROW_COPY_POINTERS, clust_index, prev_version, clust_offsets, heap); entry = row_build_index_entry(row, index, heap); @@ -250,6 +244,7 @@ row_vers_impl_x_locked_off_kernel( version = prev_version; }/* for (;;) */ +exit_func: mtr_commit(&mtr); mem_heap_free(heap); @@ -330,8 +325,8 @@ row_vers_old_has_index_entry( comp = index->table->comp; ut_ad(comp == page_is_comp(buf_frame_align(rec))); heap = mem_heap_create(1024); - clust_offsets = rec_get_offsets(rec, clust_index, - ULINT_UNDEFINED, heap); + clust_offsets = rec_get_offsets(rec, clust_index, NULL, + ULINT_UNDEFINED, &heap); if (also_curr && !rec_get_deleted_flag(rec, comp)) { row = row_build(ROW_COPY_POINTERS, clust_index, @@ -371,7 +366,7 @@ row_vers_old_has_index_entry( } clust_offsets = rec_get_offsets(prev_version, clust_index, - ULINT_UNDEFINED, heap); + NULL, ULINT_UNDEFINED, &heap); if (!rec_get_deleted_flag(prev_version, comp)) { row = row_build(ROW_COPY_POINTERS, clust_index, @@ -438,7 +433,7 @@ row_vers_build_for_consistent_read( #endif /* UNIV_SYNC_DEBUG */ heap = mem_heap_create(1024); - offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap); ut_ad(!read_view_sees_trx_id(view, row_get_rec_trx_id(rec, index, offsets))); @@ -466,8 +461,8 @@ row_vers_build_for_consistent_read( break; } - offsets = rec_get_offsets(prev_version, index, - ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(prev_version, index, NULL, + ULINT_UNDEFINED, &heap); prev_trx_id = row_get_rec_trx_id(prev_version, index, offsets); if (read_view_sees_trx_id(view, prev_trx_id)) { diff --git a/innobase/trx/trx0rec.c b/innobase/trx/trx0rec.c index 484d4f62744..12a0512da53 100644 --- a/innobase/trx/trx0rec.c +++ b/innobase/trx/trx0rec.c @@ -1010,8 +1010,9 @@ trx_undo_report_row_operation( ibool is_insert; trx_rseg_t* rseg; mtr_t mtr; - mem_heap_t* heap; - ulint* offsets = NULL; + mem_heap_t* heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; ut_a(index->type & DICT_CLUSTERED); @@ -1066,8 +1067,6 @@ trx_undo_report_row_operation( mtr_start(&mtr); - heap = mem_heap_create(100); - for (;;) { undo_page = buf_page_get_gen(undo->space, page_no, RW_X_LATCH, undo->guess_page, @@ -1084,8 +1083,8 @@ trx_undo_report_row_operation( index, clust_entry, &mtr); } else { - offsets = rec_reget_offsets(rec, index, - offsets, ULINT_UNDEFINED, heap); + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &heap); offset = trx_undo_page_report_modify(undo_page, trx, index, rec, offsets, update, cmpl_info, &mtr); } @@ -1129,7 +1128,9 @@ trx_undo_report_row_operation( mutex_exit(&(trx->undo_mutex)); mtr_commit(&mtr); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(DB_OUT_OF_FILE_SPACE); } } @@ -1146,7 +1147,9 @@ trx_undo_report_row_operation( *roll_ptr = trx_undo_build_roll_ptr(is_insert, rseg->id, page_no, offset); - mem_heap_free(heap); + if (heap) { + mem_heap_free(heap); + } return(DB_SUCCESS); } @@ -1266,7 +1269,6 @@ trx_undo_prev_version_build( ibool dummy_extern; byte* buf; ulint err; - ulint* index_offsets = NULL; #ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED)); #endif /* UNIV_SYNC_DEBUG */ @@ -1282,12 +1284,10 @@ trx_undo_prev_version_build( "InnoDB: Submit a detailed bug report to" " http://bugs.mysql.com\n" "InnoDB: index record ", index->name); - index_offsets = rec_get_offsets(index_rec, index, - ULINT_UNDEFINED, heap); - rec_print(stderr, index_rec, index_offsets); + rec_print(stderr, index_rec, index); fputs("\n" "InnoDB: record version ", stderr); - rec_print(stderr, rec, offsets); + rec_print_new(stderr, rec, offsets); putc('\n', stderr); return(DB_ERROR); } @@ -1353,12 +1353,10 @@ trx_undo_prev_version_build( ut_print_buf(stderr, undo_rec, 150); fputs("\n" "InnoDB: index record ", stderr); - index_offsets = rec_get_offsets(index_rec, index, - ULINT_UNDEFINED, heap); - rec_print(stderr, index_rec, index_offsets); + rec_print(stderr, index_rec, index); fputs("\n" "InnoDB: record version ", stderr); - rec_print(stderr, rec, offsets); + rec_print_new(stderr, rec, offsets); fprintf(stderr, "\n" "InnoDB: Record trx id %lu %lu, update rec trx id %lu %lu\n" "InnoDB: Roll ptr in rec %lu %lu, in update rec %lu %lu\n", |