Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Reduce the number of calls to btr_cur_optimistic_insert()
- Summary:
- During the record insertion, InnoDB finds out the page the record
- should be inserted, acquires the latch for that page and attempts
- to insert the record to the page. If there is not enough room in
- the page then the b-tree structure must be changed so it releases
- the page latch and then gets the b-tree latch. It then re-computes
- the page to which the record should be inserted. Most of the time
- this second page is the same page as the previously found page and
- it still doesn't have room for the record insertion. Rarely,
- another thread (eg. purge thread) gets a hold of the previously
- found page and deletes some records on that page so that there is
- room for insertion in InnoDB's second attempt.
- This diff eliminates the unnecessary attempts to insert the record
- into the page by checking if the page has been modified since the
- last time the insertion had been attempted.
- diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
- index df2900c..1381b40 100644
- --- a/storage/innodb_plugin/handler/ha_innodb.cc
- +++ b/storage/innodb_plugin/handler/ha_innodb.cc
- @@ -1109,6 +1109,10 @@ static SHOW_VAR innodb_status_variables[]= {
- (char*) &export_vars.innodb_malloc_cache_block_size_decompress, SHOW_LONG},
- {"no_undo_slot_free",
- (char*) &export_vars.no_undo_slot_free, SHOW_LONG},
- +#ifdef UNIV_DEBUG
- + {"num_optimistic_insert_calls_in_pessimistic_descent",
- + (char*) &export_vars.num_optimistic_insert_calls_in_pessimistic_descent, SHOW_LONGLONG},
- +#endif
- {NullS, NullS, SHOW_LONG}
- };
- diff --git a/storage/innodb_plugin/ibuf/ibuf0ibuf.c b/storage/innodb_plugin/ibuf/ibuf0ibuf.c
- index a227a73..b770afd 100644
- --- a/storage/innodb_plugin/ibuf/ibuf0ibuf.c
- +++ b/storage/innodb_plugin/ibuf/ibuf0ibuf.c
- @@ -2581,7 +2581,23 @@ ibuf_insert_low(
- ulint space, /*!< in: space id where to insert */
- ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
- ulint page_no,/*!< in: page number where to insert */
- - que_thr_t* thr) /*!< in: query thread */
- + que_thr_t* thr, /*!< in: query thread */
- + ulint* ibuf_page_no, /*!< *page_no and *modify_clock are used to decide
- + whether to call btr_cur_optimistic_insert() during
- + pessimistic descent down the index tree.
- + in: If this is optimistic descent, then *page_no
- + must be ULINT_UNDEFINED. If it is pessimistic
- + descent, *page_no must be the page_no to which an
- + optimistic insert was attempted last time
- + ibuf_insert_low() was called.
- + out: If this is the optimistic descent, *page_no is set
- + to the page_no to which an optimistic insert was
- + attempted. If it is pessimistic descent, this value is
- + not changed. */
- + ib_uint64_t* modify_clock) /*!< in/out: *modify_clock == ULLINT_UNDEFINED
- + during optimistic descent, and the modify_clock
- + value for the page that was used for optimistic
- + insert during pessimistic descent */
- {
- big_rec_t* dummy_big_rec;
- btr_pcur_t pcur;
- @@ -2739,6 +2755,8 @@ ibuf_insert_low(
- cursor = btr_pcur_get_btr_cur(&pcur);
- if (mode == BTR_MODIFY_PREV) {
- + ut_a(*ibuf_page_no == ULINT_UNDEFINED);
- + ut_a(*modify_clock == ULLINT_UNDEFINED);
- err = btr_cur_optimistic_insert(BTR_NO_LOCKING_FLAG, cursor,
- ibuf_entry, &ins_rec,
- &dummy_big_rec, 0, thr, &mtr);
- @@ -2746,6 +2764,10 @@ ibuf_insert_low(
- /* Update the page max trx id field */
- page_update_max_trx_id(btr_cur_get_block(cursor), NULL,
- thr_get_trx(thr)->id, &mtr);
- + } else {
- + *ibuf_page_no = buf_block_get_page_no(btr_cur_get_block(cursor));
- + *modify_clock = buf_block_get_modify_clock(
- + btr_cur_get_block(cursor));
- }
- } else {
- ut_ad(mode == BTR_MODIFY_TREE);
- @@ -2757,10 +2779,16 @@ ibuf_insert_low(
- root = ibuf_tree_root_get(&mtr);
- - err = btr_cur_optimistic_insert(
- - BTR_NO_LOCKING_FLAG | BTR_NO_UNDO_LOG_FLAG,
- - cursor, ibuf_entry, &ins_rec,
- - &dummy_big_rec, 0, thr, &mtr);
- + if ((*ibuf_page_no != buf_block_get_page_no(btr_cur_get_block(cursor)))
- + || (*modify_clock != buf_block_get_modify_clock(
- + btr_cur_get_block(cursor)))) {
- + err = btr_cur_optimistic_insert(
- + BTR_NO_LOCKING_FLAG | BTR_NO_UNDO_LOG_FLAG,
- + cursor, ibuf_entry, &ins_rec,
- + &dummy_big_rec, 0, thr, &mtr);
- + } else {
- + err = DB_FAIL;
- + }
- if (err == DB_FAIL) {
- err = btr_cur_pessimistic_insert(
- @@ -2845,6 +2873,8 @@ ibuf_insert(
- {
- ulint err;
- ulint entry_size;
- + ulint ibuf_page_no = ULINT_UNDEFINED;
- + ullint modify_clock = ULLINT_UNDEFINED;
- ut_a(trx_sys_multiple_tablespace_format);
- ut_ad(dtuple_check_typed(entry));
- @@ -2873,10 +2903,12 @@ do_insert:
- }
- err = ibuf_insert_low(BTR_MODIFY_PREV, entry, entry_size,
- - index, space, zip_size, page_no, thr);
- + index, space, zip_size, page_no, thr,
- + &ibuf_page_no, &modify_clock);
- if (err == DB_FAIL) {
- err = ibuf_insert_low(BTR_MODIFY_TREE, entry, entry_size,
- - index, space, zip_size, page_no, thr);
- + index, space, zip_size, page_no, thr,
- + &ibuf_page_no, &modify_clock);
- }
- if (err == DB_SUCCESS) {
- diff --git a/storage/innodb_plugin/include/srv0srv.h b/storage/innodb_plugin/include/srv0srv.h
- index 14ea98c..c0177a4 100644
- --- a/storage/innodb_plugin/include/srv0srv.h
- +++ b/storage/innodb_plugin/include/srv0srv.h
- @@ -1141,6 +1141,9 @@ struct export_var_struct{
- ulint innodb_drop_purge_skip_row;
- ulint innodb_drop_ibuf_skip_row;
- ulint no_undo_slot_free;
- +#ifdef UNIV_DEBUG
- + ullint num_optimistic_insert_calls_in_pessimistic_descent;
- +#endif /* UNIV_DEBUG */
- };
- /** The server system struct */
- diff --git a/storage/innodb_plugin/row/row0ins.c b/storage/innodb_plugin/row/row0ins.c
- index 43db5c2..95c3953 100644
- --- a/storage/innodb_plugin/row/row0ins.c
- +++ b/storage/innodb_plugin/row/row0ins.c
- @@ -70,6 +70,12 @@ check.
- If you make a change in this module make sure that no codepath is
- introduced where a call to log_free_check() is bypassed. */
- +#ifdef UNIV_DEBUG
- +/** Number of optimistic and pessimistic inserts performed on the
- +b-tree of the indexes */
- +ullint row_ins_optimistic_insert_calls_in_pessimistic_descent = 0;
- +#endif /* UNIV_DEBUG */
- +
- /*********************************************************************//**
- Creates an insert node struct.
- @return own: insert node struct */
- @@ -1999,7 +2005,23 @@ row_ins_index_entry_low(
- dict_index_t* index, /*!< in: index */
- dtuple_t* entry, /*!< in/out: index entry to insert */
- ulint n_ext, /*!< in: number of externally stored columns */
- - que_thr_t* thr) /*!< in: query thread */
- + que_thr_t* thr, /*!< in: query thread */
- + ulint* page_no, /*!< *page_no and *modify_clock are used to decide
- + whether to call btr_cur_optimistic_insert() during
- + pessimistic descent down the index tree.
- + in: If this is optimistic descent, then *page_no
- + must be ULINT_UNDEFINED. If it is pessimistic
- + descent, *page_no must be the page_no to which an
- + optimistic insert was attempted last time
- + row_ins_index_entry_low() was called.
- + out: If this is the optimistic descent, *page_no is set
- + to the page_no to which an optimistic insert was
- + attempted. If it is pessimistic descent, this value is
- + not changed. */
- + ib_uint64_t* modify_clock) /*!< in/out: *modify_clock == ULLINT_UNDEFINED
- + during optimistic descent, and the modify_clock
- + value for the page that was used for optimistic
- + insert during pessimistic descent */
- {
- btr_cur_t cursor;
- ulint ignore_sec_unique = 0;
- @@ -2185,9 +2207,16 @@ row_ins_index_entry_low(
- }
- } else {
- if (mode == BTR_MODIFY_LEAF) {
- + ut_a(*page_no == ULINT_UNDEFINED);
- + ut_a(*modify_clock == ULLINT_UNDEFINED);
- err = btr_cur_optimistic_insert(
- 0, &cursor, entry, &insert_rec, &big_rec,
- n_ext, thr, &mtr);
- + if (err != DB_SUCCESS) {
- + *page_no = buf_block_get_page_no(btr_cur_get_block(&cursor));
- + *modify_clock = buf_block_get_modify_clock(
- + btr_cur_get_block(&cursor));
- + }
- } else {
- ut_a(mode == BTR_MODIFY_TREE);
- if (buf_LRU_buf_pool_running_out()) {
- @@ -2197,9 +2226,16 @@ row_ins_index_entry_low(
- goto function_exit;
- }
- - err = btr_cur_optimistic_insert(
- - 0, &cursor, entry, &insert_rec, &big_rec,
- - n_ext, thr, &mtr);
- + if ((*page_no != buf_block_get_page_no(btr_cur_get_block(&cursor)))
- + || (*modify_clock != buf_block_get_modify_clock(
- + btr_cur_get_block(&cursor)))) {
- + ut_d(++row_ins_optimistic_insert_calls_in_pessimistic_descent);
- + err = btr_cur_optimistic_insert(
- + 0, &cursor, entry, &insert_rec, &big_rec,
- + n_ext, thr, &mtr);
- + } else {
- + err = DB_FAIL;
- + }
- if (err == DB_FAIL) {
- err = btr_cur_pessimistic_insert(
- @@ -2290,6 +2326,8 @@ row_ins_index_entry(
- que_thr_t* thr) /*!< in: query thread */
- {
- ulint err;
- + ulint page_no = ULINT_UNDEFINED;
- + ullint modify_clock = ULLINT_UNDEFINED;
- if (foreign && UT_LIST_GET_FIRST(index->table->foreign_list)) {
- err = row_ins_check_foreign_constraints(index->table, index,
- @@ -2303,7 +2341,7 @@ row_ins_index_entry(
- /* Try first optimistic descent to the B-tree */
- err = row_ins_index_entry_low(BTR_MODIFY_LEAF, index, entry,
- - n_ext, thr);
- + n_ext, thr, &page_no, &modify_clock);
- if (err != DB_FAIL) {
- return(err);
- @@ -2312,7 +2350,7 @@ row_ins_index_entry(
- /* Try then pessimistic descent to the B-tree */
- err = row_ins_index_entry_low(BTR_MODIFY_TREE, index, entry,
- - n_ext, thr);
- + n_ext, thr, &page_no, &modify_clock);
- return(err);
- }
- diff --git a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0srv.c
- index 15c18a8..35199f7 100644
- --- a/storage/innodb_plugin/srv/srv0srv.c
- +++ b/storage/innodb_plugin/srv/srv0srv.c
- @@ -2304,6 +2304,10 @@ export_zip(
- *decompressed_secondary_usec = zip_stat->decompressed_secondary_usec;
- }
- +#ifdef UNIV_DEBUG
- +extern ullint row_ins_optimistic_insert_calls_in_pessimistic_descent;
- +#endif /* UNIV_DEBUG */
- +
- /******************************************************************//**
- Function to pass InnoDB status variables to MySQL */
- UNIV_INTERN
- @@ -2757,6 +2761,10 @@ srv_export_innodb_status(void)
- export_vars.innodb_drop_purge_skip_row = srv_drop_purge_skip_row;
- export_vars.innodb_drop_ibuf_skip_row = srv_drop_ibuf_skip_row;
- +#ifdef UNIV_DEBUG
- + export_vars.num_optimistic_insert_calls_in_pessimistic_descent =
- + row_ins_optimistic_insert_calls_in_pessimistic_descent;
- +#endif /* UNIV_DEBUG */
- mutex_exit(&srv_innodb_monitor_mutex);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement