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 Bains | 6 Jun |