diff options
Diffstat (limited to 'innobase/btr/btr0cur.c')
-rw-r--r-- | innobase/btr/btr0cur.c | 119 |
1 files changed, 44 insertions, 75 deletions
diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c index b2bfdbec4e4..fdc8343e190 100644 --- a/innobase/btr/btr0cur.c +++ b/innobase/btr/btr0cur.c @@ -66,6 +66,16 @@ this many index pages */ #define BTR_BLOB_HDR_SIZE 8 /*********************************************************************** +Marks all extern fields in a record as owned by the record. This function +should be called if the delete mark of a record is removed: a not delete +marked record always owns all its extern fields. */ +static +void +btr_cur_unmark_extern_fields( +/*=========================*/ + rec_t* rec, /* in: record in a clustered index */ + mtr_t* mtr); /* in: mtr */ +/*********************************************************************** Adds path information to the cursor for the current page, for which the binary search has been performed. */ static @@ -1323,66 +1333,6 @@ btr_cur_parse_update_in_place( } /***************************************************************** -Updates a secondary index record when the update causes no size -changes in its fields. The only case when this function is currently -called is that in a char field characters change to others which -are identified in the collation order. */ - -ulint -btr_cur_update_sec_rec_in_place( -/*============================*/ - /* out: DB_SUCCESS or error number */ - btr_cur_t* cursor, /* in: cursor on the record to update; - cursor stays valid and positioned on the - same record */ - upd_t* update, /* in: update vector */ - que_thr_t* thr, /* in: query thread */ - mtr_t* mtr) /* in: mtr */ -{ - dict_index_t* index = cursor->index; - dict_index_t* clust_index; - ulint err; - rec_t* rec; - dulint roll_ptr = ut_dulint_zero; - trx_t* trx = thr_get_trx(thr); - - /* Only secondary index records are updated using this function */ - ut_ad(0 == (index->type & DICT_CLUSTERED)); - - rec = btr_cur_get_rec(cursor); - - if (btr_cur_print_record_ops && thr) { - printf( - "Trx with id %lu %lu going to update table %s index %s\n", - (unsigned long) ut_dulint_get_high(thr_get_trx(thr)->id), - (unsigned long) ut_dulint_get_low(thr_get_trx(thr)->id), - index->table_name, index->name); - rec_print(rec); - } - - err = lock_sec_rec_modify_check_and_lock(0, rec, index, thr); - - if (err != DB_SUCCESS) { - - return(err); - } - - /* Remove possible hash index pointer to this record */ - btr_search_update_hash_on_delete(cursor); - - row_upd_rec_in_place(rec, update); - - clust_index = dict_table_get_first_index(index->table); - - /* Note that roll_ptr is really just a dummy value since - a secondary index record does not contain any sys columns */ - - btr_cur_update_in_place_log(BTR_KEEP_SYS_FLAG, rec, clust_index, - update, trx, roll_ptr, mtr); - return(DB_SUCCESS); -} - -/***************************************************************** 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. */ @@ -2709,7 +2659,7 @@ btr_estimate_number_of_different_key_vals( ulint n_cols; ulint matched_fields; ulint matched_bytes; - ulint* n_diff; + ib_longlong* n_diff; ulint not_empty_flag = 0; ulint total_external_size = 0; ulint i; @@ -2732,10 +2682,11 @@ btr_estimate_number_of_different_key_vals( btr_cur_open_at_rnd_pos(index, BTR_SEARCH_LEAF, &cursor, &mtr); - /* Count the number of different key values minus one - for each prefix of the key on this index page: we subtract - one because otherwise our algorithm would give a wrong - estimate for an index where there is just one key value */ + /* Count the number of different key values for each prefix of + the key on this index page. If the prefix does not determine + the index record uniquely in te B-tree, then we subtract one + because otherwise our algorithm would give a wrong estimate + for an index where there is just one key value. */ page = btr_cur_get_page(&cursor); @@ -2757,6 +2708,9 @@ btr_estimate_number_of_different_key_vals( &matched_bytes); for (j = matched_fields + 1; j <= n_cols; j++) { + /* We add one if this index record has + a different prefix from the previous */ + n_diff[j]++; } @@ -2766,6 +2720,18 @@ btr_estimate_number_of_different_key_vals( rec = page_rec_get_next(rec); } + if (n_cols == dict_index_get_n_unique_in_tree(index)) { + /* We add one because we know that the first record + on the page certainly had a different prefix than the + last record on the previous index page in the + alphabetical order. Before this fix, if there was + just one big record on each clustered index page, the + algorithm grossly underestimated the number of rows + in the table. */ + + n_diff[n_cols]++; + } + total_external_size += btr_rec_get_externally_stored_len(rec); mtr_commit(&mtr); @@ -2781,7 +2747,8 @@ btr_estimate_number_of_different_key_vals( for (j = 0; j <= n_cols; j++) { index->stat_n_diff_key_vals[j] = - (n_diff[j] * index->stat_n_leaf_pages + (n_diff[j] + * (ib_longlong)index->stat_n_leaf_pages + BTR_KEY_VAL_ESTIMATE_N_PAGES - 1 + total_external_size + not_empty_flag) @@ -2992,7 +2959,7 @@ btr_cur_mark_dtuple_inherited_extern( Marks all extern fields in a record as owned by the record. This function should be called if the delete mark of a record is removed: a not delete marked record always owns all its extern fields. */ - +static void btr_cur_unmark_extern_fields( /*=========================*/ @@ -3216,8 +3183,10 @@ btr_store_big_rec_extern_fields( prev_page_no, RW_X_LATCH, &mtr); +#ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(prev_page, SYNC_EXTERN_STORAGE); +#endif /* UNIV_SYNC_DEBUG */ mlog_write_ulint(prev_page + FIL_PAGE_DATA + BTR_BLOB_HDR_NEXT_PAGE_NO, @@ -3252,9 +3221,9 @@ btr_store_big_rec_extern_fields( rec_page = buf_page_get(space_id, buf_frame_get_page_no(data), RW_X_LATCH, &mtr); - +#ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(rec_page, SYNC_NO_ORDER_CHECK); - +#endif /* UNIV_SYNC_DEBUG */ mlog_write_ulint(data + local_len + BTR_EXTERN_LEN, 0, MLOG_4BYTES, &mtr); mlog_write_ulint(data + local_len + BTR_EXTERN_LEN + 4, @@ -3346,9 +3315,9 @@ btr_free_externally_stored_field( rec_page = buf_page_get(buf_frame_get_space_id(data), buf_frame_get_page_no(data), RW_X_LATCH, &mtr); - +#ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(rec_page, SYNC_NO_ORDER_CHECK); - +#endif /* UNIV_SYNC_DEBUG */ space_id = mach_read_from_4(data + local_len + BTR_EXTERN_SPACE_ID); @@ -3391,9 +3360,9 @@ btr_free_externally_stored_field( } page = buf_page_get(space_id, page_no, RW_X_LATCH, &mtr); - +#ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(page, SYNC_EXTERN_STORAGE); - +#endif /* UNIV_SYNC_DEBUG */ next_page_no = mach_read_from_4(page + FIL_PAGE_DATA + BTR_BLOB_HDR_NEXT_PAGE_NO); @@ -3571,9 +3540,9 @@ btr_copy_externally_stored_field( mtr_start(&mtr); page = buf_page_get(space_id, page_no, RW_S_LATCH, &mtr); - +#ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(page, SYNC_EXTERN_STORAGE); - +#endif /* UNIV_SYNC_DEBUG */ blob_header = page + offset; part_len = btr_blob_get_part_len(blob_header); |