@@ -56,6 +56,9 @@ Created 5/7/1996 Heikki Tuuri
5656/* * Lock scheduling algorithm */
5757ulong innodb_lock_schedule_algorithm = INNODB_LOCK_SCHEDULE_ALGORITHM_FCFS;
5858
59+ /* * The value of innodb_deadlock_detect */
60+ my_bool innobase_deadlock_detect;
61+
5962/* * Total number of cached record locks */
6063static const ulint REC_LOCK_CACHE = 8 ;
6164
@@ -124,7 +127,7 @@ class DeadlockChecker {
124127@return id of transaction chosen as victim or 0 */
125128static const trx_t * check_and_resolve (
126129const lock_t * lock,
127- const trx_t * trx);
130+ trx_t * trx);
128131
129132private:
130133/* * Do a shallow copy. Default destructor OK.
@@ -2136,25 +2139,8 @@ RecLock::deadlock_check(lock_t* lock)
21362139ut_ad (lock->trx == m_trx);
21372140ut_ad (trx_mutex_own (m_trx));
21382141
2139- bool async_rollback = m_trx->in_innodb & TRX_FORCE_ROLLBACK_ASYNC;
2140-
2141- /* This is safe, because DeadlockChecker::check_and_resolve()
2142- is invoked when a lock wait is enqueued for the currently
2143- running transaction. Because m_trx is a running transaction
2144- (it is not currently suspended because of a lock wait),
2145- its state can only be changed by this thread, which is
2146- currently associated with the transaction. */
2147-
2148- trx_mutex_exit (m_trx);
2149-
2150- /* If transaction is marked for ASYNC rollback then we should
2151- not allow it to wait for another lock causing possible deadlock.
2152- We return current transaction as deadlock victim here. */
2153-
2154- const trx_t * victim_trx = async_rollback ? m_trx
2155- : DeadlockChecker::check_and_resolve (lock, m_trx);
2156-
2157- trx_mutex_enter (m_trx);
2142+ const trx_t * victim_trx =
2143+ DeadlockChecker::check_and_resolve (lock, m_trx);
21582144
21592145/* Check the outcome of the deadlock test. It is possible that
21602146the transaction that blocked our lock was rolled back and we
@@ -4653,25 +4639,8 @@ lock_table_enqueue_waiting(
46534639/* Enqueue the lock request that will wait to be granted */
46544640lock = lock_table_create (c_lock, table, mode | LOCK_WAIT, trx);
46554641
4656- bool async_rollback = trx->in_innodb & TRX_FORCE_ROLLBACK_ASYNC;
4657- /* Release the mutex to obey the latching order.
4658- This is safe, because DeadlockChecker::check_and_resolve()
4659- is invoked when a lock wait is enqueued for the currently
4660- running transaction. Because trx is a running transaction
4661- (it is not currently suspended because of a lock wait),
4662- its state can only be changed by this thread, which is
4663- currently associated with the transaction. */
4664-
4665- trx_mutex_exit (trx);
4666-
4667- /* If transaction is marked for ASYNC rollback then we should
4668- not allow it to wait for another lock causing possible deadlock.
4669- We return current transaction as deadlock victim here. */
4670-
4671- const trx_t * victim_trx = async_rollback ? trx
4672- : DeadlockChecker::check_and_resolve (lock, trx);
4673-
4674- trx_mutex_enter (trx);
4642+ const trx_t * victim_trx =
4643+ DeadlockChecker::check_and_resolve (lock, trx);
46754644
46764645if (victim_trx != 0 ) {
46774646ut_ad (victim_trx == trx);
@@ -8441,17 +8410,37 @@ and rolling it back. It will attempt to resolve all deadlocks. The returned
84418410transaction id will be the joining transaction instance or NULL if some other
84428411transaction was chosen as a victim and rolled back or no deadlock found.
84438412
8444- @param lock lock the transaction is requesting
8445- @param trx transaction requesting the lock
8413+ @param[in] lock lock the transaction is requesting
8414+ @param[in,out] trx transaction requesting the lock
84468415
84478416@return transaction instanace chosen as victim or 0 */
84488417const trx_t *
8449- DeadlockChecker::check_and_resolve (const lock_t * lock, const trx_t * trx)
8418+ DeadlockChecker::check_and_resolve (const lock_t * lock, trx_t * trx)
84508419{
84518420ut_ad (lock_mutex_own ());
8421+ ut_ad (trx_mutex_own (trx));
84528422check_trx_state (trx);
84538423ut_ad (!srv_read_only_mode);
84548424
8425+ /* If transaction is marked for ASYNC rollback then we should
8426+ not allow it to wait for another lock causing possible deadlock.
8427+ We return current transaction as deadlock victim here. */
8428+ if (trx->in_innodb & TRX_FORCE_ROLLBACK_ASYNC) {
8429+ return (trx);
8430+ } else if (!innobase_deadlock_detect) {
8431+ return (NULL );
8432+ }
8433+
8434+ /* Release the mutex to obey the latching order.
8435+ This is safe, because DeadlockChecker::check_and_resolve()
8436+ is invoked when a lock wait is enqueued for the currently
8437+ running transaction. Because m_trx is a running transaction
8438+ (it is not currently suspended because of a lock wait),
8439+ its state can only be changed by this thread, which is
8440+ currently associated with the transaction. */
8441+
8442+ trx_mutex_exit (trx);
8443+
84558444const trx_t * victim_trx;
84568445THD* start_mysql_thd;
84578446bool report_waits = false ;
@@ -8491,7 +8480,7 @@ DeadlockChecker::check_and_resolve(const lock_t* lock, const trx_t* trx)
84918480
84928481break ;
84938482
8494- } else if (victim_trx != 0 && victim_trx != trx) {
8483+ } else if (victim_trx != NULL && victim_trx != trx) {
84958484
84968485ut_ad (victim_trx == checker.m_wait_lock ->trx );
84978486
@@ -8512,6 +8501,8 @@ DeadlockChecker::check_and_resolve(const lock_t* lock, const trx_t* trx)
85128501lock_deadlock_found = true ;
85138502}
85148503
8504+ trx_mutex_enter (trx);
8505+
85158506return (victim_trx);
85168507}
85178508
0 commit comments