3855 Marko Mäkelä 2012-05-23
WL#6255 preparation: Do not recompute offsets after B-tree insert.
btr_root_raise_and_insert(), btr_page_insert_fits(),
btr_page_tuple_smaller(), btr_page_split_and_insert(),
btr_cur_insert_if_possible(), btr_cur_optimistic_insert(),
btr_cur_pessimistic_insert(), ibuf_insert_to_index_page_low(),
page_cur_tuple_insert(), row_ins_sec_index_entry_by_modify():
Add in/out parameters for offsets and heap.
row_ins_sec_index_entry_low(): Add a parameter for heap.
modified:
storage/innobase/btr/btr0btr.cc
storage/innobase/btr/btr0cur.cc
storage/innobase/ibuf/ibuf0ibuf.cc
storage/innobase/include/btr0btr.h
storage/innobase/include/btr0cur.h
storage/innobase/include/page0cur.h
storage/innobase/include/page0cur.ic
storage/innobase/row/row0ins.cc
storage/innobase/row/row0log.cc
storage/innobase/row/row0merge.cc
3854 Marko Mäkelä 2012-05-23
Add function attributes. Replace btr_page_get_level() with a macro.
modified:
storage/innobase/include/btr0btr.h
storage/innobase/include/btr0btr.ic
3853 Marko Mäkelä 2012-05-23
WL#5526 optimization cleanup:
row_log_online_op(): Fix a bogus warning on uninitialized mrec_size,
and do a little less work while holding index->online_log->mutex.
modified:
storage/innobase/row/row0log.cc
3852 Marko Mäkelä 2012-05-22
Add function attributes.
modified:
storage/innobase/include/rem0rec.h
=== modified file 'storage/innobase/btr/btr0btr.cc'
--- a/storage/innobase/btr/btr0btr.cc revid:marko.makela@stripped2gjq7ana
+++ b/storage/innobase/btr/btr0btr.cc revid:marko.makela@stripped
@@ -1864,6 +1864,8 @@ btr_root_raise_and_insert(
on the root page; when the function returns,
the cursor is positioned on the predecessor
of the inserted record */
+ ulint** offsets,/*!< out: offsets on inserted record */
+ mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
const dtuple_t* tuple, /*!< in: tuple to insert */
ulint n_ext, /*!< in: number of externally stored columns */
mtr_t* mtr) /*!< in: mtr */
@@ -1873,7 +1875,6 @@ btr_root_raise_and_insert(
page_t* new_page;
ulint new_page_no;
rec_t* rec;
- mem_heap_t* heap;
dtuple_t* node_ptr;
ulint level;
rec_t* node_ptr_rec;
@@ -1958,7 +1959,9 @@ btr_root_raise_and_insert(
lock_update_root_raise(new_block, root_block);
/* Create a memory heap where the node pointer is stored */
- heap = mem_heap_create(100);
+ if (!*heap) {
+ *heap = mem_heap_create(1000);
+ }
rec = page_rec_get_next(page_get_infimum_rec(new_page));
new_page_no = buf_block_get_page_no(new_block);
@@ -1966,8 +1969,8 @@ btr_root_raise_and_insert(
/* Build the node pointer (= node key and page address) for the
child */
- node_ptr = dict_index_build_node_ptr(index, rec, new_page_no, heap,
- level);
+ node_ptr = dict_index_build_node_ptr(
+ index, rec, new_page_no, *heap, level);
/* The node pointer must be marked as the predefined minimum record,
as there is no lower alphabetical limit to records in the leftmost
node of a level: */
@@ -1993,15 +1996,12 @@ btr_root_raise_and_insert(
page_cur_set_before_first(root_block, page_cursor);
node_ptr_rec = page_cur_tuple_insert(page_cursor, node_ptr,
- index, 0, mtr);
+ index, offsets, heap, 0, mtr);
/* The root page should only contain the node pointer
to new_page at this point. Thus, the data should fit. */
ut_a(node_ptr_rec);
- /* Free the memory heap */
- mem_heap_free(heap);
-
/* We play safe and reset the free bits for the new page */
#if 0
@@ -2017,7 +2017,8 @@ btr_root_raise_and_insert(
PAGE_CUR_LE, page_cursor);
/* Split the child and insert tuple */
- return(btr_page_split_and_insert(flags, cursor, tuple, n_ext, mtr));
+ return(btr_page_split_and_insert(flags, cursor, offsets, heap,
+ tuple, n_ext, mtr));
}
/*************************************************************//**
@@ -2245,9 +2246,9 @@ func_exit:
/*************************************************************//**
Returns TRUE if the insert fits on the appropriate half-page with the
chosen split_rec.
-@return TRUE if fits */
-static
-ibool
+@return true if fits */
+static __attribute__((nonnull(1,3,4,6), warn_unused_result))
+bool
btr_page_insert_fits(
/*=================*/
btr_cur_t* cursor, /*!< in: cursor at which insert
@@ -2255,11 +2256,11 @@ btr_page_insert_fits(
const rec_t* split_rec,/*!< in: suggestion for first record
on upper half-page, or NULL if
tuple to be inserted should be first */
- const ulint* offsets,/*!< in: rec_get_offsets(
- split_rec, cursor->index) */
+ ulint** offsets,/*!< in: rec_get_offsets(
+ split_rec, cursor->index); out: garbage */
const dtuple_t* tuple, /*!< in: tuple to insert */
ulint n_ext, /*!< in: number of externally stored columns */
- mem_heap_t* heap) /*!< in: temporary memory heap */
+ mem_heap_t** heap) /*!< in: temporary memory heap */
{
page_t* page;
ulint insert_size;
@@ -2268,15 +2269,13 @@ btr_page_insert_fits(
ulint total_n_recs;
const rec_t* rec;
const rec_t* end_rec;
- ulint* offs;
page = btr_cur_get_page(cursor);
- ut_ad(!split_rec == !offsets);
- ut_ad(!offsets
- || !page_is_comp(page) == !rec_offs_comp(offsets));
- ut_ad(!offsets
- || rec_offs_validate(split_rec, cursor->index, offsets));
+ ut_ad(!split_rec
+ || !page_is_comp(page) == !rec_offs_comp(*offsets));
+ ut_ad(!split_rec
+ || rec_offs_validate(split_rec, cursor->index, *offsets));
insert_size = rec_get_converted_size(cursor->index, tuple, n_ext);
free_space = page_get_free_space_of_empty(page_is_comp(page));
@@ -2294,7 +2293,7 @@ btr_page_insert_fits(
rec = page_rec_get_next(page_get_infimum_rec(page));
end_rec = page_rec_get_next(btr_cur_get_rec(cursor));
- } else if (cmp_dtuple_rec(tuple, split_rec, offsets) >= 0) {
+ } else if (cmp_dtuple_rec(tuple, split_rec, *offsets) >= 0) {
rec = page_rec_get_next(page_get_infimum_rec(page));
end_rec = split_rec;
@@ -2309,19 +2308,17 @@ btr_page_insert_fits(
/* Ok, there will be enough available space on the
half page where the tuple is inserted */
- return(TRUE);
+ return(true);
}
- offs = NULL;
-
while (rec != end_rec) {
/* In this loop we calculate the amount of reserved
space after rec is removed from page. */
- offs = rec_get_offsets(rec, cursor->index, offs,
- ULINT_UNDEFINED, &heap);
+ *offsets = rec_get_offsets(rec, cursor->index, *offsets,
+ ULINT_UNDEFINED, heap);
- total_data -= rec_offs_size(offs);
+ total_data -= rec_offs_size(*offsets);
total_n_recs--;
if (total_data + page_dir_calc_reserved_space(total_n_recs)
@@ -2330,13 +2327,13 @@ btr_page_insert_fits(
/* Ok, there will be enough available space on the
half page where the tuple is inserted */
- return(TRUE);
+ return(true);
}
rec = page_rec_get_next_const(rec);
}
- return(FALSE);
+ return(false);
}
/*******************************************************//**
@@ -2358,6 +2355,8 @@ btr_insert_on_non_leaf_level_func(
btr_cur_t cursor;
dberr_t err;
rec_t* rec;
+ ulint* offsets = NULL;
+ mem_heap_t* heap = NULL;
ut_ad(level > 0);
@@ -2369,15 +2368,17 @@ btr_insert_on_non_leaf_level_func(
| BTR_NO_LOCKING_FLAG
| BTR_KEEP_SYS_FLAG
| BTR_NO_UNDO_LOG_FLAG,
- &cursor, tuple, &rec,
+ &cursor, &offsets, &heap,
+ tuple, &rec,
&dummy_big_rec, 0, NULL, mtr);
ut_a(err == DB_SUCCESS);
+ mem_heap_free(heap);
}
/**************************************************************//**
Attaches the halves of an index page on the appropriate level in an
index tree. */
-static
+static __attribute__((nonnull))
void
btr_attach_half_pages(
/*==================*/
@@ -2513,13 +2514,13 @@ btr_attach_half_pages(
/*************************************************************//**
Determine if a tuple is smaller than any record on the page.
@return TRUE if smaller */
-static
-ibool
+static __attribute__((nonnull, warn_unused_result))
+bool
btr_page_tuple_smaller(
/*===================*/
btr_cur_t* cursor, /*!< in: b-tree cursor */
const dtuple_t* tuple, /*!< in: tuple to consider */
- ulint* offsets,/*!< in/out: temporary storage */
+ ulint** offsets,/*!< in/out: temporary storage */
ulint n_uniq, /*!< in: number of unique fields
in the index page records */
mem_heap_t** heap) /*!< in/out: heap for offsets */
@@ -2534,11 +2535,11 @@ btr_page_tuple_smaller(
page_cur_move_to_next(&pcur);
first_rec = page_cur_get_rec(&pcur);
- offsets = rec_get_offsets(
- first_rec, cursor->index, offsets,
+ *offsets = rec_get_offsets(
+ first_rec, cursor->index, *offsets,
n_uniq, heap);
- return(cmp_dtuple_rec(tuple, first_rec, offsets) < 0);
+ return(cmp_dtuple_rec(tuple, first_rec, *offsets) < 0);
}
/*************************************************************//**
@@ -2558,6 +2559,8 @@ btr_page_split_and_insert(
btr_cur_t* cursor, /*!< in: cursor at which to insert; when the
function returns, the cursor is positioned
on the predecessor of the inserted record */
+ ulint** offsets,/*!< out: offsets on inserted record */
+ mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
const dtuple_t* tuple, /*!< in: tuple to insert */
ulint n_ext, /*!< in: number of externally stored columns */
mtr_t* mtr) /*!< in: mtr */
@@ -2583,15 +2586,15 @@ btr_page_split_and_insert(
ibool insert_left;
ulint n_iterations = 0;
rec_t* rec;
- mem_heap_t* heap;
ulint n_uniq;
- ulint* offsets;
- heap = mem_heap_create(1024);
+ if (!*heap) {
+ *heap = mem_heap_create(1024);
+ }
n_uniq = dict_index_get_n_unique_in_tree(cursor->index);
func_start:
- mem_heap_empty(heap);
- offsets = NULL;
+ mem_heap_empty(*heap);
+ *offsets = NULL;
ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(cursor->index),
MTR_MEMO_X_LOCK));
@@ -2620,7 +2623,7 @@ func_start:
if (split_rec == NULL) {
insert_left = btr_page_tuple_smaller(
- cursor, tuple, offsets, n_uniq, &heap);
+ cursor, tuple, offsets, n_uniq, heap);
}
} else if (btr_page_get_split_rec_to_right(cursor, &split_rec)) {
direction = FSP_UP;
@@ -2642,7 +2645,7 @@ func_start:
if (page_get_n_recs(page) > 1) {
split_rec = page_get_middle_rec(page);
} else if (btr_page_tuple_smaller(cursor, tuple,
- offsets, n_uniq, &heap)) {
+ offsets, n_uniq, heap)) {
split_rec = page_rec_get_next(
page_get_infimum_rec(page));
} else {
@@ -2665,10 +2668,10 @@ func_start:
if (split_rec) {
first_rec = move_limit = split_rec;
- offsets = rec_get_offsets(split_rec, cursor->index, offsets,
- n_uniq, &heap);
+ *offsets = rec_get_offsets(split_rec, cursor->index, *offsets,
+ n_uniq, heap);
- insert_left = cmp_dtuple_rec(tuple, split_rec, offsets) < 0;
+ insert_left = cmp_dtuple_rec(tuple, split_rec, *offsets) < 0;
if (!insert_left && new_page_zip && n_iterations > 0) {
/* If a compressed page has already been split,
@@ -2715,7 +2718,7 @@ insert_empty:
insert_will_fit = !new_page_zip
&& btr_page_insert_fits(cursor, NULL,
- NULL, tuple, n_ext, heap);
+ offsets, tuple, n_ext, heap);
}
if (insert_will_fit && page_is_leaf(page)) {
@@ -2835,8 +2838,8 @@ insert_empty:
page_cur_search(insert_block, cursor->index, tuple,
PAGE_CUR_LE, page_cursor);
- rec = page_cur_tuple_insert(page_cursor, tuple,
- cursor->index, n_ext, mtr);
+ rec = page_cur_tuple_insert(page_cursor, tuple, cursor->index,
+ offsets, heap, n_ext, mtr);
#ifdef UNIV_ZIP_DEBUG
{
@@ -2866,7 +2869,7 @@ insert_empty:
page_cur_search(insert_block, cursor->index, tuple,
PAGE_CUR_LE, page_cursor);
rec = page_cur_tuple_insert(page_cursor, tuple, cursor->index,
- n_ext, mtr);
+ offsets, heap, n_ext, mtr);
if (rec == NULL) {
/* The insert did not fit on the page: loop back to the
@@ -2907,7 +2910,7 @@ func_exit:
ut_ad(page_validate(buf_block_get_frame(left_block), cursor->index));
ut_ad(page_validate(buf_block_get_frame(right_block), cursor->index));
- mem_heap_free(heap);
+ ut_ad(!rec || rec_offs_validate(rec, cursor->index, *offsets));
return(rec);
}
=== modified file 'storage/innobase/btr/btr0cur.cc'
--- a/storage/innobase/btr/btr0cur.cc revid:marko.makela@stripped82845-kp9aopbl2gjq7ana
+++ b/storage/innobase/btr/btr0cur.cc revid:marko.makela@strippedba8sy6ic
@@ -1054,7 +1054,7 @@ be freed by reorganizing. Differs from b
no heuristics is applied to whether it pays to use CPU time for
reorganizing the page or not.
@return pointer to inserted record if succeed, else NULL */
-static
+static __attribute__((nonnull, warn_unused_result))
rec_t*
btr_cur_insert_if_possible(
/*=======================*/
@@ -1062,6 +1062,8 @@ btr_cur_insert_if_possible(
cursor stays valid */
const dtuple_t* tuple, /*!< in: tuple to insert; the size info need not
have been stored to tuple */
+ ulint** offsets,/*!< out: offsets on *rec */
+ mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
ulint n_ext, /*!< in: number of externally stored columns */
mtr_t* mtr) /*!< in: mtr */
{
@@ -1077,8 +1079,8 @@ btr_cur_insert_if_possible(
page_cursor = btr_cur_get_page_cur(cursor);
/* Now, try the insert */
- rec = page_cur_tuple_insert(page_cursor, tuple,
- cursor->index, n_ext, mtr);
+ rec = page_cur_tuple_insert(page_cursor, tuple, cursor->index,
+ offsets, heap, n_ext, mtr);
if (UNIV_UNLIKELY(!rec)) {
/* If record did not fit, reorganize */
@@ -1088,11 +1090,13 @@ btr_cur_insert_if_possible(
page_cur_search(block, cursor->index, tuple,
PAGE_CUR_LE, page_cursor);
- rec = page_cur_tuple_insert(page_cursor, tuple,
- cursor->index, n_ext, mtr);
+ rec = page_cur_tuple_insert(
+ page_cursor, tuple, cursor->index,
+ offsets, heap, n_ext, mtr);
}
}
+ ut_ad(!rec || rec_offs_validate(rec, cursor->index, *offsets));
return(rec);
}
@@ -1191,6 +1195,8 @@ btr_cur_optimistic_insert(
specified */
btr_cur_t* cursor, /*!< in: cursor on page after which to insert;
cursor stays valid */
+ ulint** offsets,/*!< out: offsets on *rec */
+ mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
dtuple_t* entry, /*!< in/out: entry to insert */
rec_t** rec, /*!< out: pointer to inserted record if
succeed */
@@ -1346,7 +1352,7 @@ fail_err:
{
const rec_t* page_cursor_rec = page_cur_get_rec(page_cursor);
*rec = page_cur_tuple_insert(page_cursor, entry, index,
- n_ext, mtr);
+ offsets, heap, n_ext, mtr);
reorg = page_cursor_rec != page_cur_get_rec(page_cursor);
if (UNIV_UNLIKELY(reorg)) {
@@ -1371,7 +1377,7 @@ fail_err:
page_cur_search(block, index, entry, PAGE_CUR_LE, page_cursor);
*rec = page_cur_tuple_insert(page_cursor, entry, index,
- n_ext, mtr);
+ offsets, heap, n_ext, mtr);
if (UNIV_UNLIKELY(!*rec)) {
if (zip_size != 0) {
@@ -1457,6 +1463,8 @@ btr_cur_pessimistic_insert(
insertion will certainly succeed */
btr_cur_t* cursor, /*!< in: cursor after which to insert;
cursor stays valid */
+ ulint** offsets,/*!< out: offsets on *rec */
+ mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
dtuple_t* entry, /*!< in/out: entry to insert */
rec_t** rec, /*!< out: pointer to inserted record if
succeed */
@@ -1470,7 +1478,6 @@ btr_cur_pessimistic_insert(
dict_index_t* index = cursor->index;
ulint zip_size = dict_table_zip_size(index->table);
big_rec_t* big_rec_vec = NULL;
- mem_heap_t* heap = NULL;
dberr_t err;
ibool dummy_inh;
ibool success;
@@ -1493,8 +1500,9 @@ btr_cur_pessimistic_insert(
cursor->flag = BTR_CUR_BINARY;
- err = btr_cur_optimistic_insert(flags, cursor, entry, rec,
- big_rec, n_ext, thr, mtr);
+ err = btr_cur_optimistic_insert(
+ flags, cursor, offsets, heap, entry, rec,
+ big_rec, n_ext, thr, mtr);
if (err != DB_FAIL) {
return(err);
@@ -1556,14 +1564,10 @@ btr_cur_pessimistic_insert(
/* The page is the root page */
*rec = btr_root_raise_and_insert(
- flags, cursor, entry, n_ext, mtr);
+ flags, cursor, offsets, heap, entry, n_ext, mtr);
} else {
*rec = btr_page_split_and_insert(
- flags, cursor, entry, n_ext, mtr);
- }
-
- if (UNIV_LIKELY_NULL(heap)) {
- mem_heap_free(heap);
+ flags, cursor, offsets, heap, entry, n_ext, mtr);
}
ut_ad(page_rec_get_next(btr_cur_get_rec(cursor)) == *rec);
@@ -2148,7 +2152,8 @@ any_extern:
}
/* There are no externally stored columns in new_entry */
- rec = btr_cur_insert_if_possible(cursor, new_entry, 0/*n_ext*/, mtr);
+ rec = btr_cur_insert_if_possible(
+ cursor, new_entry, offsets, heap, 0/*n_ext*/, mtr);
ut_a(rec); /* <- We calculated above the insert would fit */
if (page_zip && !dict_index_is_clust(index)
@@ -2427,7 +2432,8 @@ make_external:
page_cur_move_to_prev(page_cursor);
- rec = btr_cur_insert_if_possible(cursor, new_entry, n_ext, mtr);
+ rec = btr_cur_insert_if_possible(cursor, new_entry,
+ offsets, heap, n_ext, mtr);
if (rec) {
page_cursor->rec = rec;
@@ -2435,9 +2441,6 @@ make_external:
lock_rec_restore_from_page_infimum(btr_cur_get_block(cursor),
rec, block);
- *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
stored fields */
@@ -2493,11 +2496,13 @@ make_external:
err = btr_cur_pessimistic_insert(BTR_NO_UNDO_LOG_FLAG
| BTR_NO_LOCKING_FLAG
| BTR_KEEP_SYS_FLAG,
- cursor, new_entry, &rec,
+ cursor, offsets, heap,
+ new_entry, &rec,
&dummy_big_rec, n_ext, NULL, mtr);
ut_a(rec);
ut_a(err == DB_SUCCESS);
ut_a(dummy_big_rec == NULL);
+ ut_ad(rec_offs_validate(rec, cursor->index, *offsets));
page_cursor->rec = rec;
if (dict_index_is_sec_or_ibuf(index)) {
@@ -2524,8 +2529,6 @@ make_external:
#endif /* UNIV_ZIP_DEBUG */
page_zip = buf_block_get_page_zip(rec_block);
- *offsets = rec_get_offsets(rec, index, *offsets,
- ULINT_UNDEFINED, heap);
btr_cur_unmark_extern_fields(page_zip,
rec, index, *offsets, mtr);
}
@@ -3167,8 +3170,8 @@ btr_cur_pessimistic_delete(
index, next_rec, buf_block_get_page_no(block),
heap, level);
- btr_insert_on_non_leaf_level(flags, index,
- level + 1, node_ptr, mtr);
+ btr_insert_on_non_leaf_level(
+ flags, index, level + 1, node_ptr, mtr);
}
}
=== modified file 'storage/innobase/ibuf/ibuf0ibuf.cc'
--- a/storage/innobase/ibuf/ibuf0ibuf.cc revid:marko.makela@oracle.com-20120522082845-kp9aopbl2gjq7ana
+++ b/storage/innobase/ibuf/ibuf0ibuf.cc revid:marko.makela@stripped523084804-es3dmpmzba8sy6ic
@@ -3239,6 +3239,7 @@ ibuf_insert_low(
btr_cur_t* cursor;
dtuple_t* ibuf_entry;
mem_heap_t* heap;
+ ulint* offsets = NULL;
ulint buffered;
lint min_n_recs;
rec_t* ins_rec;
@@ -3286,7 +3287,7 @@ ibuf_insert_low(
return(DB_STRONG_FAIL);
}
- heap = mem_heap_create(512);
+ heap = mem_heap_create(1024);
/* Build the entry which contains the space id and the page number
as the first fields and the type information for other fields, and
@@ -3456,9 +3457,11 @@ fail_exit:
cursor = btr_pcur_get_btr_cur(&pcur);
if (mode == BTR_MODIFY_PREV) {
- err = btr_cur_optimistic_insert(BTR_NO_LOCKING_FLAG, cursor,
- ibuf_entry, &ins_rec,
- &dummy_big_rec, 0, thr, &mtr);
+ err = btr_cur_optimistic_insert(
+ BTR_NO_LOCKING_FLAG,
+ cursor, &offsets, &heap,
+ ibuf_entry, &ins_rec,
+ &dummy_big_rec, 0, thr, &mtr);
block = btr_cur_get_block(cursor);
ut_ad(buf_block_get_space(block) == IBUF_SPACE_ID);
@@ -3485,7 +3488,7 @@ fail_exit:
err = btr_cur_pessimistic_insert(BTR_NO_LOCKING_FLAG
| BTR_NO_UNDO_LOG_FLAG,
- cursor,
+ cursor, &offsets, &heap,
ibuf_entry, &ins_rec,
&dummy_big_rec, 0, thr, &mtr);
mutex_exit(&ibuf_pessimistic_insert_mutex);
@@ -3684,7 +3687,7 @@ skip_watch:
/********************************************************************//**
During merge, inserts to an index page a secondary index entry extracted
from the insert buffer. */
-static
+static __attribute__((nonnull))
void
ibuf_insert_to_index_page_low(
/*==========================*/
@@ -3692,6 +3695,8 @@ ibuf_insert_to_index_page_low(
buf_block_t* block, /*!< in/out: index page where the buffered
entry should be placed */
dict_index_t* index, /*!< in: record descriptor */
+ ulint** offsets,/*!< out: offsets on *rec */
+ mem_heap_t* heap, /*!< in/out: memory heap */
mtr_t* mtr, /*!< in/out: mtr */
page_cur_t* page_cur)/*!< in/out: cursor positioned on the record
after which to insert the buffered entry */
@@ -3703,8 +3708,8 @@ ibuf_insert_to_index_page_low(
const page_t* bitmap_page;
ulint old_bits;
- if (UNIV_LIKELY
- (page_cur_tuple_insert(page_cur, entry, index, 0, mtr) != NULL)) {
+ if (page_cur_tuple_insert(
+ page_cur, entry, index, offsets, &heap, 0, mtr) != NULL) {
return;
}
@@ -3715,8 +3720,8 @@ ibuf_insert_to_index_page_low(
/* This time the record must fit */
- if (UNIV_LIKELY
- (page_cur_tuple_insert(page_cur, entry, index, 0, mtr) != NULL)) {
+ if (page_cur_tuple_insert(page_cur, entry, index,
+ offsets, &heap, 0, mtr) != NULL) {
return;
}
@@ -3770,6 +3775,8 @@ ibuf_insert_to_index_page(
ulint low_match;
page_t* page = buf_block_get_frame(block);
rec_t* rec;
+ ulint* offsets;
+ mem_heap_t* heap;
ut_ad(ibuf_inside(mtr));
ut_ad(dtuple_check_typed(entry));
@@ -3820,10 +3827,14 @@ dump:
low_match = page_cur_search(block, index, entry,
PAGE_CUR_LE, &page_cur);
+ heap = mem_heap_create(
+ sizeof(upd_t)
+ + REC_OFFS_HEADER_SIZE * sizeof(*offsets)
+ + dtuple_get_n_fields(entry)
+ * (sizeof(upd_field_t) + sizeof *offsets));
+
if (UNIV_UNLIKELY(low_match == dtuple_get_n_fields(entry))) {
- mem_heap_t* heap;
upd_t* update;
- ulint* offsets;
page_zip_des_t* page_zip;
rec = page_cur_get_rec(&page_cur);
@@ -3832,12 +3843,6 @@ dump:
row_ins_sec_index_entry_by_modify(BTR_MODIFY_LEAF). */
ut_ad(rec_get_deleted_flag(rec, page_is_comp(page)));
- heap = mem_heap_create(
- sizeof(upd_t)
- + REC_OFFS_HEADER_SIZE * sizeof(*offsets)
- + dtuple_get_n_fields(entry)
- * (sizeof(upd_field_t) + sizeof *offsets));
-
offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED,
&heap);
update = row_upd_build_sec_rec_difference_binary(
@@ -3851,9 +3856,7 @@ dump:
Bug #56680 was fixed. */
btr_cur_set_deleted_flag_for_ibuf(
rec, page_zip, FALSE, mtr);
-updated_in_place:
- mem_heap_free(heap);
- return;
+ goto updated_in_place;
}
/* Copy the info bits. Clear the delete-mark. */
@@ -3897,15 +3900,20 @@ updated_in_place:
lock_rec_store_on_page_infimum(block, rec);
page_cur_delete_rec(&page_cur, index, offsets, mtr);
page_cur_move_to_prev(&page_cur);
- mem_heap_free(heap);
- ibuf_insert_to_index_page_low(entry, block, index, mtr,
+ ibuf_insert_to_index_page_low(entry, block, index,
+ &offsets, heap, mtr,
&page_cur);
lock_rec_restore_from_page_infimum(block, rec, block);
} else {
- ibuf_insert_to_index_page_low(entry, block, index, mtr,
+ offsets = NULL;
+ ibuf_insert_to_index_page_low(entry, block, index,
+ &offsets, heap, mtr,
&page_cur);
}
+
+updated_in_place:
+ mem_heap_free(heap);
}
/****************************************************************//**
=== modified file 'storage/innobase/include/btr0btr.h'
--- a/storage/innobase/include/btr0btr.h revid:marko.makela@oracle.com-20120522082845-kp9aopbl2gjq7ana
+++ b/storage/innobase/include/btr0btr.h revid:marko.makela@stripped523084804-es3dmpmzba8sy6ic
@@ -217,7 +217,8 @@ page_t*
btr_root_get(
/*=========*/
dict_index_t* index, /*!< in: index tree */
- mtr_t* mtr); /*!< in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
+ __attribute__((nonnull));
/**************************************************************//**
Gets the height of the B-tree (the level of the root, when the leaf
level is assumed to be 0). The caller must hold an S or X latch on
@@ -290,7 +291,8 @@ UNIV_INLINE
index_id_t
btr_page_get_index_id(
/*==================*/
- const page_t* page); /*!< in: index page */
+ const page_t* page) /*!< in: index page */
+ __attribute__((nonnull, pure, warn_unused_result));
#ifndef UNIV_HOTBACKUP
/********************************************************//**
Gets the node level field in an index page.
@@ -299,16 +301,9 @@ UNIV_INLINE
ulint
btr_page_get_level_low(
/*===================*/
- const page_t* page); /*!< in: index page */
-/********************************************************//**
-Gets the node level field in an index page.
-@return level, leaf level == 0 */
-UNIV_INLINE
-ulint
-btr_page_get_level(
-/*===============*/
- const page_t* page, /*!< in: index page */
- mtr_t* mtr); /*!< in: mini-transaction handle */
+ const page_t* page) /*!< in: index page */
+ __attribute__((nonnull, pure, warn_unused_result));
+#define btr_page_get_level(page, mtr) btr_page_get_level_low(page)
/********************************************************//**
Gets the next index page number.
@return next page number */
@@ -317,7 +312,8 @@ ulint
btr_page_get_next(
/*==============*/
const page_t* page, /*!< in: index page */
- mtr_t* mtr); /*!< in: mini-transaction handle */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
+ __attribute__((nonnull, warn_unused_result));
/********************************************************//**
Gets the previous index page number.
@return prev page number */
@@ -326,7 +322,8 @@ ulint
btr_page_get_prev(
/*==============*/
const page_t* page, /*!< in: index page */
- mtr_t* mtr); /*!< in: mini-transaction handle */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
+ __attribute__((nonnull, warn_unused_result));
/*************************************************************//**
Gets pointer to the previous user record in the tree. It is assumed
that the caller has appropriate latches on the page and its neighbor.
@@ -336,8 +333,9 @@ rec_t*
btr_get_prev_user_rec(
/*==================*/
rec_t* rec, /*!< in: record on leaf level */
- mtr_t* mtr); /*!< in: mtr holding a latch on the page, and if
+ mtr_t* mtr) /*!< in: mtr holding a latch on the page, and if
needed, also to the previous page */
+ __attribute__((nonnull, warn_unused_result));
/*************************************************************//**
Gets pointer to the next user record in the tree. It is assumed
that the caller has appropriate latches on the page and its neighbor.
@@ -347,8 +345,9 @@ rec_t*
btr_get_next_user_rec(
/*==================*/
rec_t* rec, /*!< in: record on leaf level */
- mtr_t* mtr); /*!< in: mtr holding a latch on the page, and if
+ mtr_t* mtr) /*!< in: mtr holding a latch on the page, and if
needed, also to the next page */
+ __attribute__((nonnull, warn_unused_result));
/**************************************************************//**
Releases the latch on a leaf page and bufferunfixes it. */
UNIV_INLINE
@@ -358,7 +357,8 @@ btr_leaf_page_release(
buf_block_t* block, /*!< in: buffer block */
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF or
BTR_MODIFY_LEAF */
- mtr_t* mtr); /*!< in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
+ __attribute__((nonnull));
/**************************************************************//**
Gets the child node file address in a node pointer.
NOTE: the offsets array must contain all offsets for the record since
@@ -371,7 +371,8 @@ ulint
btr_node_ptr_get_child_page_no(
/*===========================*/
const rec_t* rec, /*!< in: node pointer record */
- const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ __attribute__((nonnull, pure, warn_unused_result));
/************************************************************//**
Creates the root node for a new index tree.
@return page number of the created root, FIL_NULL if did not succeed */
@@ -385,7 +386,8 @@ btr_create(
or 0 for uncompressed pages */
index_id_t index_id,/*!< in: index id */
dict_index_t* index, /*!< in: index */
- mtr_t* mtr); /*!< in: mini-transaction handle */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
+ __attribute__((nonnull));
/************************************************************//**
Frees a B-tree except the root page, which MUST be freed after this
by calling btr_free_root. */
@@ -407,7 +409,8 @@ btr_free_root(
ulint zip_size, /*!< in: compressed page size in bytes
or 0 for uncompressed pages */
ulint root_page_no, /*!< in: root page number */
- mtr_t* mtr); /*!< in/out: mini-transaction */
+ mtr_t* mtr) /*!< in/out: mini-transaction */
+ __attribute__((nonnull));
/*************************************************************//**
Makes tree one level higher by splitting the root, and inserts
the tuple. It is assumed that mtr contains an x-latch on the tree.
@@ -424,9 +427,12 @@ btr_root_raise_and_insert(
on the root page; when the function returns,
the cursor is positioned on the predecessor
of the inserted record */
+ ulint** offsets,/*!< out: offsets on inserted record */
+ mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
const dtuple_t* tuple, /*!< in: tuple to insert */
ulint n_ext, /*!< in: number of externally stored columns */
- mtr_t* mtr); /*!< in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
+ __attribute__((nonnull, warn_unused_result));
/*************************************************************//**
Reorganizes an index page.
IMPORTANT: if btr_page_reorganize() is invoked on a compressed leaf
@@ -440,7 +446,8 @@ btr_page_reorganize(
/*================*/
buf_block_t* block, /*!< in: page to be reorganized */
dict_index_t* index, /*!< in: record descriptor */
- mtr_t* mtr); /*!< in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
+ __attribute__((nonnull));
/*************************************************************//**
Decides if the page should be split at the convergence point of
inserts converging to left.
@@ -450,9 +457,10 @@ ibool
btr_page_get_split_rec_to_left(
/*===========================*/
btr_cur_t* cursor, /*!< in: cursor at which to insert */
- rec_t** split_rec);/*!< out: if split recommended,
+ rec_t** split_rec)/*!< out: if split recommended,
the first record on upper half page,
or NULL if tuple should be first */
+ __attribute__((nonnull, warn_unused_result));
/*************************************************************//**
Decides if the page should be split at the convergence point of
inserts converging to right.
@@ -462,9 +470,10 @@ ibool
btr_page_get_split_rec_to_right(
/*============================*/
btr_cur_t* cursor, /*!< in: cursor at which to insert */
- rec_t** split_rec);/*!< out: if split recommended,
+ rec_t** split_rec)/*!< out: if split recommended,
the first record on upper half page,
or NULL if tuple should be first */
+ __attribute__((nonnull, warn_unused_result));
/*************************************************************//**
Splits an index page to halves and inserts the tuple. It is assumed
that mtr holds an x-latch to the index tree. NOTE: the tree x-latch is
@@ -482,9 +491,12 @@ btr_page_split_and_insert(
btr_cur_t* cursor, /*!< in: cursor at which to insert; when the
function returns, the cursor is positioned
on the predecessor of the inserted record */
+ ulint** offsets,/*!< out: offsets on inserted record */
+ mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
const dtuple_t* tuple, /*!< in: tuple to insert */
ulint n_ext, /*!< in: number of externally stored columns */
- mtr_t* mtr); /*!< in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
+ __attribute__((nonnull, warn_unused_result));
/*******************************************************//**
Inserts a data tuple to a tree on a non-leaf level. It is assumed
that mtr holds an x-latch on the tree. */
@@ -498,7 +510,8 @@ btr_insert_on_non_leaf_level_func(
dtuple_t* tuple, /*!< in: the record to be inserted */
const char* file, /*!< in: file name */
ulint line, /*!< in: line where called */
- mtr_t* mtr); /*!< in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
+ __attribute__((nonnull));
# define btr_insert_on_non_leaf_level(f,i,l,t,m) \
btr_insert_on_non_leaf_level_func(f,i,l,t,__FILE__,__LINE__,m)
#endif /* !UNIV_HOTBACKUP */
@@ -509,7 +522,8 @@ void
btr_set_min_rec_mark(
/*=================*/
rec_t* rec, /*!< in/out: record */
- mtr_t* mtr); /*!< in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
+ __attribute__((nonnull));
#ifndef UNIV_HOTBACKUP
/*************************************************************//**
Deletes on the upper level the node pointer to a page. */
@@ -519,7 +533,8 @@ btr_node_ptr_delete(
/*================*/
dict_index_t* index, /*!< in: index tree */
buf_block_t* block, /*!< in: page whose node pointer is deleted */
- mtr_t* mtr); /*!< in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
+ __attribute__((nonnull));
#ifdef UNIV_DEBUG
/************************************************************//**
Checks that the node pointer to a page is appropriate.
@@ -530,7 +545,8 @@ btr_check_node_ptr(
/*===============*/
dict_index_t* index, /*!< in: index tree */
buf_block_t* block, /*!< in: index page */
- mtr_t* mtr); /*!< in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
+ __attribute__((nonnull, warn_unused_result));
#endif /* UNIV_DEBUG */
/*************************************************************//**
Tries to merge the page first to the left immediate brother if such a
@@ -564,7 +580,8 @@ btr_discard_page(
/*=============*/
btr_cur_t* cursor, /*!< in: cursor on the page to discard: not on
the root page */
- mtr_t* mtr); /*!< in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
+ __attribute__((nonnull));
#endif /* !UNIV_HOTBACKUP */
/****************************************************************//**
Parses the redo log record for setting an index record as the predefined
@@ -578,7 +595,8 @@ btr_parse_set_min_rec_mark(
byte* end_ptr,/*!< in: buffer end */
ulint comp, /*!< in: nonzero=compact page format */
page_t* page, /*!< in: page or NULL */
- mtr_t* mtr); /*!< in: mtr or NULL */
+ mtr_t* mtr) /*!< in: mtr or NULL */
+ __attribute__((nonnull(1,2), warn_unused_result));
/***********************************************************//**
Parses a redo log record of reorganizing a page.
@return end of log record or NULL */
@@ -590,7 +608,8 @@ btr_parse_page_reorganize(
byte* end_ptr,/*!< in: buffer end */
dict_index_t* index, /*!< in: record descriptor */
buf_block_t* block, /*!< in: page to be reorganized, or NULL */
- mtr_t* mtr); /*!< in: mtr or NULL */
+ mtr_t* mtr) /*!< in: mtr or NULL */
+ __attribute__((nonnull(1,2,3), warn_unused_result));
#ifndef UNIV_HOTBACKUP
/**************************************************************//**
Gets the number of pages in a B-tree.
@@ -636,7 +655,8 @@ btr_page_free(
/*==========*/
dict_index_t* index, /*!< in: index tree */
buf_block_t* block, /*!< in: block to be freed, x-latched */
- mtr_t* mtr); /*!< in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
+ __attribute__((nonnull));
/**************************************************************//**
Frees a file page used in an index tree. Can be used also to BLOB
external storage pages, because the page level 0 can be given as an
@@ -648,7 +668,8 @@ btr_page_free_low(
dict_index_t* index, /*!< in: index tree */
buf_block_t* block, /*!< in: block to be freed, x-latched */
ulint level, /*!< in: page level */
- mtr_t* mtr); /*!< in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
+ __attribute__((nonnull));
#ifdef UNIV_BTR_PRINT
/*************************************************************//**
Prints size info of a B-tree. */
@@ -656,7 +677,8 @@ UNIV_INTERN
void
btr_print_size(
/*===========*/
- dict_index_t* index); /*!< in: index tree */
+ dict_index_t* index) /*!< in: index tree */
+ __attribute__((nonnull));
/**************************************************************//**
Prints directories and other info of all nodes in the index. */
UNIV_INTERN
@@ -664,8 +686,9 @@ void
btr_print_index(
/*============*/
dict_index_t* index, /*!< in: index */
- ulint width); /*!< in: print this many entries from start
+ ulint width) /*!< in: print this many entries from start
and end */
+ __attribute__((nonnull));
#endif /* UNIV_BTR_PRINT */
/************************************************************//**
Checks the size and number of fields in a record based on the definition of
@@ -677,9 +700,10 @@ btr_index_rec_validate(
/*===================*/
const rec_t* rec, /*!< in: index record */
const dict_index_t* index, /*!< in: index */
- ibool dump_on_error); /*!< in: TRUE if the function
+ ibool dump_on_error) /*!< in: TRUE if the function
should print hex dump of record
and page on error */
+ __attribute__((nonnull, warn_unused_result));
/**************************************************************//**
Checks the consistency of an index tree.
@return TRUE if ok */
@@ -688,7 +712,8 @@ ibool
btr_validate_index(
/*===============*/
dict_index_t* index, /*!< in: index */
- trx_t* trx); /*!< in: transaction or NULL */
+ trx_t* trx) /*!< in: transaction or NULL */
+ __attribute__((nonnull(1), warn_unused_result));
#define BTR_N_LEAF_PAGES 1
#define BTR_TOTAL_SIZE 2
=== modified file 'storage/innobase/include/btr0btr.ic'
--- a/storage/innobase/include/btr0btr.ic revid:marko.makela@stripped7ana
+++ b/storage/innobase/include/btr0btr.ic revid:marko.makela@stripped
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -126,22 +126,6 @@ btr_page_get_level_low(
}
/********************************************************//**
-Gets the node level field in an index page.
-@return level, leaf level == 0 */
-UNIV_INLINE
-ulint
-btr_page_get_level(
-/*===============*/
- const page_t* page, /*!< in: index page */
- mtr_t* mtr __attribute__((unused)))
- /*!< in: mini-transaction handle */
-{
- ut_ad(page && mtr);
-
- return(btr_page_get_level_low(page));
-}
-
-/********************************************************//**
Sets the node level field in an index page. */
UNIV_INLINE
void
@@ -278,6 +262,7 @@ btr_node_ptr_get_child_page_no(
" in a node ptr record at offset %lu\n",
(ulong) page_offset(rec));
buf_page_print(page_align(rec), 0, 0);
+ ut_ad(0);
}
return(page_no);
=== modified file 'storage/innobase/include/btr0cur.h'
--- a/storage/innobase/include/btr0cur.h revid:marko.makela@stripped
+++ b/storage/innobase/include/btr0cur.h revid:marko.makela@oracle.com-20120523084804-es3dmpmzba8sy6ic
@@ -212,6 +212,8 @@ btr_cur_optimistic_insert(
specified */
btr_cur_t* cursor, /*!< in: cursor on page after which to insert;
cursor stays valid */
+ ulint** offsets,/*!< out: offsets on *rec */
+ mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
dtuple_t* entry, /*!< in/out: entry to insert */
rec_t** rec, /*!< out: pointer to inserted record if
succeed */
@@ -225,7 +227,7 @@ btr_cur_optimistic_insert(
index in a compressed tablespace, the
mtr must be committed before latching
any further pages */
- __attribute__((nonnull(2,3,4,5,8), warn_unused_result));
+ __attribute__((nonnull(2,3,4,5,6,7,10), warn_unused_result));
/*************************************************************//**
Performs an insert on a page of an index tree. It is assumed that mtr
holds an x-latch on the tree and on the cursor page. If the insert is
@@ -244,6 +246,8 @@ btr_cur_pessimistic_insert(
insertion will certainly succeed */
btr_cur_t* cursor, /*!< in: cursor after which to insert;
cursor stays valid */
+ ulint** offsets,/*!< out: offsets on *rec */
+ mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
dtuple_t* entry, /*!< in/out: entry to insert */
rec_t** rec, /*!< out: pointer to inserted record if
succeed */
@@ -253,7 +257,7 @@ btr_cur_pessimistic_insert(
ulint n_ext, /*!< in: number of externally stored columns */
que_thr_t* thr, /*!< in: query thread or NULL */
mtr_t* mtr) /*!< in: mtr */
- __attribute__((nonnull(2,3,4,5,8), warn_unused_result));
+ __attribute__((nonnull(2,3,4,5,6,7,10), warn_unused_result));
/*************************************************************//**
See if there is enough place in the page modification log to log
an update-in-place.
=== modified file 'storage/innobase/include/page0cur.h'
--- a/storage/innobase/include/page0cur.h revid:marko.makela@oracle.com-20120522082845-kp9aopbl2gjq7ana
+++ b/storage/innobase/include/page0cur.h revid:marko.makela@stripped20523084804-es3dmpmzba8sy6ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2009, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -170,8 +170,11 @@ page_cur_tuple_insert(
page_cur_t* cursor, /*!< in/out: a page cursor */
const dtuple_t* tuple, /*!< in: pointer to a data tuple */
dict_index_t* index, /*!< in: record descriptor */
+ ulint** offsets,/*!< out: offsets on *rec */
+ mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
ulint n_ext, /*!< in: number of externally stored columns */
- mtr_t* mtr); /*!< in: mini-transaction handle, or NULL */
+ mtr_t* mtr) /*!< in: mini-transaction handle, or NULL */
+ __attribute__((nonnull(1,2,3,4,5), warn_unused_result));
#endif /* !UNIV_HOTBACKUP */
/***********************************************************//**
Inserts a record next to page cursor. Returns pointer to inserted record if
=== modified file 'storage/innobase/include/page0cur.ic'
--- a/storage/innobase/include/page0cur.ic revid:marko.makela@oracle.com-20120522082845-kp9aopbl2gjq7ana
+++ b/storage/innobase/include/page0cur.ic revid:marko.makela@stripped120523084804-es3dmpmzba8sy6ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -245,33 +245,36 @@ page_cur_tuple_insert(
page_cur_t* cursor, /*!< in/out: a page cursor */
const dtuple_t* tuple, /*!< in: pointer to a data tuple */
dict_index_t* index, /*!< in: record descriptor */
+ ulint** offsets,/*!< out: offsets on *rec */
+ mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
ulint n_ext, /*!< in: number of externally stored columns */
mtr_t* mtr) /*!< in: mini-transaction handle, or NULL */
{
- mem_heap_t* heap;
- ulint* offsets;
ulint size
= rec_get_converted_size(index, tuple, n_ext);
rec_t* rec;
- heap = mem_heap_create(size
- + (4 + REC_OFFS_HEADER_SIZE
- + dtuple_get_n_fields(tuple))
- * sizeof *offsets);
- rec = rec_convert_dtuple_to_rec((byte*) mem_heap_alloc(heap, size),
+ if (!*heap) {
+ *heap = mem_heap_create(size
+ + (4 + REC_OFFS_HEADER_SIZE
+ + dtuple_get_n_fields(tuple))
+ * sizeof **offsets);
+ }
+
+ rec = rec_convert_dtuple_to_rec((byte*) mem_heap_alloc(*heap, size),
index, tuple, n_ext);
- offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
+ *offsets = rec_get_offsets(
+ rec, index, *offsets, ULINT_UNDEFINED, heap);
if (buf_block_get_page_zip(cursor->block)) {
rec = page_cur_insert_rec_zip(&cursor->rec, cursor->block,
- index, rec, offsets, mtr);
+ index, rec, *offsets, mtr);
} else {
rec = page_cur_insert_rec_low(cursor->rec,
- index, rec, offsets, mtr);
+ index, rec, *offsets, mtr);
}
- ut_ad(!rec || !cmp_dtuple_rec(tuple, rec, offsets));
- mem_heap_free(heap);
+ ut_ad(!rec || !cmp_dtuple_rec(tuple, rec, *offsets));
return(rec);
}
#endif /* !UNIV_HOTBACKUP */
=== modified file 'storage/innobase/row/row0ins.cc'
--- a/storage/innobase/row/row0ins.cc revid:marko.makela@strippedp9aopbl2gjq7ana
+++ b/storage/innobase/row/row0ins.cc revid:marko.makela@strippedc
@@ -234,16 +234,16 @@ row_ins_sec_index_entry_by_modify(
depending on whether mtr holds just a leaf
latch or also a tree latch */
btr_cur_t* cursor, /*!< in: B-tree cursor */
+ ulint** offsets,/*!< in/out: offsets on cursor->page_cur.rec */
+ mem_heap_t* heap, /*!< in/out: memory heap */
const dtuple_t* entry, /*!< in: index entry to insert */
que_thr_t* thr, /*!< in: query thread */
mtr_t* mtr) /*!< in: mtr; must be committed before
latching any further pages */
{
big_rec_t* dummy_big_rec;
- mem_heap_t* heap;
upd_t* update;
rec_t* rec;
- ulint* offsets;
dberr_t err;
rec = btr_cur_get_rec(cursor);
@@ -251,29 +251,23 @@ row_ins_sec_index_entry_by_modify(
ut_ad(!dict_index_is_clust(cursor->index));
ut_ad(rec_get_deleted_flag(rec,
dict_table_is_comp(cursor->index->table)));
+ ut_ad(rec_offs_validate(rec, cursor->index, *offsets));
/* We know that in the alphabetical ordering, entry and rec are
identified. But in their binary form there may be differences if
there are char fields in them. Therefore we have to calculate the
difference. */
- heap = mem_heap_create(
- sizeof(upd_t)
- + REC_OFFS_HEADER_SIZE * sizeof(*offsets)
- + dtuple_get_n_fields(entry)
- * (sizeof(upd_field_t) + sizeof *offsets));
- offsets = rec_get_offsets(rec, cursor->index, NULL,
- ULINT_UNDEFINED, &heap);
update = row_upd_build_sec_rec_difference_binary(
- rec, cursor->index, offsets, entry, heap);
+ rec, cursor->index, *offsets, entry, heap);
if (mode == BTR_MODIFY_LEAF) {
/* Try an optimistic updating of the record, keeping changes
within the page */
- /* TODO: pass only offsets, no &offsets, &heap */
+ /* TODO: pass only *offsets */
err = btr_cur_optimistic_update(
BTR_KEEP_SYS_FLAG, cursor,
- &offsets, &heap, update, 0, thr,
+ offsets, &heap, update, 0, thr,
thr_get_trx(thr)->id, mtr);
switch (err) {
case DB_OVERFLOW:
@@ -287,19 +281,15 @@ row_ins_sec_index_entry_by_modify(
ut_a(mode == BTR_MODIFY_TREE);
if (buf_LRU_buf_pool_running_out()) {
- err = DB_LOCK_TABLE_FULL;
-
- goto func_exit;
+ return(DB_LOCK_TABLE_FULL);
}
err = btr_cur_pessimistic_update(
BTR_KEEP_SYS_FLAG, cursor,
- &offsets, &heap, &dummy_big_rec, update, 0, thr,
+ offsets, &heap, &dummy_big_rec, update, 0, thr,
thr_get_trx(thr)->id, mtr);
ut_ad(!dummy_big_rec);
}
-func_exit:
- mem_heap_free(heap);
return(err);
}
@@ -2273,7 +2263,8 @@ err_exit:
if (mode != BTR_MODIFY_TREE) {
ut_ad(mode == BTR_MODIFY_LEAF);
err = btr_cur_optimistic_insert(
- 0, &cursor, entry, &insert_rec, &big_rec,
+ 0, &cursor, &offsets, &heap,
+ entry, &insert_rec, &big_rec,
n_ext, thr, &mtr);
} else {
if (buf_LRU_buf_pool_running_out()) {
@@ -2282,7 +2273,8 @@ err_exit:
goto err_exit;
}
err = btr_cur_pessimistic_insert(
- 0, &cursor, entry, &insert_rec, &big_rec,
+ 0, &cursor, &offsets, &heap,
+ entry, &insert_rec, &big_rec,
n_ext, thr, &mtr);
}
@@ -2301,9 +2293,10 @@ err_exit:
}
}
- if (UNIV_LIKELY_NULL(heap)) {
+ if (heap) {
mem_heap_free(heap);
}
+
return(err);
}
@@ -2321,6 +2314,7 @@ row_ins_sec_index_entry_low(
depending on whether we wish optimistic or
pessimistic descent down the index tree */
dict_index_t* index, /*!< in: secondary index */
+ mem_heap_t* heap, /*!< in/out: memory heap */
dtuple_t* entry, /*!< in/out: index entry to insert */
que_thr_t* thr) /*!< in: query thread */
{
@@ -2329,6 +2323,7 @@ row_ins_sec_index_entry_low(
dberr_t err;
ulint n_unique;
mtr_t mtr;
+ ulint* offsets = NULL;
ut_ad(!dict_index_is_clust(index));
ut_ad(!dict_index_is_online_ddl(index));
@@ -2403,16 +2398,20 @@ row_ins_sec_index_entry_low(
/* There is already an index entry with a long enough common
prefix, we must convert the insert into a modify of an
existing record */
+ offsets = rec_get_offsets(
+ btr_cur_get_rec(&cursor), index, offsets,
+ ULINT_UNDEFINED, &heap);
err = row_ins_sec_index_entry_by_modify(
- mode, &cursor, entry, thr, &mtr);
+ mode, &cursor, &offsets, heap, entry, thr, &mtr);
} else {
rec_t* insert_rec;
big_rec_t* big_rec;
if (mode == BTR_MODIFY_LEAF) {
err = btr_cur_optimistic_insert(
- 0, &cursor, entry, &insert_rec,
+ 0, &cursor, &offsets, &heap,
+ entry, &insert_rec,
&big_rec, 0, thr, &mtr);
} else {
ut_ad(mode == BTR_MODIFY_TREE);
@@ -2421,7 +2420,8 @@ row_ins_sec_index_entry_low(
err = DB_LOCK_TABLE_FULL;
} else {
err = btr_cur_pessimistic_insert(
- 0, &cursor, entry, &insert_rec,
+ 0, &cursor, &offsets, &heap,
+ entry, &insert_rec,
&big_rec, 0, thr, &mtr);
}
}
@@ -2536,7 +2536,8 @@ row_ins_sec_index_entry(
dtuple_t* entry, /*!< in/out: index entry to insert */
que_thr_t* thr) /*!< in: query thread */
{
- dberr_t err;
+ dberr_t err;
+ mem_heap_t* heap;
if (UT_LIST_GET_FIRST(index->table->foreign_list)) {
err = row_ins_check_foreign_constraints(index->table, index,
@@ -2552,18 +2553,23 @@ row_ins_sec_index_entry(
return(DB_SUCCESS);
}
+ heap = mem_heap_create(1024);
+
/* Try first optimistic descent to the B-tree */
- err = row_ins_sec_index_entry_low(BTR_MODIFY_LEAF, index, entry, thr);
- if (err != DB_FAIL) {
+ err = row_ins_sec_index_entry_low(BTR_MODIFY_LEAF, index, heap,
+ entry, thr);
+ if (err == DB_FAIL) {
+ mem_heap_empty(heap);
- return(err);
- }
+ /* Try then pessimistic descent to the B-tree */
- /* Try then pessimistic descent to the B-tree */
+ err = row_ins_sec_index_entry_low(
+ BTR_MODIFY_TREE, index, heap, entry, thr);
+ }
- return(row_ins_sec_index_entry_low(
- BTR_MODIFY_TREE, index, entry, thr));
+ mem_heap_free(heap);
+ return(err);
}
/***************************************************************//**
=== modified file 'storage/innobase/row/row0log.cc'
--- a/storage/innobase/row/row0log.cc revid:marko.makela@stripped
+++ b/storage/innobase/row/row0log.cc revid:marko.makela@strippedm-20120523084804-es3dmpmzba8sy6ic
@@ -105,32 +105,11 @@ row_log_online_op(
== (op == ROW_OP_PURGE));
#endif /* UNIV_SYNC_DEBUG */
-#ifdef UNIV_DEBUG
- switch (op) {
- case ROW_OP_INSERT:
- case ROW_OP_DELETE_MARK:
- case ROW_OP_DELETE_UNMARK:
- case ROW_OP_DELETE_PURGE:
- ut_ad(trx_id);
- /* fall through */
- case ROW_OP_PURGE:
- goto op_ok;
- }
-op_ok:
-#endif /* UNIV_DEBUG */
if (dict_index_is_corrupted(index)) {
return;
}
ut_ad(dict_index_is_online_ddl(index));
- mutex_enter(&index->online_log->mutex);
-
- if (trx_id > index->online_log->max_trx) {
- index->online_log->max_trx = trx_id;
- }
-
- log = index->online_log;
- UNIV_MEM_INVALID(log->tail.buf, sizeof log->tail.buf);
/* Compute the size of the record. This differs from
row_merge_buf_encode(), because here we do not encode
@@ -150,15 +129,33 @@ op_ok:
case ROW_OP_DELETE_MARK:
case ROW_OP_DELETE_UNMARK:
case ROW_OP_DELETE_PURGE:
+#ifdef UNIV_SYNC_DEBUG
+ ut_ad(rw_lock_own(dict_index_get_lock(index), RW_LOCK_SHARED));
+#endif /* UNIV_SYNC_DEBUG */
+ ut_ad(trx_id);
mrec_size = ROW_LOG_HEADER_SIZE + DATA_TRX_ID_LEN
+ (extra_size >= 0x80) + size;
- break;
+ goto op_ok;
case ROW_OP_PURGE:
+#ifdef UNIV_SYNC_DEBUG
+ ut_ad(rw_lock_own(dict_index_get_lock(index), RW_LOCK_EX));
+#endif /* UNIV_SYNC_DEBUG */
mrec_size = ROW_LOG_HEADER_SIZE
+ (extra_size >= 0x80) + size;
- break;
+ goto op_ok;
}
+ ut_error;
+op_ok:
+ log = index->online_log;
+ mutex_enter(&log->mutex);
+
+ if (trx_id > log->max_trx) {
+ log->max_trx = trx_id;
+ }
+
+ UNIV_MEM_INVALID(log->tail.buf, sizeof log->tail.buf);
+
ut_ad(log->tail.bytes < srv_sort_buf_size);
avail_size = srv_sort_buf_size - log->tail.bytes;
@@ -215,7 +212,7 @@ op_ok:
UNIV_MEM_ASSERT_RW(log->tail.block, srv_sort_buf_size);
ret = os_file_write(
"(modification log)",
- OS_FILE_FROM_FD(index->online_log->fd),
+ OS_FILE_FROM_FD(log->fd),
log->tail.block, byte_offset, srv_sort_buf_size);
log->tail.blocks++;
if (!ret) {
@@ -235,7 +232,7 @@ write_failed:
}
UNIV_MEM_INVALID(log->tail.buf, sizeof log->tail.buf);
- mutex_exit(&index->online_log->mutex);
+ mutex_exit(&log->mutex);
}
/******************************************************//**
@@ -572,7 +569,7 @@ insert_the_rec:
BTR_NO_UNDO_LOG_FLAG
| BTR_NO_LOCKING_FLAG
| BTR_CREATE_FLAG,
- &cursor,
+ &cursor, &offsets, &heap,
const_cast<dtuple_t*>(entry),
&rec, &big_rec,
0, NULL, &mtr);
@@ -599,7 +596,7 @@ insert_the_rec:
BTR_NO_UNDO_LOG_FLAG
| BTR_NO_LOCKING_FLAG
| BTR_CREATE_FLAG,
- &cursor,
+ &cursor, &offsets, &heap,
const_cast<dtuple_t*>(entry),
&rec, &big_rec,
0, NULL, &mtr);
=== modified file 'storage/innobase/row/row0merge.cc'
--- a/storage/innobase/row/row0merge.cc revid:marko.makela@stripped
+++ b/storage/innobase/row/row0merge.cc revid:marko.makela@strippedom-20120523084804-es3dmpmzba8sy6ic
@@ -2155,6 +2155,7 @@ row_merge_insert_index_tuples(
const byte* b;
mem_heap_t* heap;
mem_heap_t* tuple_heap;
+ mem_heap_t* ins_heap;
dberr_t error = DB_SUCCESS;
ulint foffs = 0;
ulint* offsets;
@@ -2170,6 +2171,7 @@ row_merge_insert_index_tuples(
ulint i = 1 + REC_OFFS_HEADER_SIZE
+ dict_index_get_n_fields(index);
heap = mem_heap_create(sizeof *buf + i * sizeof *offsets);
+ ins_heap = mem_heap_create(sizeof *buf + i * sizeof *offsets);
offsets = static_cast<ulint*>(
mem_heap_alloc(heap, i * sizeof *offsets));
offsets[0] = i;
@@ -2246,12 +2248,13 @@ row_merge_insert_index_tuples(
> 0);
}
#endif /* UNIV_DEBUG */
+ ulint* ins_offsets = NULL;
error = btr_cur_optimistic_insert(
BTR_NO_UNDO_LOG_FLAG | BTR_NO_LOCKING_FLAG
| BTR_KEEP_SYS_FLAG | BTR_CREATE_FLAG,
- &cursor, dtuple, &rec, &big_rec,
- 0, NULL, &mtr);
+ &cursor, &ins_offsets, &ins_heap,
+ dtuple, &rec, &big_rec, 0, NULL, &mtr);
if (error == DB_FAIL) {
ut_ad(!big_rec);
@@ -2270,8 +2273,8 @@ row_merge_insert_index_tuples(
BTR_NO_UNDO_LOG_FLAG
| BTR_NO_LOCKING_FLAG
| BTR_KEEP_SYS_FLAG | BTR_CREATE_FLAG,
- &cursor, dtuple, &rec, &big_rec,
- 0, NULL, &mtr);
+ &cursor, &ins_offsets, &ins_heap,
+ dtuple, &rec, &big_rec, 0, NULL, &mtr);
}
if (!dict_index_is_clust(index)) {
@@ -2294,7 +2297,8 @@ row_merge_insert_index_tuples(
ut_ad(dict_index_is_clust(index));
ut_ad(error == DB_SUCCESS);
error = row_ins_index_entry_big_rec(
- dtuple, big_rec, offsets, &tuple_heap,
+ dtuple, big_rec,
+ ins_offsets, &ins_heap,
index, NULL, __FILE__, __LINE__);
dtuple_convert_back_big_rec(
index, dtuple, big_rec);
@@ -2305,11 +2309,13 @@ row_merge_insert_index_tuples(
}
mem_heap_empty(tuple_heap);
+ mem_heap_empty(ins_heap);
}
}
err_exit:
mem_heap_free(tuple_heap);
+ mem_heap_free(ins_heap);
mem_heap_free(heap);
return(error);
No bundle (reason: useless for push emails).| Thread |
|---|
| • bzr push into mysql-trunk-wl6255 branch (marko.makela:3852 to 3855) WL#6255 | marko.makela | 23 May |