List:Commits« Previous MessageNext Message »
From:Sunny Bains Date:June 11 2010 2:13am
Subject:bzr commit into mysql-5.6-sunny branch (Sunny.Bains:3144)
View as plain text  
#At file:///Users/sunny/innodb/bzr-new/5.6/ based on revid:sunny.bains@stripped

 3144 Sunny Bains	2010-06-11
      Move all lock_mutex_enter()/lock_mutex_exit() to lock0*.c except for trx0i_s.c.
      Introduce two new functions to handle the previous use case.

    modified:
      storage/innobase/include/lock0lock.h
      storage/innobase/include/lock0priv.h
      storage/innobase/lock/lock0lock.c
      storage/innobase/lock/lock0wait.c
      storage/innobase/row/row0sel.c
      storage/innobase/trx/trx0trx.c
=== modified file 'storage/innobase/include/lock0lock.h'
--- a/storage/innobase/include/lock0lock.h	revid:sunny.bains@stripped
+++ b/storage/innobase/include/lock0lock.h	revid:sunny.bains@stripped
@@ -484,24 +484,15 @@ lock_rec_unlock(
 	const rec_t*		rec,	/*!< in: record */
 	enum lock_mode		lock_mode);/*!< in: LOCK_S or LOCK_X */
 /*********************************************************************//**
-Releases transaction locks, and releases possible other transactions waiting
-because of these locks. Caller must reserve the followin locks before
-calling: lock_mutex, trx_sys_mutex and the trx mutex. */
+Releases a transaction's locks, and releases possible other transactions
+waiting because of these locks. Change the state of the transaction to
+TRX_COMMITTED_IN_MEMORY. */
 UNIV_INTERN
 void
-lock_release(
-/*=========*/
+lock_trx_release_locks(
+/*===================*/
 	trx_t*	trx);	/*!< in: transaction */
 /*********************************************************************//**
-Cancels a waiting lock request and releases possible other transactions
-waiting behind it. */
-UNIV_INTERN
-void
-lock_cancel_waiting_and_release(
-/*============================*/
-	lock_t*	lock);	/*!< in: waiting lock request */
-
-/*********************************************************************//**
 Removes locks on a table to be dropped or truncated.
 If remove_also_table_sx_locks is TRUE then table-level S and X locks are
 also removed in addition to other table-level and record-level locks.
@@ -792,6 +783,24 @@ void
 lock_unlock_table_autoinc_for_mysql(
 /*===============================*/
 	trx_t*	trx);			/*!< in/out: transaction */
+/*********************************************************************//**
+Check whether the transaction has already been rolled back because it
+was selected as a deadlock victim, or if it has to wait then cancel
+the wait lock.
+@return DB_DEADLOCK, DB_LOCK_WAIT or DB_SUCCESS */
+UNIV_INTERN
+enum db_err
+lock_trx_handle_wait(
+/*=================*/
+	trx_t*		trx); 	/*!< in, out: trx lock state */
+/*********************************************************************//**
+Get the number of locks on a table.
+@return number of locks */
+UNIV_INTERN
+ulint
+lock_table_get_n_locks(
+/*===================*/
+	dict_table_t*	table);
 /** Lock modes and types */
 /* @{ */
 #define LOCK_MODE_MASK	0xFUL	/*!< mask used to extract mode from the

=== modified file 'storage/innobase/include/lock0priv.h'
--- a/storage/innobase/include/lock0priv.h	revid:sunny.bains@stripped
+++ b/storage/innobase/include/lock0priv.h	revid:sunny.bains@stripped
@@ -101,6 +101,15 @@ lock_rec_get_prev(
 	const lock_t*	in_lock,/*!< in: record lock */
 	ulint		heap_no);/*!< in: heap number of the record */
 
+/*********************************************************************//**
+Cancels a waiting lock request and releases possible other transactions
+waiting behind it. */
+UNIV_INTERN
+void
+lock_cancel_waiting_and_release(
+/*============================*/
+	lock_t*		lock);	/*!< in: waiting lock request */
+
 #ifndef UNIV_NONINL
 #include "lock0priv.ic"
 #endif

=== modified file 'storage/innobase/lock/lock0lock.c'
--- a/storage/innobase/lock/lock0lock.c	revid:sunny.bains@stripped
+++ b/storage/innobase/lock/lock0lock.c	revid:sunny.bains@stripped
@@ -4076,7 +4076,7 @@ released:
 /*********************************************************************//**
 Releases transaction locks, and releases possible other transactions waiting
 because of these locks. */
-UNIV_INTERN
+static
 void
 lock_release(
 /*=========*/
@@ -5879,7 +5879,6 @@ lock_cancel_waiting_and_release(
 	}
 }
 
-
 /*********************************************************************//**
 Unlocks AUTO_INC type locks that were possibly reserved by a trx. This
 function should be called at the the end of an SQL statement, by the
@@ -5899,3 +5898,106 @@ lock_unlock_table_autoinc(
 	}
 }
 
+/*********************************************************************//**
+Releases a transaction's locks, and releases possible other transactions
+waiting because of these locks. Change the state of the transaction to
+TRX_COMMITTED_IN_MEMORY. */
+UNIV_INTERN
+void
+lock_trx_release_locks(
+/*===================*/
+	trx_t*	trx)	/*!< in: transaction */
+{
+	lock_mutex_enter();
+
+	ut_ad(trx->lock.conc_state == TRX_ACTIVE
+	      || trx->lock.conc_state == TRX_PREPARED);
+
+	/* The following assignment makes the transaction committed in memory
+	and makes its changes to data visible to other transactions.
+	NOTE that there is a small discrepancy from the strict formal
+	visibility rules here: a human user of the database can see
+	modifications made by another transaction T even before the necessary
+	log segment has been flushed to the disk. If the database happens to
+	crash before the flush, the user has seen modifications from T which
+	will never be a committed transaction. However, any transaction T2
+	which sees the modifications of the committing transaction T, and
+	which also itself makes modifications to the database, will get an lsn
+	larger than the committing transaction T. In the case where the log
+	flush fails, and T never gets committed, also T2 will never get
+	committed. */
+
+	/*--------------------------------------*/
+	trx->lock.conc_state = TRX_COMMITTED_IN_MEMORY;
+	/*--------------------------------------*/
+
+	/* If we release transaction mutex below and we are still doing
+	recovery i.e.: back ground rollback thread is still active
+	then there is a chance that the rollback thread may see
+	this trx as COMMITTED_IN_MEMORY and goes adhead to clean it
+	up calling trx_cleanup_at_db_startup(). This can happen
+	in the case we are committing a trx here that is left in
+	PREPARED state during the crash. Note that commit of the
+	rollback of a PREPARED trx happens in the recovery thread
+	while the rollback of other transactions happen in the
+	background thread. To avoid this race we unconditionally
+	unset the is_recovered flag from the trx. */
+
+	lock_release(trx);
+
+	lock_mutex_exit();
+}
+
+/*********************************************************************//**
+Check whether the transaction has already been rolled back because it
+was selected as a deadlock victim, or if it has to wait then cancel
+the wait lock.
+@return DB_DEADLOCK, DB_LOCK_WAIT or DB_SUCCESS */
+UNIV_INTERN
+enum db_err
+lock_trx_handle_wait(
+/*=================*/
+	trx_t*		trx) 	/*!< in, out: trx lock state */
+{
+	enum db_err	err;
+
+	lock_mutex_enter();
+
+	trx_mutex_enter(trx);
+
+	if (trx->lock.was_chosen_as_deadlock_victim) {
+		err = DB_DEADLOCK;
+	} else if (trx->lock.wait_lock != NULL) {
+		lock_cancel_waiting_and_release(trx->lock.wait_lock);
+		err = DB_LOCK_WAIT;
+	} else {
+		/* The lock was probably granted before we got here. */
+		err = DB_SUCCESS;
+	}
+
+	trx_mutex_exit(trx);
+
+	lock_mutex_exit();
+
+	return(err);
+}
+
+/*********************************************************************//**
+Get the number of locks on a table.
+@return number of locks */
+UNIV_INTERN
+ulint
+lock_table_get_n_locks(
+/*===================*/
+	dict_table_t*	table)
+{
+	ulint		n_table_locks;
+
+	lock_mutex_enter();
+
+	n_table_locks = UT_LIST_GET_LEN(table->locks);
+
+	lock_mutex_exit();
+
+	return(n_table_locks);
+}

=== modified file 'storage/innobase/lock/lock0wait.c'
--- a/storage/innobase/lock/lock0wait.c	revid:sunny.bains@stripped
+++ b/storage/innobase/lock/lock0wait.c	revid:sunny.bains@stripped
@@ -23,12 +23,15 @@ The transaction lock system
 Created 25/5/2010 Sunny Bains
 *******************************************************/
 
+#define LOCK_MODULE_IMPLEMENTATION
+
 #include "srv0mon.h"
 #include "que0que.h"
 #include "lock0lock.h"
 #include "row0mysql.h"
 #include "srv0start.h"
 #include "ha_prototypes.h"
+#include "lock0priv.h"
 
 UNIV_INTERN ibool	srv_lock_timeout_active 	= FALSE;
 UNIV_INTERN ulint	srv_n_lock_wait_count		= 0;

=== modified file 'storage/innobase/row/row0sel.c'
--- a/storage/innobase/row/row0sel.c	revid:sunny.bains@stripped
+++ b/storage/innobase/row/row0sel.c	revid:sunny.bains@stripped
@@ -4110,23 +4110,13 @@ no_gap_lock:
 				goto lock_wait_or_error;
 			}
 
-			lock_mutex_enter();
-                        trx_mutex_enter(trx);
-			if (trx->lock.was_chosen_as_deadlock_victim) {
-                                trx_mutex_exit(trx);
-				lock_mutex_exit();
-				err = DB_DEADLOCK;
+			/* Check whether it was a deadlock or not, if not
+			a deadlock and the transaction had to wait then
+			release the lock it is waiting on. */
 
-				goto lock_wait_or_error;
-			}
-			if (trx->lock.wait_lock != NULL) {
-
-				lock_cancel_waiting_and_release(
-					trx->lock.wait_lock);
-			} else {
-                                trx_mutex_exit(trx);
-				lock_mutex_exit();
+			err = lock_trx_handle_wait(trx);
 
+			if (err == DB_SUCCESS) {
 				/* The lock was granted while we were
 				searching for the last committed version.
 				Do a normal locking read. */
@@ -4134,11 +4124,10 @@ no_gap_lock:
 				offsets = rec_get_offsets(rec, index, offsets,
 							  ULINT_UNDEFINED,
 							  &heap);
-				err = DB_SUCCESS;
 				break;
+			} else {
+				goto lock_wait_or_error;
 			}
-                        trx_mutex_exit(trx);
-			lock_mutex_exit();
 
 			if (old_vers == NULL) {
 				/* The row was not yet committed */
@@ -4622,11 +4611,8 @@ row_search_check_if_query_cache_permitte
 	We do not check what type locks there are on the table, though only
 	IX type locks actually would require ret = FALSE. */
 
-	lock_mutex_enter();
-
-	if (UT_LIST_GET_LEN(table->locks) == 0
-	    && ut_dulint_cmp(trx->id,
-			     table->query_cache_inv_trx_id) >= 0) {
+	if (lock_get_table_n_locks(table) == 0
+	    && ut_dulint_cmp(trx->id, table->query_cache_inv_trx_id) >= 0) {
 
 		ret = TRUE;
 
@@ -4647,8 +4633,6 @@ row_search_check_if_query_cache_permitte
 		}
 	}
 
-	lock_mutex_exit();
-
 	return(ret);
 }
 

=== modified file 'storage/innobase/trx/trx0trx.c'
--- a/storage/innobase/trx/trx0trx.c	revid:sunny.bains@stripped
+++ b/storage/innobase/trx/trx0trx.c	revid:sunny.bains@stripped
@@ -750,44 +750,7 @@ trx_commit(
 
 	trx->must_flush_log_later = FALSE;
 
-	lock_mutex_enter();
-
-	ut_ad(trx->lock.conc_state == TRX_ACTIVE
-	      || trx->lock.conc_state == TRX_PREPARED);
-
-	/* The following assignment makes the transaction committed in memory
-	and makes its changes to data visible to other transactions.
-	NOTE that there is a small discrepancy from the strict formal
-	visibility rules here: a human user of the database can see
-	modifications made by another transaction T even before the necessary
-	log segment has been flushed to the disk. If the database happens to
-	crash before the flush, the user has seen modifications from T which
-	will never be a committed transaction. However, any transaction T2
-	which sees the modifications of the committing transaction T, and
-	which also itself makes modifications to the database, will get an lsn
-	larger than the committing transaction T. In the case where the log
-	flush fails, and T never gets committed, also T2 will never get
-	committed. */
-
-	/*--------------------------------------*/
-	trx->lock.conc_state = TRX_COMMITTED_IN_MEMORY;
-	/*--------------------------------------*/
-
-	/* If we release transaction mutex below and we are still doing
-	recovery i.e.: back ground rollback thread is still active
-	then there is a chance that the rollback thread may see
-	this trx as COMMITTED_IN_MEMORY and goes adhead to clean it
-	up calling trx_cleanup_at_db_startup(). This can happen
-	in the case we are committing a trx here that is left in
-	PREPARED state during the crash. Note that commit of the
-	rollback of a PREPARED trx happens in the recovery thread
-	while the rollback of other transactions happen in the
-	background thread. To avoid this race we unconditionally
-	unset the is_recovered flag from the trx. */
-
-	lock_release(trx);
-
-	lock_mutex_exit();
+	lock_trx_release_locks(trx);
 
 	trx_sys_mutex_enter();
 


Attachment: [text/bzr-bundle] bzr/sunny.bains@oracle.com-20100611021227-kdk6lp25gosng78v.bundle
Thread
bzr commit into mysql-5.6-sunny branch (Sunny.Bains:3144) Sunny Bains11 Jun