diff options
author | monty@mashka.mysql.fi <> | 2003-08-11 22:44:43 +0300 |
---|---|---|
committer | monty@mashka.mysql.fi <> | 2003-08-11 22:44:43 +0300 |
commit | 2263e3e51faba531a0a7055dbf706a6a8719ad70 (patch) | |
tree | 3c0ddcb446b8be099c3ab2616c459a573ee3cf92 /innobase/btr | |
parent | 1279f9b024614cf97cf447cfb10d6d7d69abb8bc (diff) | |
parent | 6e7a509d06824447e427dd44d5692489267d9c4b (diff) | |
download | mariadb-git-2263e3e51faba531a0a7055dbf706a6a8719ad70.tar.gz |
Merge with 4.0.14
Diffstat (limited to 'innobase/btr')
-rw-r--r-- | innobase/btr/btr0btr.c | 29 | ||||
-rw-r--r-- | innobase/btr/btr0cur.c | 110 | ||||
-rw-r--r-- | innobase/btr/btr0pcur.c | 2 |
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); } /************************************************************* |