diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2021-01-26 16:39:56 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2021-01-27 15:45:39 +0200 |
commit | e71e6133535da8d5eab86e504f0b116a03680780 (patch) | |
tree | 160adf5e0ded57571fa18e376534953f2602d1e8 /storage/innobase/include/trx0trx.h | |
parent | 7f1ab8f742ac42e82dd39a6e11390254cb72319c (diff) | |
download | mariadb-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.h | 55 |
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)); |