Commit a4c5cf7c authored by Marko Mäkelä's avatar Marko Mäkelä

Reduce the ibuf_mutex hold time. This does not fix the update

regression in Bug #54914, but it does speed up the execution for
innodb_change_buffering=inserts.

ibuf_add_ops(), ibuf_merge_or_delete_for_page(),
ibuf_delete_for_discarded_space(): Use atomic built-ins instead of
ibuf_mutex, when available.

ibuf_add_free_page(), ibuf_remove_free_page(), ibuf_contract_ext():
Release ibuf_mutex earlier.

ibuf_free_excess_pages(): Release ibuf_mutex before a conditional branch.

ibuf_insert_low(): Release ibuf_mutex before a conditional
branch. Create ibuf_entry before re-acquiring ibuf_mutex. Simplify a
loop to reduce code footprint. Release ibuf_mutex before mtr_commit()
[btr_pcur_close()].

ibuf_is_empty(): Release ibuf_mutex before mtr_commit().
parent 9943e3f4
......@@ -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++) {
mutex_enter(&ibuf_mutex);
if (!ibuf_data_too_much_free()) {
ibool too_much_free;
mutex_exit(&ibuf_mutex);
mutex_enter(&ibuf_mutex);
too_much_free = 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,16 +3341,36 @@ ibuf_insert_low(
return(DB_STRONG_FAIL);
}
mutex_exit(&ibuf_mutex);
heap = mem_heap_create(512);
/* Build the entry which contains the space id and the page number
as the first fields and the type information for other fields, and
which will be inserted to the insert buffer. Using a counter value
of 0xFFFF we find the last record for (space, page_no), from which
we can then read the counter value N and use N + 1 in the record we
insert. (We patch the ibuf_entry's counter field to the correct
value just before actually inserting the entry.) */
ibuf_entry = ibuf_entry_build(
op, index, entry, space, page_no,
no_counter ? ULINT_UNDEFINED : 0xFFFF, heap);
/* Open a cursor to the insert buffer tree to calculate if we can add
the new entry to it without exceeding the free space limit for the
page. */
if (mode == BTR_MODIFY_TREE) {
mutex_enter(&ibuf_pessimistic_insert_mutex);
for (;;) {
mutex_enter(&ibuf_pessimistic_insert_mutex);
ibuf_enter();
ibuf_enter();
mutex_enter(&ibuf_mutex);
mutex_enter(&ibuf_mutex);
while (!ibuf_data_enough_free_for_insert()) {
if (UNIV_LIKELY(ibuf_data_enough_free_for_insert())) {
break;
}
mutex_exit(&ibuf_mutex);
......@@ -3351,39 +3380,16 @@ ibuf_insert_low(
err = ibuf_add_free_page();
if (err == DB_STRONG_FAIL) {
if (UNIV_UNLIKELY(err == DB_STRONG_FAIL)) {
mem_heap_free(heap);
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
as the first fields and the type information for other fields, and
which will be inserted to the insert buffer. Using a counter value
of 0xFFFF we find the last record for (space, page_no), from which
we can then read the counter value N and use N + 1 in the record we
insert. (We patch the ibuf_entry's counter field to the correct
value just before actually inserting the entry.) */
ibuf_entry = ibuf_entry_build(
op, index, entry, space, page_no,
no_counter ? ULINT_UNDEFINED : 0xFFFF, heap);
/* Open a cursor to the insert buffer tree to calculate if we can add
the new entry to it without exceeding the free space limit for the
page. */
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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment