diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c index dc8e61e5070..1d162f82b93 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.c +++ b/storage/innobase/ibuf/ibuf0ibuf.c @@ -1350,10 +1350,18 @@ ibuf_add_ops( const ulint* ops) /*!< in: operation counts */ { +#ifndef HAVE_ATOMIC_BUILTINS + ut_ad(mutex_own(&ibuf_mutex)); +#endif /* !HAVE_ATOMIC_BUILTINS */ + ulint i; for (i = 0; i < IBUF_OP_COUNT; i++) { +#ifdef HAVE_ATOMIC_BUILTINS + os_atomic_increment_ulint(&arr[i], ops[i]); +#else /* HAVE_ATOMIC_BUILTINS */ arr[i] += ops[i]; +#endif /* HAVE_ATOMIC_BUILTINS */ } } @@ -2096,13 +2104,13 @@ ibuf_add_free_page(void) bitmap_page = ibuf_bitmap_get_map_page( IBUF_SPACE_ID, page_no, zip_size, &mtr); + mutex_exit(&ibuf_mutex); + ibuf_bitmap_page_set_bits( bitmap_page, page_no, zip_size, IBUF_BITMAP_IBUF, TRUE, &mtr); mtr_commit(&mtr); - mutex_exit(&ibuf_mutex); - ibuf_exit(); return(DB_SUCCESS); @@ -2158,6 +2166,8 @@ ibuf_remove_free_page(void) root = ibuf_tree_root_get(&mtr2); + mutex_exit(&ibuf_mutex); + page_no = flst_get_last(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST, &mtr2).page; @@ -2166,7 +2176,6 @@ ibuf_remove_free_page(void) is a level 2 page. */ mtr_commit(&mtr2); - mutex_exit(&ibuf_mutex); ibuf_exit(); @@ -2220,6 +2229,8 @@ ibuf_remove_free_page(void) bitmap_page = ibuf_bitmap_get_map_page( IBUF_SPACE_ID, page_no, zip_size, &mtr); + mutex_exit(&ibuf_mutex); + ibuf_bitmap_page_set_bits( bitmap_page, page_no, zip_size, IBUF_BITMAP_IBUF, FALSE, &mtr); @@ -2228,8 +2239,6 @@ ibuf_remove_free_page(void) #endif mtr_commit(&mtr); - mutex_exit(&ibuf_mutex); - ibuf_exit(); } @@ -2270,17 +2279,16 @@ ibuf_free_excess_pages(void) for (i = 0; i < 4; i++) { + ibool too_much_free; + mutex_enter(&ibuf_mutex); + too_much_free = ibuf_data_too_much_free(); + mutex_exit(&ibuf_mutex); - if (!ibuf_data_too_much_free()) { - - mutex_exit(&ibuf_mutex); - + if (!too_much_free) { return; } - mutex_exit(&ibuf_mutex); - ibuf_remove_free_page(); } } @@ -2486,8 +2494,8 @@ ibuf_contract_ext( mutex_enter(&ibuf_mutex); if (ibuf->empty) { -ibuf_is_empty: mutex_exit(&ibuf_mutex); +ibuf_is_empty: #if 0 /* TODO */ if (srv_shutdown_state) { @@ -2515,6 +2523,7 @@ ibuf_is_empty: position within the leaf */ btr_pcur_open_at_rnd_pos(ibuf->index, BTR_SEARCH_LEAF, &pcur, &mtr); + mutex_exit(&ibuf_mutex); ut_ad(page_validate(btr_pcur_get_page(&pcur), ibuf->index)); @@ -2535,8 +2544,6 @@ ibuf_is_empty: goto ibuf_is_empty; } - mutex_exit(&ibuf_mutex); - sum_sizes = ibuf_get_merge_page_nos(TRUE, btr_pcur_get_rec(&pcur), space_ids, space_versions, page_nos, &n_stored); @@ -3304,6 +3311,7 @@ ibuf_insert_low( ulint n_stored; mtr_t mtr; mtr_t bitmap_mtr; + ibool too_big; ut_a(!dict_index_is_clust(index)); ut_ad(dtuple_check_typed(entry)); @@ -3316,12 +3324,13 @@ ibuf_insert_low( do_merge = FALSE; mutex_enter(&ibuf_mutex); + too_big = ibuf->size >= ibuf->max_size + IBUF_CONTRACT_DO_NOT_INSERT; + mutex_exit(&ibuf_mutex); - if (ibuf->size >= ibuf->max_size + IBUF_CONTRACT_DO_NOT_INSERT) { + if (too_big) { /* Insert buffer is now too big, contract it but do not try to insert */ - mutex_exit(&ibuf_mutex); #ifdef UNIV_IBUF_DEBUG fputs("Ibuf too big\n", stderr); @@ -3332,40 +3341,6 @@ ibuf_insert_low( return(DB_STRONG_FAIL); } - mutex_exit(&ibuf_mutex); - - if (mode == BTR_MODIFY_TREE) { - mutex_enter(&ibuf_pessimistic_insert_mutex); - - ibuf_enter(); - - mutex_enter(&ibuf_mutex); - - while (!ibuf_data_enough_free_for_insert()) { - - mutex_exit(&ibuf_mutex); - - ibuf_exit(); - - mutex_exit(&ibuf_pessimistic_insert_mutex); - - err = ibuf_add_free_page(); - - if (err == DB_STRONG_FAIL) { - - return(err); - } - - mutex_enter(&ibuf_pessimistic_insert_mutex); - - ibuf_enter(); - - mutex_enter(&ibuf_mutex); - } - } else { - ibuf_enter(); - } - heap = mem_heap_create(512); /* Build the entry which contains the space id and the page number @@ -3384,6 +3359,37 @@ ibuf_insert_low( the new entry to it without exceeding the free space limit for the page. */ + if (mode == BTR_MODIFY_TREE) { + for (;;) { + mutex_enter(&ibuf_pessimistic_insert_mutex); + + ibuf_enter(); + + mutex_enter(&ibuf_mutex); + + if (UNIV_LIKELY(ibuf_data_enough_free_for_insert())) { + + break; + } + + mutex_exit(&ibuf_mutex); + + ibuf_exit(); + + mutex_exit(&ibuf_pessimistic_insert_mutex); + + err = ibuf_add_free_page(); + + if (UNIV_UNLIKELY(err == DB_STRONG_FAIL)) { + + mem_heap_free(heap); + return(err); + } + } + } else { + ibuf_enter(); + } + mtr_start(&mtr); btr_pcur_open(ibuf->index, ibuf_entry, PAGE_CUR_LE, mode, &pcur, &mtr); @@ -4118,9 +4124,8 @@ ibuf_delete_rec( btr_pcur_commit_specify_mtr(pcur, mtr); func_exit: - btr_pcur_close(pcur); - mutex_exit(&ibuf_mutex); + btr_pcur_close(pcur); return(TRUE); } @@ -4495,6 +4500,11 @@ reset_bit: btr_pcur_close(&pcur); mem_heap_free(heap); +#ifdef HAVE_ATOMIC_BUILTINS + os_atomic_increment_ulint(&ibuf->n_merges, 1); + ibuf_add_ops(ibuf->n_merged_ops, mops); + ibuf_add_ops(ibuf->n_discarded_ops, dops); +#else /* HAVE_ATOMIC_BUILTINS */ /* Protect our statistics keeping from race conditions */ mutex_enter(&ibuf_mutex); @@ -4503,6 +4513,7 @@ reset_bit: ibuf_add_ops(ibuf->n_discarded_ops, dops); mutex_exit(&ibuf_mutex); +#endif /* HAVE_ATOMIC_BUILTINS */ if (update_ibuf_bitmap && !tablespace_being_deleted) { @@ -4604,10 +4615,14 @@ leave_loop: mtr_commit(&mtr); btr_pcur_close(&pcur); +#ifdef HAVE_ATOMIC_BUILTINS + ibuf_add_ops(ibuf->n_discarded_ops, dops); +#else /* HAVE_ATOMIC_BUILTINS */ /* Protect our statistics keeping from race conditions */ mutex_enter(&ibuf_mutex); ibuf_add_ops(ibuf->n_discarded_ops, dops); mutex_exit(&ibuf_mutex); +#endif /* HAVE_ATOMIC_BUILTINS */ ibuf_exit(); @@ -4652,10 +4667,10 @@ ibuf_is_empty(void) is_empty = FALSE; } - mtr_commit(&mtr); - mutex_exit(&ibuf_mutex); + mtr_commit(&mtr); + ibuf_exit(); return(is_empty);