List:Commits« Previous MessageNext Message »
From:kevin.lewis Date:September 7 2012 8:37pm
Subject:bzr push into mysql-trunk branch (kevin.lewis:4445 to 4446) Bug#14551372
View as plain text  
 4446 kevin.lewis@stripped	2012-09-07
      Bug#14551372 - INNODB: UNIV_SYNC_DEBUG SYNC ARRAY IS NOT OPTIMIZED
      
      As part of the investigation into Bug 14520559 (LARGE BLOB INSERTS
      ARE SLOW AND TROUBLESOME), I found that the sync array that is used
      under UNIV_SYNC_DEBUG will store the same level-latch pair over and
      over when the latch is recursively locked.  The maximum size of this
      sync array was hit when running innodb_bug13450566.test with a 4k
      page size because seven different latches were being locked
      recursively over and over.  This filled up the available 10,000 slots
      in the array and an assert was hit.  When the assert happened, there
      were actually only 14 unique latches being tracked for that thread.
      
      This patch add a count field to each slot in this sync array. The
      count is > 1 for recursive locking.  This reduces the actual array
      size tremendously and can help performance when using UNIV_SYNC_DEBUG
      as well as prevent this 'array full' assert when a lot of recursive
      locking is happening.  This will require an extra search through the
      array to find the previous latch-level slot, but that is offset when
      it searches only tens of slots instead of thousands of slots.
      
      Approved by Sunny in http://bur03.no.oracle.com/rb/r/1247/

    modified:
      storage/innobase/sync/sync0sync.cc
 4445 Marc Alff	2012-09-07 [merge]
      Merge mysql-5.6 --> mysql-trunk

    modified:
      mysql-test/suite/perfschema/r/func_file_io.result
      mysql-test/suite/perfschema/r/func_mutex.result
      mysql-test/suite/perfschema/t/func_file_io.test
      mysql-test/suite/perfschema/t/func_mutex.test
=== modified file 'storage/innobase/sync/sync0sync.cc'
--- a/storage/innobase/sync/sync0sync.cc	revid:marc.alff@stripped
+++ b/storage/innobase/sync/sync0sync.cc	revid:kevin.lewis@stripped
@@ -250,6 +250,9 @@ struct sync_level_t{
 					latch == NULL then this will contain
 					the ordinal value of the next free
 					element */
+	ulint		count;		/*!< Numbe of times this latch has
+					been locked at this level.  Allows
+					for recursive locking */
 };
 #endif /* UNIV_SYNC_DEBUG */
 
@@ -887,6 +890,29 @@ sync_thread_levels_contain(
 }
 
 /******************************************************************//**
+Checks if the level value and latch is already stored in the level array.
+@return	slot if found or NULL */
+static
+sync_level_t*
+sync_thread_levels_find(
+/*====================*/
+	sync_arr_t*	arr,	/*!< in: pointer to level array for an OS
+				thread */
+	void*		latch,	/*!< in: pointer to a mutex or an rw-lock */
+	ulint		level)	/*!< in: level */
+{
+	for (ulint i = 0; i < arr->n_elems; i++) {
+		sync_level_t*	slot = &arr->elems[i];
+
+		if (slot->latch == latch && slot->level == level) {
+			return(slot);
+		}
+	}
+
+	return(NULL);
+}
+
+/******************************************************************//**
 Checks if the level array for the current thread contains a
 mutex or rw-latch at the specified level.
 @return	a matching latch, or NULL if not found */
@@ -1313,6 +1339,16 @@ sync_thread_add_level(
 	}
 
 levels_ok:
+	/* Look for this latch and level in the active list. If it is
+	already there, then this is a recursive lock. */
+	slot = sync_thread_levels_find(array, latch, level);
+	if (slot != NULL) {
+		slot->count++;
+		mutex_exit(&sync_thread_mutex);
+		return;
+	}
+
+	/* Get a free slot to track this level and latch */
 	if (array->next_free == ULINT_UNDEFINED) {
 		ut_a(array->n_elems < array->max_elems);
 
@@ -1333,6 +1369,7 @@ levels_ok:
 
 	slot->latch = latch;
 	slot->level = level;
+	slot->count = 1;
 
 	mutex_exit(&sync_thread_mutex);
 }
@@ -1388,6 +1425,15 @@ sync_thread_reset_level(
 			continue;
 		}
 
+		if (slot->count > 1) {
+			/* Found a latch recursively locked */
+			slot->count--;
+
+			mutex_exit(&sync_thread_mutex);
+
+			return(TRUE);
+		}
+
 		slot->latch = NULL;
 
 		/* Update the free slot list. See comment in sync_level_t

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (kevin.lewis:4445 to 4446) Bug#14551372kevin.lewis10 Sep