summaryrefslogtreecommitdiff
path: root/storage/innobase/include/trx0trx.h
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-01-26 16:39:56 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2021-01-27 15:45:39 +0200
commite71e6133535da8d5eab86e504f0b116a03680780 (patch)
tree160adf5e0ded57571fa18e376534953f2602d1e8 /storage/innobase/include/trx0trx.h
parent7f1ab8f742ac42e82dd39a6e11390254cb72319c (diff)
downloadmariadb-git-e71e6133535da8d5eab86e504f0b116a03680780.tar.gz
MDEV-24671: Replace lock_wait_timeout_task with mysql_cond_timedwait()
lock_wait(): Replaces lock_wait_suspend_thread(). Wait for the lock to be granted or the transaction to be killed using mysql_cond_timedwait() or mysql_cond_wait(). lock_wait_end(): Replaces que_thr_end_lock_wait() and lock_wait_release_thread_if_suspended(). lock_wait_timeout_task: Remove. The operating system kernel will resume the mysql_cond_timedwait() in lock_wait(). An added benefit is that innodb_lock_wait_timeout no longer has a 'jitter' of 1 second, which was caused by this wake-up task waking up only once per second, and then waking up any threads for which the timeout (which was only measured in seconds) was exceeded. innobase_kill_query(): Set trx->error_state=DB_INTERRUPTED, so that a call trx_is_interrupted(trx) in lock_wait() can be avoided. We will protect things more consistently with lock_sys.wait_mutex, which will be moved below lock_sys.mutex in the latching order. trx_lock_t::cond: Condition variable for !wait_lock, used with lock_sys.wait_mutex. srv_slot_t: Remove. Replaced by trx_lock_t::cond, lock_grant_after_reset(): Merged to to lock_grant(). lock_rec_get_index_name(): Remove. lock_sys_t: Introduce wait_pending, wait_count, wait_time, wait_time_max that are protected by wait_mutex. trx_lock_t::que_state: Remove. que_thr_state_t: Remove QUE_THR_COMMAND_WAIT, QUE_THR_LOCK_WAIT. que_thr_t: Remove is_active, start_running(), stop_no_error(). que_fork_t::n_active_thrs, trx_lock_t::n_active_thrs: Remove.
Diffstat (limited to 'storage/innobase/include/trx0trx.h')
-rw-r--r--storage/innobase/include/trx0trx.h55
1 files changed, 12 insertions, 43 deletions
diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
index 878b611864d..ca327c9a594 100644
--- a/storage/innobase/include/trx0trx.h
+++ b/storage/innobase/include/trx0trx.h
@@ -416,48 +416,19 @@ The transaction must have mysql_thd assigned. */
typedef std::vector<ib_lock_t*, ut_allocator<ib_lock_t*> > lock_list;
-/*******************************************************************//**
-Latching protocol for trx_lock_t::que_state. trx_lock_t::que_state
-captures the state of the query thread during the execution of a query.
-This is different from a transaction state. The query state of a transaction
-can be updated asynchronously by other threads. The other threads can be
-system threads, like the timeout monitor thread or user threads executing
-other queries. Another thing to be mindful of is that there is a delay between
-when a query thread is put into LOCK_WAIT state and before it actually starts
-waiting. Between these two events it is possible that the query thread is
-granted the lock it was waiting for, which implies that the state can be changed
-asynchronously.
-
-All these operations take place within the context of locking. Therefore state
-changes within the locking code must acquire both the lock mutex and the
-trx->mutex when changing trx->lock.que_state to TRX_QUE_LOCK_WAIT or
-trx->lock.wait_lock to non-NULL but when the lock wait ends it is sufficient
-to only acquire the trx->mutex.
-To query the state either of the mutexes is sufficient within the locking
-code and no mutex is required when the query thread is no longer waiting. */
-
/** The locks and state of an active transaction. Protected by
lock_sys.mutex, trx->mutex or both. */
struct trx_lock_t {
-#ifdef UNIV_DEBUG
- /** number of active query threads; at most 1, except for the
- dummy transaction in trx_purge() */
- ulint n_active_thrs;
-#endif
- trx_que_t que_state; /*!< valid when trx->state
- == TRX_STATE_ACTIVE: TRX_QUE_RUNNING,
- TRX_QUE_LOCK_WAIT, ... */
-
- lock_t* wait_lock; /*!< if trx execution state is
- TRX_QUE_LOCK_WAIT, this points to
- the lock request, otherwise this is
- NULL; set to non-NULL when holding
- both trx->mutex and lock_sys.mutex;
- set to NULL when holding
- lock_sys.mutex; readers should
- hold lock_sys.mutex, except when
- they are holding trx->mutex and
- wait_lock==NULL */
+ /** Lock request being waited for.
+ Set to nonnull when holding lock_sys.mutex, lock_sys.wait_mutex and
+ trx->mutex, by the thread that is executing the transaction.
+ Set to nullptr when holding lock_sys.wait_mutex. */
+ Atomic_relaxed<lock_t*> wait_lock;
+ /** condition variable for !wait_lock; used with lock_sys.wait_mutex */
+ mysql_cond_t cond;
+ /** lock wait start time, protected only by lock_sys.wait_mutex */
+ my_hrtime_t suspend_time;
+
ib_uint64_t deadlock_mark; /*!< A mark field that is initialized
to and checked against lock_mark_counter
by lock_deadlock_recursive(). */
@@ -468,11 +439,8 @@ struct trx_lock_t {
transaction as a victim in deadlock
resolution, it sets this to true.
Protected by trx->mutex. */
- time_t wait_started; /*!< lock wait started at this time,
- protected only by lock_sys.mutex */
-
que_thr_t* wait_thr; /*!< query thread belonging to this
- trx that is in QUE_THR_LOCK_WAIT
+ trx that is in waiting
state. For threads suspended in a
lock wait, this is protected by
lock_sys.mutex. Otherwise, this may
@@ -1067,6 +1035,7 @@ public:
#endif
ut_ad(!read_view.is_open());
ut_ad(!lock.wait_thr);
+ ut_ad(!lock.wait_lock);
ut_ad(UT_LIST_GET_LEN(lock.trx_locks) == 0);
ut_ad(lock.table_locks.empty());
ut_ad(!autoinc_locks || ib_vector_is_empty(autoinc_locks));