List:Commits« Previous MessageNext Message »
From:Sergey Vojtovich Date:February 26 2010 9:03am
Subject:bzr commit into mysql-5.1-bugteam branch (svoj:3362) Bug#49001
View as plain text  
#At file:///home/svoj/devel/innodb-snapshots/mysql-5.1-bugteam/ based on revid:svoj@stripped

 3362 Sergey Vojtovich	2010-02-26
      Applying InnoDB snapshot, fixes BUG#49001
      
      Detailed revision comments:
      
      r6545 | jyang | 2010-02-03 03:57:32 +0200 (Wed, 03 Feb 2010) | 8 lines
      branches/5.1: Fix bug #49001, "SHOW INNODB STATUS deadlock info
      incorrect when deadlock detection aborts". Print the correct
      lock owner when recursive function lock_deadlock_recursive()
      exceeds its maximum depth LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK.
      
      rb://217, approved by Marko.

    modified:
      storage/innobase/lock/lock0lock.c
=== modified file 'storage/innobase/lock/lock0lock.c'
--- a/storage/innobase/lock/lock0lock.c	2009-12-23 06:59:34 +0000
+++ b/storage/innobase/lock/lock0lock.c	2010-02-26 09:03:23 +0000
@@ -306,6 +306,7 @@ FILE*	lock_latest_err_file;
 /* Flags for recursive deadlock search */
 #define LOCK_VICTIM_IS_START	1
 #define LOCK_VICTIM_IS_OTHER	2
+#define LOCK_EXCEED_MAX_DEPTH	3
 
 /************************************************************************
 Checks if a lock request results in a deadlock. */
@@ -332,16 +333,18 @@ lock_deadlock_recursive(
 				was found and we chose some other trx as a
 				victim: we must do the search again in this
 				last case because there may be another
-				deadlock! */
+				deadlock!
+				LOCK_EXCEED_MAX_DEPTH if the lock search
+				exceeds max steps and/or max depth. */
 	trx_t*	start,		/* in: recursion starting point */
 	trx_t*	trx,		/* in: a transaction waiting for a lock */
 	lock_t*	wait_lock,	/* in: the lock trx is waiting to be granted */
 	ulint*	cost,		/* in/out: number of calculation steps thus
 				far: if this exceeds LOCK_MAX_N_STEPS_...
-				we return LOCK_VICTIM_IS_START */
+				we return LOCK_EXCEED_MAX_DEPTH */
 	ulint	depth);		/* in: recursion depth: if this exceeds
 				LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK, we
-				return LOCK_VICTIM_IS_START */
+				return LOCK_EXCEED_MAX_DEPTH */
 
 /*************************************************************************
 Gets the nth bit of a record lock. */
@@ -3084,8 +3087,6 @@ lock_deadlock_occurs(
 	lock_t*	lock,	/* in: lock the transaction is requesting */
 	trx_t*	trx)	/* in: transaction */
 {
-	dict_table_t*	table;
-	dict_index_t*	index;
 	trx_t*		mark_trx;
 	ulint		ret;
 	ulint		cost	= 0;
@@ -3107,31 +3108,50 @@ retry:
 
 	ret = lock_deadlock_recursive(trx, trx, lock, &cost, 0);
 
-	if (ret == LOCK_VICTIM_IS_OTHER) {
+	switch (ret) {
+	case LOCK_VICTIM_IS_OTHER:
 		/* We chose some other trx as a victim: retry if there still
 		is a deadlock */
-
 		goto retry;
-	}
 
-	if (ret == LOCK_VICTIM_IS_START) {
-		if (lock_get_type(lock) & LOCK_TABLE) {
-			table = lock->un_member.tab_lock.table;
-			index = NULL;
+	case LOCK_EXCEED_MAX_DEPTH:
+		/* If the lock search exceeds the max step
+		or the max depth, the current trx will be
+		the victim. Print its information. */
+		rewind(lock_latest_err_file);
+		ut_print_timestamp(lock_latest_err_file);
+
+		fputs("TOO DEEP OR LONG SEARCH IN THE LOCK TABLE"
+		      " WAITS-FOR GRAPH, WE WILL ROLL BACK"
+		      " FOLLOWING TRANSACTION \n",
+		      lock_latest_err_file);
+
+		fputs("\n*** TRANSACTION:\n", lock_latest_err_file);
+		      trx_print(lock_latest_err_file, trx, 3000);
+
+		fputs("*** WAITING FOR THIS LOCK TO BE GRANTED:\n",
+		      lock_latest_err_file);
+
+		if (lock_get_type(lock) == LOCK_REC) {
+			lock_rec_print(lock_latest_err_file, lock);
 		} else {
-			index = lock->index;
-			table = index->table;
+			lock_table_print(lock_latest_err_file, lock);
 		}
+		break;
 
-		lock_deadlock_found = TRUE;
-
+	case LOCK_VICTIM_IS_START:
 		fputs("*** WE ROLL BACK TRANSACTION (2)\n",
 		      lock_latest_err_file);
+		break;
 
-		return(TRUE);
+	default:
+		/* No deadlock detected*/
+		return(FALSE);
 	}
 
-	return(FALSE);
+	lock_deadlock_found = TRUE;
+
+	return(TRUE);
 }
 
 /************************************************************************
@@ -3147,16 +3167,18 @@ lock_deadlock_recursive(
 				was found and we chose some other trx as a
 				victim: we must do the search again in this
 				last case because there may be another
-				deadlock! */
+				deadlock!
+				LOCK_EXCEED_MAX_DEPTH if the lock search
+				exceeds max steps and/or max depth. */
 	trx_t*	start,		/* in: recursion starting point */
 	trx_t*	trx,		/* in: a transaction waiting for a lock */
 	lock_t*	wait_lock,	/* in: the lock trx is waiting to be granted */
 	ulint*	cost,		/* in/out: number of calculation steps thus
 				far: if this exceeds LOCK_MAX_N_STEPS_...
-				we return LOCK_VICTIM_IS_START */
+				we return LOCK_EXCEED_MAX_DEPTH */
 	ulint	depth)		/* in: recursion depth: if this exceeds
 				LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK, we
-				return LOCK_VICTIM_IS_START */
+				return LOCK_EXCEED_MAX_DEPTH */
 {
 	lock_t*	lock;
 	ulint	bit_no		= ULINT_UNDEFINED;
@@ -3215,7 +3237,7 @@ lock_deadlock_recursive(
 
 			lock_trx = lock->trx;
 
-			if (lock_trx == start || too_far) {
+			if (lock_trx == start) {
 
 				/* We came back to the recursion starting
 				point: a deadlock detected; or we have
@@ -3262,19 +3284,10 @@ lock_deadlock_recursive(
 				}
 #ifdef UNIV_DEBUG
 				if (lock_print_waits) {
-					fputs("Deadlock detected"
-					      " or too long search\n",
+					fputs("Deadlock detected\n",
 					      stderr);
 				}
 #endif /* UNIV_DEBUG */
-				if (too_far) {
-
-					fputs("TOO DEEP OR LONG SEARCH"
-					      " IN THE LOCK TABLE"
-					      " WAITS-FOR GRAPH\n", ef);
-
-					return(LOCK_VICTIM_IS_START);
-				}
 
 				if (trx_weight_cmp(wait_lock->trx,
 						   start) >= 0) {
@@ -3310,6 +3323,21 @@ lock_deadlock_recursive(
 				return(LOCK_VICTIM_IS_OTHER);
 			}
 
+			if (too_far) {
+
+#ifdef UNIV_DEBUG
+				if (lock_print_waits) {
+					fputs("Deadlock search exceeds"
+					      " max steps or depth.\n",
+					      stderr);
+				}
+#endif /* UNIV_DEBUG */
+				/* The information about transaction/lock
+				to be rolled back is available in the top
+				level. Do not print anything here. */
+				return(LOCK_EXCEED_MAX_DEPTH);
+			}
+
 			if (lock_trx->que_state == TRX_QUE_LOCK_WAIT) {
 
 				/* Another trx ahead has requested lock	in an


Attachment: [text/bzr-bundle] bzr/svoj@sun.com-20100226090323-m5f4hn2y4pk0w0l7.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (svoj:3362) Bug#49001Sergey Vojtovich26 Feb