List:Commits« Previous MessageNext Message »
From:Sunny Bains Date:June 6 2011 9:42am
Subject:bzr push into mysql-trunk branch (Sunny.Bains:3154 to 3155)
View as plain text  
 3155 Sunny Bains	2011-06-06
      Bug 12399395 - ASSERTION FAILURE !MUTEX_OWN(MUTEX) IN SYNC0SYNC.IC LINE 207 4 of 103
      
      When we select a victim during deadlock checking or lock wait timeout we
      acquire the trx_t::mutex before calling lock_cancel_waiting_and_release().
      This is a precondition of the lock_cancel_waiting_and_release() function.
      We note this mutex acquisition in the (new) trx_t::trx_lock_t::cancel flag.
      This flag is checked in lock_trx_table_locks_remove() to determine whether we
      need to acquire the trx_t::mutex before clearing the transaction's table
      locks that were cached in trx_t::trx_lock_t::table_locks.
      
      This new flag is covered by both the lock_sys_t::mutex and trx_t::mutex.
      
      rb://617 Approved by Jimmy Yang.

    modified:
      storage/innobase/include/trx0trx.h
      storage/innobase/lock/lock0lock.c
 3154 Rafal Somla	2011-06-03 [merge]
      Upmerge of 12612143

    modified:
      libmysql/authentication_win/plugin_client.cc
=== modified file 'storage/innobase/include/trx0trx.h'
--- a/storage/innobase/include/trx0trx.h	revid:rafal.somla@stripped
+++ b/storage/innobase/include/trx0trx.h	revid:sunny.bains@stripped
@@ -486,6 +486,18 @@ struct trx_lock_struct {
 
 	ib_vector_t*	table_locks;	/*!< All table locks requested by this
 					transaction, including AUTOINC locks */
+
+	ibool		cancel;		/*!< TRUE if the transaction is being
+					rolled back either via deadlock
+					detection or due to lock timeout. The
+					caller has to acquire the trx_t::mutex
+					in order to cancel the locks. In
+					lock_trx_table_locks_remove() we
+					check for this cancel of a transaction's
+					locks and avoid reacquiring the trx
+					mutex to prevent recursive deadlocks.
+					Protected by both the lock sys mutex
+					and the trx_t::mutex. */
 };
 
 #define TRX_MAGIC_N	91118598
@@ -540,7 +552,6 @@ struct trx_struct{
 					state and lock
 					(except some fields of lock, which
 					are protected by lock_sys->mutex) */
-
 	trx_state_t	state;		/*!< State of the trx from the point
 					of view of concurrency control:
 					TRX_STATE_NOT_STARTED (!in_trx_list),

=== modified file 'storage/innobase/lock/lock0lock.c'
--- a/storage/innobase/lock/lock0lock.c	revid:rafal.somla@stripped
+++ b/storage/innobase/lock/lock0lock.c	revid:sunny.bains@stripped
@@ -4393,7 +4393,8 @@ lock_trx_table_locks_remove(
 
 	ut_ad(lock_mutex_own());
 
-	if (!trx->lock.was_chosen_as_deadlock_victim) {
+	/* It is safe to read this because we are holding the lock mutex */
+	if (!trx->lock.cancel) {
 		trx_mutex_enter(trx);
 	} else {
 		ut_ad(trx_mutex_own(trx));
@@ -4415,7 +4416,7 @@ lock_trx_table_locks_remove(
 		if (lock == lock_to_remove) {
 			ib_vector_set(trx->lock.table_locks, i, NULL);
 
-			if (!trx->lock.was_chosen_as_deadlock_victim) {
+			if (!trx->lock.cancel) {
 				trx_mutex_exit(trx);
 			}
 
@@ -4423,7 +4424,7 @@ lock_trx_table_locks_remove(
 		}
 	}
 
-	if (!trx->lock.was_chosen_as_deadlock_victim) {
+	if (!trx->lock.cancel) {
 		trx_mutex_exit(trx);
 	}
 
@@ -6246,6 +6247,8 @@ lock_cancel_waiting_and_release(
 	ut_ad(lock_mutex_own());
 	ut_ad(trx_mutex_own(lock->trx));
 
+	lock->trx->lock.cancel = TRUE;
+
 	if (lock_get_type_low(lock) == LOCK_REC) {
 
 		lock_rec_dequeue_from_page(lock);
@@ -6271,6 +6274,8 @@ lock_cancel_waiting_and_release(
 	if (thr != NULL) {
 		lock_wait_release_thread_if_suspended(thr);
 	}
+
+	lock->trx->lock.cancel = FALSE;
 }
 
 /*********************************************************************//**

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (Sunny.Bains:3154 to 3155) Sunny Bains6 Jun