MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Inaam Rana Date:March 28 2011 1:12pm
Subject:bzr push into mysql-trunk-innodb branch (inaam.rana:3552 to 3553) WL#5829
View as plain text  
 3553 Inaam Rana	2011-03-28
      WL#5829 optimize log_flush_order_mutex usage in mtr_commit()
      
      rb://620 approved by: Marko
      
      During mtr_commit() we grab log_flush_order_mutex to ensure that we
      can insert into the flush_list in the same order in which the mtrs
      are committed. However, a page needs to be inserted in the flush
      list iff it was clean before it is touched by the mtr. This
      optimization is to acquire log_flush_order_mutex iff mtr has modified
      any clean pages. If all pages modified by the mtr were already dirty
      then they must already be in the flush list and therefore there won't
      be any insertions made to the flush list

    modified:
      storage/innobase/include/buf0flu.ic
      storage/innobase/include/mtr0mtr.h
      storage/innobase/include/mtr0mtr.ic
      storage/innobase/mtr/mtr0mtr.c
 3552 Vasil Dimov	2011-03-28 [merge]
      Merge mysql-5.5-innodb -> mysql-trunk-innodb

    modified:
      storage/innobase/trx/trx0i_s.c
=== modified file 'storage/innobase/include/buf0flu.ic'
--- a/storage/innobase/include/buf0flu.ic	revid:vasil.dimov@stripped
+++ b/storage/innobase/include/buf0flu.ic	revid:inaam.rana@stripped
@@ -70,7 +70,7 @@ buf_flush_note_modification(
 
 	ut_ad(!buf_pool_mutex_own(buf_pool));
 	ut_ad(!buf_flush_list_mutex_own(buf_pool));
-	ut_ad(log_flush_order_mutex_own());
+	ut_ad(!mtr->made_dirty || log_flush_order_mutex_own());
 
 	ut_ad(mtr->start_lsn != 0);
 	ut_ad(mtr->modifications);
@@ -81,6 +81,8 @@ buf_flush_note_modification(
 	block->page.newest_modification = mtr->end_lsn;
 
 	if (!block->page.oldest_modification) {
+		ut_a(mtr->made_dirty);
+		ut_ad(log_flush_order_mutex_own());
 		buf_flush_insert_into_flush_list(
 			buf_pool, block, mtr->start_lsn);
 	} else {

=== modified file 'storage/innobase/include/mtr0mtr.h'
--- a/storage/innobase/include/mtr0mtr.h	revid:vasil.dimov@stripped
+++ b/storage/innobase/include/mtr0mtr.h	revid:inaam.rana@stripped
@@ -366,7 +366,6 @@ mtr_memo_push(
 	void*	object,	/*!< in: object */
 	ulint	type);	/*!< in: object type: MTR_MEMO_S_LOCK, ... */
 
-
 /* Type definition of a mini-transaction memo stack slot. */
 typedef	struct mtr_memo_slot_struct	mtr_memo_slot_t;
 struct mtr_memo_slot_struct{
@@ -386,6 +385,8 @@ struct mtr_struct{
 	ibool		modifications;
 				/* TRUE if the mtr made modifications to
 				buffer pool pages */
+	ibool		made_dirty;/*!< TRUE if mtr has made at least
+				one buffer pool page dirty */
 	ulint		n_log_recs;
 				/* count of how many page initial log records
 				have been written to the mtr log */

=== modified file 'storage/innobase/include/mtr0mtr.ic'
--- a/storage/innobase/include/mtr0mtr.ic	revid:vasil.dimov@stripped
+++ b/storage/innobase/include/mtr0mtr.ic	revid:inaam.rana@stripped
@@ -29,6 +29,16 @@ Created 11/26/1995 Heikki Tuuri
 #endif /* !UNIV_HOTBACKUP */
 #include "mach0data.h"
 
+/***************************************************//**
+Checks if a mini-transaction is dirtying a clean page.
+@return TRUE if the mtr is dirtying a clean page. */
+UNIV_INTERN
+ibool
+mtr_block_dirtied(
+/*==============*/
+	const buf_block_t*	block)	/*!< in: block being x-fixed */
+	__attribute__((nonnull,warn_unused_result));
+
 /***************************************************************//**
 Starts a mini-transaction. */
 UNIV_INLINE
@@ -44,6 +54,7 @@ mtr_start(
 	mtr->modifications = FALSE;
 	mtr->inside_ibuf = FALSE;
 	mtr->n_log_recs = 0;
+	mtr->made_dirty = FALSE;
 
 	ut_d(mtr->state = MTR_ACTIVE);
 	ut_d(mtr->magic_n = MTR_MAGIC_N);
@@ -69,6 +80,15 @@ mtr_memo_push(
 	ut_ad(mtr->magic_n == MTR_MAGIC_N);
 	ut_ad(mtr->state == MTR_ACTIVE);
 
+	/* If this mtr has x-fixed a clean page then we set
+	the made_dirty flag. This tells us if we need to
+	grab log_flush_order_mutex at mtr_commit so that we
+	can insert the dirtied page to the flush list. */
+	if (type == MTR_MEMO_PAGE_X_FIX && !mtr->made_dirty) {
+		mtr->made_dirty =
+			mtr_block_dirtied((const buf_block_t *)object);
+	}
+
 	memo = &(mtr->memo);
 
 	slot = (mtr_memo_slot_t*) dyn_array_push(memo, sizeof *slot);

=== modified file 'storage/innobase/mtr/mtr0mtr.c'
--- a/storage/innobase/mtr/mtr0mtr.c	revid:vasil.dimov@stripped
+++ b/storage/innobase/mtr/mtr0mtr.c	revid:inaam.rana@stripped
@@ -37,6 +37,25 @@ Created 11/26/1995 Heikki Tuuri
 
 #ifndef UNIV_HOTBACKUP
 # include "log0recv.h"
+
+/***************************************************//**
+Checks if a mini-transaction is dirtying a clean page.
+@return TRUE if the mtr is dirtying a clean page. */
+UNIV_INTERN
+ibool
+mtr_block_dirtied(
+/*==============*/
+	const buf_block_t*	block)	/*!< in: block being x-fixed */
+{
+	ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
+	ut_ad(block->page.buf_fix_count > 0);
+
+	/* It is OK to read oldest_modification because no
+	other thread can be performing a write of it and it
+	is only during write that the value is reset to 0. */
+	return(block->page.oldest_modification == 0);
+}
+
 /*****************************************************************//**
 Releases the item in the slot given. */
 static
@@ -128,7 +147,7 @@ mtr_memo_slot_note_modification(
 	if (slot->object != NULL && slot->type == MTR_MEMO_PAGE_X_FIX) {
 		buf_block_t*	block = (buf_block_t*) slot->object;
 
-		ut_ad(log_flush_order_mutex_own());
+		ut_ad(!mtr->made_dirty || log_flush_order_mutex_own());
 		buf_flush_note_modification(block, mtr);
 	}
 }
@@ -227,7 +246,15 @@ mtr_log_reserve_and_write(
 	mtr->end_lsn = log_close();
 
 func_exit:
-	log_flush_order_mutex_enter();
+
+	/* No need to acquire log_flush_order_mutex if this mtr has
+	not dirtied a clean page. log_flush_order_mutex is used to
+	ensure ordered insertions in the flush_list. We need to
+	insert in the flush_list iff the page in question was clean
+	before modifications. */
+	if (mtr->made_dirty) {
+		log_flush_order_mutex_enter();
+	}
 
 	/* It is now safe to release the log mutex because the
 	flush_order mutex will ensure that we are the first one
@@ -238,7 +265,9 @@ func_exit:
 		mtr_memo_note_modifications(mtr);
 	}
 
-	log_flush_order_mutex_exit();
+	if (mtr->made_dirty) {
+		log_flush_order_mutex_exit();
+	}
 }
 #endif /* !UNIV_HOTBACKUP */
 


Attachment: [text/bzr-bundle] bzr/inaam.rana@oracle.com-20110328130920-llcs0qui5wx11rik.bundle
Thread
bzr push into mysql-trunk-innodb branch (inaam.rana:3552 to 3553) WL#5829Inaam Rana28 Mar