List:Commits« Previous MessageNext Message »
From:marko.makela Date:August 9 2010 8:58am
Subject:bzr commit into mysql-trunk-innodb branch (marko.makela:3150) Bug#54914
View as plain text  
#At file:///home/marko/innobase/dev/mysql2a/5.5-innodb/ based on revid:inaam.rana@strippedagqzbkpfbk

 3150 Marko Mäkelä	2010-08-09
      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().

    modified:
      storage/innobase/ibuf/ibuf0ibuf.c
=== modified file 'storage/innobase/ibuf/ibuf0ibuf.c'
--- a/storage/innobase/ibuf/ibuf0ibuf.c	revid:inaam.rana@oracle.com-20100805154211-fa9g6qagqzbkpfbk
+++ b/storage/innobase/ibuf/ibuf0ibuf.c	revid:marko.makela@stripped09085837-s1nfx6gjf7l6ttab
@@ -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);

Attachment: [text/bzr-bundle] bzr/marko.makela@oracle.com-20100809085837-s1nfx6gjf7l6ttab.bundle
Thread
bzr commit into mysql-trunk-innodb branch (marko.makela:3150) Bug#54914marko.makela9 Aug