3862 Marko Mäkelä 2012-05-24
Fix errors in the rec_get_offsets() elimination.
btr_root_raise_and_insert(), btr_page_split_and_insert(),
btr_cur_pessimistic_insert(): Note that the memory heap for offsets
can be emptied.
btr_cur_pessimistic_update(), row_ins_sec_index_entry_by_modify(),
row_ins_sec_index_entry_low(), row_log_apply_op_low(),
row_log_apply_op(), row_undo_mod_clust_low(): Add offsets_heap for
allocating offsets only. Note that it can be emptied.
modified:
storage/innobase/btr/btr0cur.cc
storage/innobase/ibuf/ibuf0ibuf.cc
storage/innobase/include/btr0btr.h
storage/innobase/include/btr0cur.h
storage/innobase/row/row0ins.cc
storage/innobase/row/row0log.cc
storage/innobase/row/row0umod.cc
storage/innobase/row/row0upd.cc
3861 Marko Mäkelä 2012-05-24
Fix a bug in rec_get_offsets() elimination.
btr_cur_pessimistic_update(): Allocate new_entry from a separate heap,
because the heap for offsets can be emptied.
modified:
storage/innobase/btr/btr0cur.cc
=== modified file 'storage/innobase/btr/btr0cur.cc'
--- a/storage/innobase/btr/btr0cur.cc revid:marko.makela@stripped4095608-1sdgx11fliddh4va
+++ b/storage/innobase/btr/btr0cur.cc revid:marko.makela@strippedsb9upilai2
@@ -1464,7 +1464,8 @@ btr_cur_pessimistic_insert(
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 */
+ mem_heap_t** heap, /*!< in/out: pointer to memory heap
+ that can be emptied, or NULL */
dtuple_t* entry, /*!< in/out: entry to insert */
rec_t** rec, /*!< out: pointer to inserted record if
succeed */
@@ -2230,7 +2231,12 @@ btr_cur_pessimistic_update(
cursor may become invalid if *big_rec == NULL
|| !(flags & BTR_KEEP_POS_FLAG) */
ulint** offsets,/*!< out: offsets on cursor->page_cur.rec */
- mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
+ mem_heap_t** offsets_heap,
+ /*!< in/out: pointer to memory heap
+ that can be emptied, or NULL */
+ mem_heap_t* entry_heap,
+ /*!< in/out: memory heap for allocating
+ big_rec and the index tuple */
big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
be stored externally by the caller, or NULL */
const upd_t* update, /*!< in: update vector; this is allowed also
@@ -2283,7 +2289,7 @@ btr_cur_pessimistic_update(
| BTR_CREATE_FLAG | BTR_KEEP_SYS_FLAG));
optim_err = btr_cur_optimistic_update(
- flags, cursor, offsets, heap, update,
+ flags, cursor, offsets, offsets_heap, update,
cmpl_info, thr, trx_id, mtr);
switch (optim_err) {
@@ -2326,13 +2332,10 @@ btr_cur_pessimistic_update(
}
*offsets = rec_get_offsets(
- rec, index, *offsets, ULINT_UNDEFINED, heap);
+ rec, index, *offsets, ULINT_UNDEFINED, offsets_heap);
- mem_heap_t* new_entry_heap = mem_heap_create(
- rec_offs_size(*offsets)
- + DTUPLE_EST_ALLOC(rec_offs_n_fields(*offsets)));
dtuple_t* new_entry = row_rec_to_index_entry(
- ROW_COPY_DATA, rec, index, *offsets, &n_ext, new_entry_heap);
+ ROW_COPY_DATA, rec, index, *offsets, &n_ext, entry_heap);
/* The page containing the clustered index record
corresponding to new_entry is latched in mtr. If the
@@ -2341,7 +2344,7 @@ btr_cur_pessimistic_update(
purge would also have removed the clustered index record
itself. Thus the following call is safe. */
row_upd_index_replace_new_col_vals_index_pos(new_entry, index, update,
- FALSE, *heap);
+ FALSE, entry_heap);
if (!(flags & BTR_KEEP_SYS_FLAG)) {
row_upd_index_entry_sys_field(new_entry, index, DATA_ROLL_PTR,
roll_ptr);
@@ -2370,7 +2373,7 @@ btr_cur_pessimistic_update(
ut_ad(!page_is_comp(page) || !rec_get_node_ptr_flag(rec));
ut_ad(rec_offs_validate(rec, index, *offsets));
- n_ext += btr_push_update_extern_fields(new_entry, update, *heap);
+ n_ext += btr_push_update_extern_fields(new_entry, update, entry_heap);
if (page_zip) {
ut_ad(page_is_comp(page));
@@ -2421,7 +2424,7 @@ make_external:
page_cur_move_to_prev(page_cursor);
rec = btr_cur_insert_if_possible(cursor, new_entry,
- offsets, heap, n_ext, mtr);
+ offsets, offsets_heap, n_ext, mtr);
if (rec) {
page_cursor->rec = rec;
@@ -2485,7 +2488,7 @@ make_external:
err = btr_cur_pessimistic_insert(BTR_NO_UNDO_LOG_FLAG
| BTR_NO_LOCKING_FLAG
| BTR_KEEP_SYS_FLAG,
- cursor, offsets, heap,
+ cursor, offsets, offsets_heap,
new_entry, &rec,
&dummy_big_rec, n_ext, NULL, mtr);
ut_a(rec);
@@ -2536,7 +2539,6 @@ make_external:
}
return_after_reservations:
- mem_heap_free(new_entry_heap);
#ifdef UNIV_ZIP_DEBUG
ut_a(!page_zip || page_zip_validate(page_zip, page));
#endif /* UNIV_ZIP_DEBUG */
=== modified file 'storage/innobase/ibuf/ibuf0ibuf.cc'
--- a/storage/innobase/ibuf/ibuf0ibuf.cc revid:marko.makela@oracle.com-20120524095608-1sdgx11fliddh4va
+++ b/storage/innobase/ibuf/ibuf0ibuf.cc revid:marko.makela@stripped20120524111223-1l0272sb9upilai2
@@ -3238,6 +3238,7 @@ ibuf_insert_low(
btr_pcur_t pcur;
btr_cur_t* cursor;
dtuple_t* ibuf_entry;
+ mem_heap_t* offsets_heap = NULL;
mem_heap_t* heap;
ulint* offsets = NULL;
ulint buffered;
@@ -3459,7 +3460,7 @@ fail_exit:
if (mode == BTR_MODIFY_PREV) {
err = btr_cur_optimistic_insert(
BTR_NO_LOCKING_FLAG,
- cursor, &offsets, &heap,
+ cursor, &offsets, &offsets_heap,
ibuf_entry, &ins_rec,
&dummy_big_rec, 0, thr, &mtr);
block = btr_cur_get_block(cursor);
@@ -3486,11 +3487,11 @@ fail_exit:
root = ibuf_tree_root_get(&mtr);
- err = btr_cur_pessimistic_insert(BTR_NO_LOCKING_FLAG
- | BTR_NO_UNDO_LOG_FLAG,
- cursor, &offsets, &heap,
- ibuf_entry, &ins_rec,
- &dummy_big_rec, 0, thr, &mtr);
+ err = btr_cur_pessimistic_insert(
+ BTR_NO_LOCKING_FLAG | BTR_NO_UNDO_LOG_FLAG,
+ cursor, &offsets, &offsets_heap,
+ ibuf_entry, &ins_rec,
+ &dummy_big_rec, 0, thr, &mtr);
mutex_exit(&ibuf_pessimistic_insert_mutex);
ibuf_size_update(root, &mtr);
mutex_exit(&ibuf_mutex);
@@ -3500,6 +3501,10 @@ fail_exit:
ut_ad(buf_block_get_space(block) == IBUF_SPACE_ID);
}
+ if (offsets_heap) {
+ mem_heap_free(offsets_heap);
+ }
+
if (err == DB_SUCCESS && op != IBUF_OP_DELETE) {
/* Update the page max trx id field */
page_update_max_trx_id(block, NULL,
=== modified file 'storage/innobase/include/btr0btr.h'
--- a/storage/innobase/include/btr0btr.h revid:marko.makela@stripped
+++ b/storage/innobase/include/btr0btr.h revid:marko.makela@oracle.com-20120524111223-1l0272sb9upilai2
@@ -428,7 +428,8 @@ btr_root_raise_and_insert(
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 */
+ mem_heap_t** heap, /*!< in/out: pointer to memory heap
+ that can be emptied, or NULL */
const dtuple_t* tuple, /*!< in: tuple to insert */
ulint n_ext, /*!< in: number of externally stored columns */
mtr_t* mtr) /*!< in: mtr */
@@ -492,7 +493,8 @@ btr_page_split_and_insert(
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 */
+ mem_heap_t** heap, /*!< in/out: pointer to memory heap
+ that can be emptied, or NULL */
const dtuple_t* tuple, /*!< in: tuple to insert */
ulint n_ext, /*!< in: number of externally stored columns */
mtr_t* mtr) /*!< in: mtr */
=== modified file 'storage/innobase/include/btr0cur.h'
--- a/storage/innobase/include/btr0cur.h revid:marko.makela@stripped1fliddh4va
+++ b/storage/innobase/include/btr0cur.h revid:marko.makela@stripped
@@ -247,7 +247,8 @@ btr_cur_pessimistic_insert(
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 */
+ mem_heap_t** heap, /*!< in/out: pointer to memory heap
+ that can be emptied, or NULL */
dtuple_t* entry, /*!< in/out: entry to insert */
rec_t** rec, /*!< out: pointer to inserted record if
succeed */
@@ -339,7 +340,12 @@ btr_cur_pessimistic_update(
cursor may become invalid if *big_rec == NULL
|| !(flags & BTR_KEEP_POS_FLAG) */
ulint** offsets,/*!< out: offsets on cursor->page_cur.rec */
- mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
+ mem_heap_t** offsets_heap,
+ /*!< in/out: pointer to memory heap
+ that can be emptied, or NULL */
+ mem_heap_t* entry_heap,
+ /*!< in/out: memory heap for allocating
+ big_rec and the index tuple */
big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
be stored externally by the caller, or NULL */
const upd_t* update, /*!< in: update vector; this is allowed also
@@ -352,7 +358,7 @@ btr_cur_pessimistic_update(
trx_id_t trx_id, /*!< in: transaction id */
mtr_t* mtr) /*!< in: mtr; must be committed before
latching any further pages */
- __attribute__((warn_unused_result, nonnull(2,3,4,5,6,10)));
+ __attribute__((warn_unused_result, nonnull(2,3,4,5,6,7,11)));
/***********************************************************//**
Marks a clustered index record deleted. Writes an undo log record to
undo log on this delete marking. Writes in the trx id field the id
=== modified file 'storage/innobase/row/row0ins.cc'
--- a/storage/innobase/row/row0ins.cc revid:marko.makela@oracle.com-20120524095608-1sdgx11fliddh4va
+++ b/storage/innobase/row/row0ins.cc revid:marko.makela@stripped20524111223-1l0272sb9upilai2
@@ -235,6 +235,8 @@ row_ins_sec_index_entry_by_modify(
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* offsets_heap,
+ /*!< in/out: memory heap that can be emptied */
mem_heap_t* heap, /*!< in/out: memory heap */
const dtuple_t* entry, /*!< in: index entry to insert */
que_thr_t* thr, /*!< in: query thread */
@@ -267,7 +269,7 @@ row_ins_sec_index_entry_by_modify(
/* TODO: pass only *offsets */
err = btr_cur_optimistic_update(
BTR_KEEP_SYS_FLAG, cursor,
- offsets, &heap, update, 0, thr,
+ offsets, &offsets_heap, update, 0, thr,
thr_get_trx(thr)->id, mtr);
switch (err) {
case DB_OVERFLOW:
@@ -286,8 +288,9 @@ row_ins_sec_index_entry_by_modify(
err = btr_cur_pessimistic_update(
BTR_KEEP_SYS_FLAG, cursor,
- offsets, &heap, &dummy_big_rec, update, 0, thr,
- thr_get_trx(thr)->id, mtr);
+ offsets, &offsets_heap,
+ heap, &dummy_big_rec, update, 0,
+ thr, thr_get_trx(thr)->id, mtr);
ut_ad(!dummy_big_rec);
}
@@ -308,7 +311,10 @@ row_ins_clust_index_entry_by_modify(
latch or also a tree latch */
btr_cur_t* cursor, /*!< in: B-tree cursor */
ulint** offsets,/*!< out: offsets on cursor->page_cur.rec */
- mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
+ mem_heap_t** offsets_heap,
+ /*!< in/out: pointer to memory heap that can
+ be emptied, or NULL */
+ mem_heap_t* heap, /*!< in/out: memory heap */
big_rec_t** big_rec,/*!< out: possible big rec vector of fields
which have to be stored externally by the
caller */
@@ -330,22 +336,18 @@ row_ins_clust_index_entry_by_modify(
ut_ad(rec_get_deleted_flag(rec,
dict_table_is_comp(cursor->index->table)));
- if (!*heap) {
- *heap = mem_heap_create(1024);
- }
-
/* Build an update vector containing all the fields to be modified;
NOTE that this vector may NOT contain system columns trx_id or
roll_ptr */
update = row_upd_build_difference_binary(cursor->index, entry, rec,
- thr_get_trx(thr), *heap);
+ thr_get_trx(thr), heap);
if (mode == BTR_MODIFY_LEAF) {
/* Try optimistic updating of the record, keeping changes
within the page */
err = btr_cur_optimistic_update(
- 0, cursor, offsets, heap, update, 0, thr,
+ 0, cursor, offsets, offsets_heap, update, 0, thr,
thr_get_trx(thr)->id, mtr);
switch (err) {
case DB_OVERFLOW:
@@ -364,8 +366,8 @@ row_ins_clust_index_entry_by_modify(
}
err = btr_cur_pessimistic_update(
BTR_KEEP_POS_FLAG,
- cursor, offsets, heap, big_rec, update,
- 0, thr, thr_get_trx(thr)->id, mtr);
+ cursor, offsets, offsets_heap, heap,
+ big_rec, update, 0, thr, thr_get_trx(thr)->id, mtr);
}
return(err);
@@ -2142,7 +2144,7 @@ row_ins_clust_index_entry_low(
ulint n_unique;
big_rec_t* big_rec = NULL;
mtr_t mtr;
- mem_heap_t* heap = NULL;
+ mem_heap_t* offsets_heap = NULL;
ut_ad(dict_index_is_clust(index));
@@ -2192,10 +2194,11 @@ err_exit:
/* There is already an index entry with a long enough common
prefix, we must convert the insert into a modify of an
existing record */
+ mem_heap_t* entry_heap = mem_heap_create(1024);
err = row_ins_clust_index_entry_by_modify(
- mode, &cursor, &offsets, &heap, &big_rec, entry,
- thr, &mtr);
+ mode, &cursor, &offsets, &offsets_heap,
+ entry_heap, &big_rec, entry, thr, &mtr);
if (big_rec) {
ut_a(err == DB_SUCCESS);
@@ -2257,13 +2260,14 @@ err_exit:
}
mtr_commit(&mtr);
+ mem_heap_free(entry_heap);
} else {
rec_t* insert_rec;
if (mode != BTR_MODIFY_TREE) {
ut_ad(mode == BTR_MODIFY_LEAF);
err = btr_cur_optimistic_insert(
- 0, &cursor, &offsets, &heap,
+ 0, &cursor, &offsets, &offsets_heap,
entry, &insert_rec, &big_rec,
n_ext, thr, &mtr);
} else {
@@ -2273,7 +2277,7 @@ err_exit:
goto err_exit;
}
err = btr_cur_pessimistic_insert(
- 0, &cursor, &offsets, &heap,
+ 0, &cursor, &offsets, &offsets_heap,
entry, &insert_rec, &big_rec,
n_ext, thr, &mtr);
}
@@ -2286,15 +2290,15 @@ err_exit:
log_make_checkpoint_at(
IB_ULONGLONG_MAX, TRUE););
err = row_ins_index_entry_big_rec(
- entry, big_rec, offsets, &heap, index,
+ entry, big_rec, offsets, &offsets_heap, index,
thr_get_trx(thr)->mysql_thd,
__FILE__, __LINE__);
dtuple_convert_back_big_rec(index, entry, big_rec);
}
}
- if (heap) {
- mem_heap_free(heap);
+ if (offsets_heap) {
+ mem_heap_free(offsets_heap);
}
return(err);
@@ -2314,6 +2318,8 @@ 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* offsets_heap,
+ /*!< in/out: memory heap that can be emptied */
mem_heap_t* heap, /*!< in/out: memory heap */
dtuple_t* entry, /*!< in/out: index entry to insert */
que_thr_t* thr) /*!< in: query thread */
@@ -2403,7 +2409,8 @@ row_ins_sec_index_entry_low(
ULINT_UNDEFINED, &heap);
err = row_ins_sec_index_entry_by_modify(
- mode, &cursor, &offsets, heap, entry, thr, &mtr);
+ mode, &cursor, &offsets,
+ offsets_heap, heap, entry, thr, &mtr);
} else {
rec_t* insert_rec;
big_rec_t* big_rec;
@@ -2537,6 +2544,7 @@ row_ins_sec_index_entry(
que_thr_t* thr) /*!< in: query thread */
{
dberr_t err;
+ mem_heap_t* offsets_heap;
mem_heap_t* heap;
if (UT_LIST_GET_FIRST(index->table->foreign_list)) {
@@ -2553,22 +2561,25 @@ row_ins_sec_index_entry(
return(DB_SUCCESS);
}
+ offsets_heap = mem_heap_create(1024);
heap = mem_heap_create(1024);
/* Try first optimistic descent to the B-tree */
- err = row_ins_sec_index_entry_low(BTR_MODIFY_LEAF, index, heap,
- entry, thr);
+ err = row_ins_sec_index_entry_low(BTR_MODIFY_LEAF, index,
+ offsets_heap, heap, entry, thr);
if (err == DB_FAIL) {
mem_heap_empty(heap);
/* Try then pessimistic descent to the B-tree */
err = row_ins_sec_index_entry_low(
- BTR_MODIFY_TREE, index, heap, entry, thr);
+ BTR_MODIFY_TREE, index,
+ offsets_heap, heap, entry, thr);
}
mem_heap_free(heap);
+ mem_heap_free(offsets_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@oracle.com-20120524111223-1l0272sb9upilai2
@@ -340,6 +340,8 @@ row_log_apply_op_low(
row_merge_dup_t*dup, /*!< in/out: for reporting
duplicate key errors */
dberr_t* error, /*!< out: DB_SUCCESS or error code */
+ mem_heap_t* offsets_heap, /*!< in/out: memory heap for
+ allocating offsets; can be emptied */
mem_heap_t* heap, /*!< in/out: memory heap for
allocating data tuples */
ibool has_index_lock, /*!< in: TRUE if holding index->lock
@@ -388,7 +390,7 @@ row_log_apply_op_low(
ut_ad(page_rec_is_user_rec(rec));
offsets = rec_get_offsets(rec, index, NULL,
- ULINT_UNDEFINED, &heap);
+ ULINT_UNDEFINED, &offsets_heap);
update = row_upd_build_sec_rec_difference_binary(
rec, index, offsets, entry, heap);
@@ -494,7 +496,7 @@ update_the_rec:
| BTR_NO_LOCKING_FLAG
| BTR_CREATE_FLAG
| BTR_KEEP_SYS_FLAG,
- &cursor, &offsets, &heap,
+ &cursor, &offsets, &offsets_heap,
update, 0, NULL, trx_id, &mtr);
if (*error != DB_FAIL) {
@@ -525,8 +527,9 @@ update_the_rec:
| BTR_NO_LOCKING_FLAG
| BTR_CREATE_FLAG
| BTR_KEEP_SYS_FLAG,
- &cursor, &offsets, &heap, &big_rec,
- update, 0, NULL, trx_id, &mtr);
+ &cursor, &offsets, &offsets_heap,
+ heap, &big_rec, update,
+ 0, NULL, trx_id, &mtr);
ut_ad(!big_rec);
break;
@@ -569,7 +572,7 @@ insert_the_rec:
BTR_NO_UNDO_LOG_FLAG
| BTR_NO_LOCKING_FLAG
| BTR_CREATE_FLAG,
- &cursor, &offsets, &heap,
+ &cursor, &offsets, &offsets_heap,
const_cast<dtuple_t*>(entry),
&rec, &big_rec,
0, NULL, &mtr);
@@ -596,7 +599,7 @@ insert_the_rec:
BTR_NO_UNDO_LOG_FLAG
| BTR_NO_LOCKING_FLAG
| BTR_CREATE_FLAG,
- &cursor, &offsets, &heap,
+ &cursor, &offsets, &offsets_heap,
const_cast<dtuple_t*>(entry),
&rec, &big_rec,
0, NULL, &mtr);
@@ -614,6 +617,7 @@ insert_the_rec:
func_exit:
mtr_commit(&mtr);
mem_heap_empty(heap);
+ mem_heap_empty(offsets_heap);
}
/******************************************************//**
@@ -628,6 +632,8 @@ row_log_apply_op(
row_merge_dup_t*dup, /*!< in/out: for reporting
duplicate key errors */
dberr_t* error, /*!< out: DB_SUCCESS or error code */
+ mem_heap_t* offsets_heap, /*!< in/out: memory heap for
+ allocating offsets; can be emptied */
mem_heap_t* heap, /*!< in/out: memory heap for
allocating data tuples */
ibool has_index_lock, /*!< in: TRUE if holding index->lock
@@ -742,8 +748,8 @@ corrupted:
putc('\n', stderr);
}
#endif /* ROW_LOG_APPLY_PRINT */
- row_log_apply_op_low(index, dup, error, heap, has_index_lock,
- op, trx_id, entry);
+ row_log_apply_op_low(index, dup, error, offsets_heap, heap,
+ has_index_lock, op, trx_id, entry);
return(mrec);
}
@@ -765,6 +771,7 @@ row_log_apply_ops(
const mrec_t* next_mrec;
const mrec_t* mrec_end= NULL; /* silence bogus warning */
const mrec_t* next_mrec_end;
+ mem_heap_t* offsets_heap;
mem_heap_t* heap;
ulint* offsets;
ibool has_index_lock;
@@ -783,6 +790,7 @@ row_log_apply_ops(
offsets[0] = i;
offsets[1] = dict_index_get_n_fields(index);
+ offsets_heap = mem_heap_create(UNIV_PAGE_SIZE);
heap = mem_heap_create(UNIV_PAGE_SIZE);
has_index_lock = TRUE;
@@ -892,8 +900,8 @@ all_done:
memcpy((mrec_t*) mrec_end, next_mrec,
(&index->online_log->head.buf)[1] - mrec_end);
mrec = row_log_apply_op(
- index, dup, &error, heap, has_index_lock,
- index->online_log->head.buf,
+ index, dup, &error, offsets_heap, heap,
+ has_index_lock, index->online_log->head.buf,
(&index->online_log->head.buf)[1], offsets);
if (error != DB_SUCCESS) {
goto func_exit;
@@ -980,8 +988,8 @@ all_done:
}
next_mrec = row_log_apply_op(
- index, dup, &error, heap, has_index_lock,
- mrec, mrec_end, offsets);
+ index, dup, &error, offsets_heap, heap,
+ has_index_lock, mrec, mrec_end, offsets);
if (error != DB_SUCCESS) {
goto func_exit;
@@ -1048,6 +1056,7 @@ func_exit:
}
mem_heap_free(heap);
+ mem_heap_free(offsets_heap);
ut_free(offsets);
return(error);
}
=== modified file 'storage/innobase/row/row0umod.cc'
--- a/storage/innobase/row/row0umod.cc revid:marko.makela@stripped
+++ b/storage/innobase/row/row0umod.cc revid:marko.makela@stripped-20120524111223-1l0272sb9upilai2
@@ -107,6 +107,8 @@ row_undo_mod_clust_low(
/*===================*/
undo_node_t* node, /*!< in: row undo node */
ulint** offsets,/*!< out: rec_get_offsets() on the record */
+ mem_heap_t** offsets_heap,
+ /*!< in/out: memory heap that can be emptied */
mem_heap_t* heap, /*!< in/out: memory heap */
que_thr_t* thr, /*!< in: query thread */
mtr_t* mtr, /*!< in: mtr; must be committed before
@@ -135,13 +137,12 @@ row_undo_mod_clust_low(
== thr_get_trx(thr)->id);
if (mode == BTR_MODIFY_LEAF) {
- err = btr_cur_optimistic_update(BTR_NO_LOCKING_FLAG
- | BTR_NO_UNDO_LOG_FLAG
- | BTR_KEEP_SYS_FLAG,
- btr_cur,
- offsets, &heap, node->update,
- node->cmpl_info, thr,
- thr_get_trx(thr)->id, mtr);
+ err = btr_cur_optimistic_update(
+ BTR_NO_LOCKING_FLAG | BTR_NO_UNDO_LOG_FLAG
+ | BTR_KEEP_SYS_FLAG,
+ btr_cur, offsets, offsets_heap,
+ node->update, node->cmpl_info,
+ thr, thr_get_trx(thr)->id, mtr);
} else {
big_rec_t* dummy_big_rec;
@@ -151,7 +152,8 @@ row_undo_mod_clust_low(
BTR_NO_LOCKING_FLAG
| BTR_NO_UNDO_LOG_FLAG
| BTR_KEEP_SYS_FLAG,
- btr_cur, offsets, &heap, &dummy_big_rec, node->update,
+ btr_cur, offsets, offsets_heap, heap,
+ &dummy_big_rec, node->update,
node->cmpl_info, thr, thr_get_trx(thr)->id, mtr);
ut_a(!dummy_big_rec);
@@ -254,14 +256,15 @@ row_undo_mod_clust(
mtr_start(&mtr);
- mem_heap_t* heap = mem_heap_create(1024);
- ulint* offsets = NULL;
+ mem_heap_t* heap = mem_heap_create(1024);
+ mem_heap_t* offsets_heap = NULL;
+ ulint* offsets = NULL;
/* Try optimistic processing of the record, keeping changes within
the index page */
- err = row_undo_mod_clust_low(node, &offsets, heap, thr, &mtr,
- BTR_MODIFY_LEAF);
+ err = row_undo_mod_clust_low(node, &offsets, &offsets_heap,
+ heap, thr, &mtr, BTR_MODIFY_LEAF);
if (err != DB_SUCCESS) {
btr_pcur_commit_specify_mtr(pcur, &mtr);
@@ -271,8 +274,9 @@ row_undo_mod_clust(
mtr_start(&mtr);
- err = row_undo_mod_clust_low(node, &offsets, heap, thr, &mtr,
- BTR_MODIFY_TREE);
+ err = row_undo_mod_clust_low(
+ node, &offsets, &offsets_heap, heap, thr, &mtr,
+ BTR_MODIFY_TREE);
ut_ad(err == DB_SUCCESS || err == DB_OUT_OF_FILE_SPACE);
}
@@ -320,6 +324,9 @@ row_undo_mod_clust(
}
}
+ if (offsets_heap) {
+ mem_heap_free(offsets_heap);
+ }
mem_heap_free(heap);
return(err);
}
@@ -517,6 +524,7 @@ row_undo_mod_del_unmark_sec_and_undo_upd
switch (search_result) {
mem_heap_t* heap;
+ mem_heap_t* offsets_heap;
ulint* offsets;
case ROW_BUFFERED:
case ROW_NOT_DELETED_REF:
@@ -548,11 +556,11 @@ row_undo_mod_del_unmark_sec_and_undo_upd
ut_a(err == DB_SUCCESS);
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(btr_cur_get_rec(btr_cur),
- index, NULL, ULINT_UNDEFINED, &heap);
+ + dtuple_get_n_fields(entry) * sizeof(upd_field_t));
+ offsets_heap = NULL;
+ offsets = rec_get_offsets(
+ btr_cur_get_rec(btr_cur),
+ index, NULL, ULINT_UNDEFINED, &offsets_heap);
update = row_upd_build_sec_rec_difference_binary(
btr_cur_get_rec(btr_cur), index, offsets, entry, heap);
if (upd_get_n_fields(update) == 0) {
@@ -566,8 +574,8 @@ row_undo_mod_del_unmark_sec_and_undo_upd
/* TODO: pass offsets, not &offsets */
err = btr_cur_optimistic_update(
BTR_KEEP_SYS_FLAG | BTR_NO_LOCKING_FLAG,
- btr_cur, &offsets, &heap, update, 0, thr,
- thr_get_trx(thr)->id, &mtr);
+ btr_cur, &offsets, &offsets_heap,
+ update, 0, thr, thr_get_trx(thr)->id, &mtr);
switch (err) {
case DB_OVERFLOW:
case DB_UNDERFLOW:
@@ -580,12 +588,14 @@ row_undo_mod_del_unmark_sec_and_undo_upd
ut_a(mode == BTR_MODIFY_TREE);
err = btr_cur_pessimistic_update(
BTR_KEEP_SYS_FLAG | BTR_NO_LOCKING_FLAG,
- btr_cur, &offsets, &heap, &dummy_big_rec,
+ btr_cur, &offsets, &offsets_heap,
+ heap, &dummy_big_rec,
update, 0, thr, thr_get_trx(thr)->id, &mtr);
ut_a(!dummy_big_rec);
}
mem_heap_free(heap);
+ mem_heap_free(offsets_heap);
}
btr_pcur_close(&pcur);
=== modified file 'storage/innobase/row/row0upd.cc'
--- a/storage/innobase/row/row0upd.cc revid:marko.makela@strippedm-20120524095608-1sdgx11fliddh4va
+++ b/storage/innobase/row/row0upd.cc revid:marko.makela@stripped23-1l0272sb9upilai2
@@ -2066,6 +2066,7 @@ row_upd_clust_rec(
que_thr_t* thr, /*!< in: query thread */
mtr_t* mtr) /*!< in: mtr; gets committed here */
{
+ mem_heap_t* offsets_heap;
mem_heap_t* heap;
big_rec_t* big_rec = NULL;
btr_pcur_t* pcur;
@@ -2083,7 +2084,7 @@ row_upd_clust_rec(
ut_ad(!rec_get_deleted_flag(btr_pcur_get_rec(pcur),
dict_table_is_comp(index->table)));
- heap = mem_heap_create(1024);
+ offsets_heap = NULL;
/* Try optimistic updating of the record, keeping changes within
the page; we do not check locks because we assume the x-lock on the
@@ -2093,7 +2094,7 @@ row_upd_clust_rec(
/* TODO: reuse offsets from caller */
offsets = rec_get_offsets(
btr_cur_get_rec(btr_cur),
- index, offsets, ULINT_UNDEFINED, &heap);
+ index, offsets, ULINT_UNDEFINED, &offsets_heap);
err = btr_cur_update_in_place(
BTR_NO_LOCKING_FLAG, btr_cur,
@@ -2102,7 +2103,7 @@ row_upd_clust_rec(
} else {
err = btr_cur_optimistic_update(
BTR_NO_LOCKING_FLAG, btr_cur,
- &offsets, &heap, node->update,
+ &offsets, &offsets_heap, node->update,
node->cmpl_info, thr, thr_get_trx(thr)->id, mtr);
}
@@ -2134,9 +2135,12 @@ row_upd_clust_rec(
ut_ad(!rec_get_deleted_flag(btr_pcur_get_rec(pcur),
dict_table_is_comp(index->table)));
+ heap = mem_heap_create(1024);
+
err = btr_cur_pessimistic_update(
BTR_NO_LOCKING_FLAG | BTR_KEEP_POS_FLAG, btr_cur,
- &offsets, &heap, &big_rec, node->update, node->cmpl_info,
+ &offsets, &offsets_heap, heap, &big_rec,
+ node->update, node->cmpl_info,
thr, thr_get_trx(thr)->id, mtr);
if (big_rec) {
ut_a(err == DB_SUCCESS);
@@ -2184,8 +2188,11 @@ row_upd_clust_rec(
}
mtr_commit(mtr);
-func_exit:
mem_heap_free(heap);
+func_exit:
+ if (offsets_heap) {
+ mem_heap_free(offsets_heap);
+ }
if (big_rec) {
dtuple_big_rec_free(big_rec);
No bundle (reason: useless for push emails).| Thread |
|---|
| • bzr push into mysql-trunk-wl6255 branch (marko.makela:3861 to 3862) | marko.makela | 24 May |