summaryrefslogtreecommitdiff
path: root/innobase/btr
diff options
context:
space:
mode:
Diffstat (limited to 'innobase/btr')
-rw-r--r--innobase/btr/btr0btr.c29
-rw-r--r--innobase/btr/btr0cur.c110
-rw-r--r--innobase/btr/btr0pcur.c2
3 files changed, 70 insertions, 71 deletions
diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c
index 51c164b7cef..d8a0959e47f 100644
--- a/innobase/btr/btr0btr.c
+++ b/innobase/btr/btr0btr.c
@@ -822,9 +822,16 @@ btr_page_reorganize_low(
{
page_t* new_page;
ulint log_mode;
+ ulint data_size1;
+ ulint data_size2;
+ ulint max_ins_size1;
+ ulint max_ins_size2;
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_X_FIX));
+ data_size1 = page_get_data_size(page);
+ max_ins_size1 = page_get_max_insert_size_after_reorganize(page, 1);
+
/* Write the log record */
mlog_write_initial_log_record(page, MLOG_PAGE_REORGANIZE, mtr);
@@ -859,6 +866,19 @@ btr_page_reorganize_low(
lock_move_reorganize_page(page, new_page);
}
+ data_size2 = page_get_data_size(page);
+ max_ins_size2 = page_get_max_insert_size_after_reorganize(page, 1);
+
+ if (data_size1 != data_size2 || max_ins_size1 != max_ins_size2) {
+ buf_page_print(page);
+ buf_page_print(new_page);
+ fprintf(stderr,
+"InnoDB: Error: page old data size %lu new data size %lu\n"
+"InnoDB: Error: page old max ins size %lu new max ins size %lu\n"
+"InnoDB: Make a detailed bug report and send it to mysql@lists.mysql.com\n",
+ data_size1, data_size2, max_ins_size1, max_ins_size2);
+ }
+
buf_frame_free(new_page);
/* Restore logging mode */
@@ -1945,11 +1965,20 @@ btr_compress(
btr_page_reorganize(merge_page, mtr);
+ max_ins_size = page_get_max_insert_size(merge_page, n_recs);
+
ut_ad(page_validate(merge_page, cursor->index));
ut_ad(page_get_max_insert_size(merge_page, n_recs)
== max_ins_size_reorg);
}
+ if (data_size > max_ins_size) {
+
+ /* Add fault tolerance, though this should never happen */
+
+ return;
+ }
+
btr_search_drop_page_hash_index(page);
/* Remove the page from the level list */
diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c
index 69952c842ce..f6b4a2964f5 100644
--- a/innobase/btr/btr0cur.c
+++ b/innobase/btr/btr0cur.c
@@ -1110,6 +1110,10 @@ btr_cur_pessimistic_insert(
if (big_rec_vec == NULL) {
+ if (n_extents > 0) {
+ fil_space_release_free_extents(index->space,
+ n_extents);
+ }
return(DB_TOO_BIG_RECORD);
}
}
@@ -1367,7 +1371,8 @@ btr_cur_update_sec_rec_in_place(
}
/*****************************************************************
-Updates a record when the update causes no size changes in its fields. */
+Updates a record when the update causes no size changes in its fields.
+We assume here that the ordering fields of the record do not change. */
ulint
btr_cur_update_in_place(
@@ -1458,7 +1463,8 @@ btr_cur_update_in_place(
Tries to update a record on a page in an index tree. It is assumed that mtr
holds an x-latch on the page. The operation does not succeed if there is too
little space on the page or if the update would result in too empty a page,
-so that tree compression is recommended. */
+so that tree compression is recommended. We assume here that the ordering
+fields of the record do not change. */
ulint
btr_cur_optimistic_update(
@@ -1510,10 +1516,11 @@ btr_cur_optimistic_update(
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
MTR_MEMO_PAGE_X_FIX));
- if (!row_upd_changes_field_size(rec, index, update)) {
+ if (!row_upd_changes_field_size_or_external(rec, index, update)) {
- /* The simplest and most common case: the update does not
- change the size of any field */
+ /* The simplest and the most common case: the update does not
+ change the size of any field and none of the updated fields is
+ externally stored in rec or update */
return(btr_cur_update_in_place(flags, cursor, update,
cmpl_info, thr, mtr));
@@ -1542,7 +1549,7 @@ btr_cur_optimistic_update(
new_entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap);
- row_upd_clust_index_replace_new_col_vals(new_entry, update);
+ row_upd_index_replace_new_col_vals(new_entry, index, update, NULL);
old_rec_size = rec_get_size(rec);
new_rec_size = rec_get_converted_size(new_entry);
@@ -1672,54 +1679,13 @@ btr_cur_pess_upd_restore_supremum(
lock_rec_reset_and_inherit_gap_locks(page_get_supremum_rec(prev_page),
rec);
}
-
-/***************************************************************
-Replaces and copies the data in the new column values stored in the
-update vector to the clustered index entry given. */
-static
-void
-btr_cur_copy_new_col_vals(
-/*======================*/
- dtuple_t* entry, /* in/out: index entry where replaced */
- upd_t* update, /* in: update vector */
- mem_heap_t* heap) /* in: heap where data is copied */
-{
- upd_field_t* upd_field;
- dfield_t* dfield;
- dfield_t* new_val;
- ulint field_no;
- byte* data;
- ulint i;
-
- dtuple_set_info_bits(entry, update->info_bits);
-
- for (i = 0; i < upd_get_n_fields(update); i++) {
-
- upd_field = upd_get_nth_field(update, i);
-
- field_no = upd_field->field_no;
-
- dfield = dtuple_get_nth_field(entry, field_no);
-
- new_val = &(upd_field->new_val);
-
- if (new_val->len == UNIV_SQL_NULL) {
- data = NULL;
- } else {
- data = mem_heap_alloc(heap, new_val->len);
-
- ut_memcpy(data, new_val->data, new_val->len);
- }
-
- dfield_set_data(dfield, data, new_val->len);
- }
-}
/*****************************************************************
Performs an update of a record on a page of a tree. It is assumed
that mtr holds an x-latch on the tree and on the cursor page. If the
update is made on the leaf level, to avoid deadlocks, mtr must also
-own x-latches to brothers of page, if those brothers exist. */
+own x-latches to brothers of page, if those brothers exist. We assume
+here that the ordering fields of the record do not change. */
ulint
btr_cur_pessimistic_update(
@@ -1816,7 +1782,7 @@ btr_cur_pessimistic_update(
new_entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap);
- btr_cur_copy_new_col_vals(new_entry, update, heap);
+ row_upd_index_replace_new_col_vals(new_entry, index, update, heap);
if (!(flags & BTR_KEEP_SYS_FLAG)) {
row_upd_index_entry_sys_field(new_entry, index, DATA_ROLL_PTR,
@@ -1825,21 +1791,6 @@ btr_cur_pessimistic_update(
trx->id);
}
- page_cursor = btr_cur_get_page_cur(cursor);
-
- /* Store state of explicit locks on rec on the page infimum record,
- before deleting rec. The page infimum acts as a dummy carrier of the
- locks, taking care also of lock releases, before we can move the locks
- back on the actual record. There is a special case: if we are
- inserting on the root page and the insert causes a call of
- btr_root_raise_and_insert. Therefore we cannot in the lock system
- delete the lock structs set on the root page even if the root
- page carries just node pointers. */
-
- lock_rec_store_on_page_infimum(rec);
-
- btr_search_update_hash_on_delete(cursor);
-
if (flags & BTR_NO_UNDO_LOG_FLAG) {
/* We are in a transaction rollback undoing a row
update: we must free possible externally stored fields
@@ -1860,10 +1811,6 @@ btr_cur_pessimistic_update(
ext_vect = mem_heap_alloc(heap, sizeof(ulint) * rec_get_n_fields(rec));
n_ext_vect = btr_push_update_extern_fields(ext_vect, rec, update);
- page_cur_delete_rec(page_cursor, mtr);
-
- page_cur_move_to_prev(page_cursor);
-
if ((rec_get_converted_size(new_entry) >=
page_get_free_space_of_empty() / 2)
|| (rec_get_converted_size(new_entry) >= REC_MAX_DATA_SIZE)) {
@@ -1874,10 +1821,31 @@ btr_cur_pessimistic_update(
mem_heap_free(heap);
+ err = DB_TOO_BIG_RECORD;
+
goto return_after_reservations;
}
}
+ page_cursor = btr_cur_get_page_cur(cursor);
+
+ /* Store state of explicit locks on rec on the page infimum record,
+ before deleting rec. The page infimum acts as a dummy carrier of the
+ locks, taking care also of lock releases, before we can move the locks
+ back on the actual record. There is a special case: if we are
+ inserting on the root page and the insert causes a call of
+ btr_root_raise_and_insert. Therefore we cannot in the lock system
+ delete the lock structs set on the root page even if the root
+ page carries just node pointers. */
+
+ lock_rec_store_on_page_infimum(rec);
+
+ btr_search_update_hash_on_delete(cursor);
+
+ page_cur_delete_rec(page_cursor, mtr);
+
+ page_cur_move_to_prev(page_cursor);
+
rec = btr_cur_insert_if_possible(cursor, new_entry,
&dummy_reorganized, mtr);
ut_a(rec || optim_err != DB_UNDERFLOW);
@@ -3372,8 +3340,8 @@ btr_free_externally_stored_field(
page_no = mach_read_from_4(data + local_len
+ BTR_EXTERN_PAGE_NO);
- offset = mach_read_from_4(data + local_len + BTR_EXTERN_OFFSET);
-
+ offset = mach_read_from_4(data + local_len
+ + BTR_EXTERN_OFFSET);
extern_len = mach_read_from_4(data + local_len
+ BTR_EXTERN_LEN + 4);
diff --git a/innobase/btr/btr0pcur.c b/innobase/btr/btr0pcur.c
index 13efacb9da3..39e70d91be8 100644
--- a/innobase/btr/btr0pcur.c
+++ b/innobase/btr/btr0pcur.c
@@ -381,6 +381,8 @@ btr_pcur_move_to_next_page(
btr_leaf_page_release(page, cursor->latch_mode, mtr);
page_cur_set_before_first(next_page, btr_pcur_get_page_cur(cursor));
+
+ page_check_dir(next_page);
}
/*************************************************************