Commit 4e359eb8 authored by Marko Mäkelä's avatar Marko Mäkelä

Cleanup: Reduce trx_t::mutex hold time

parent 814bc213
...@@ -1872,8 +1872,6 @@ lock_rec_cancel( ...@@ -1872,8 +1872,6 @@ lock_rec_cancel(
/*============*/ /*============*/
lock_t* lock) /*!< in: waiting record lock request */ lock_t* lock) /*!< in: waiting record lock request */
{ {
que_thr_t* thr;
ut_ad(lock_mutex_own()); ut_ad(lock_mutex_own());
ut_ad(lock_get_type_low(lock) == LOCK_REC); ut_ad(lock_get_type_low(lock) == LOCK_REC);
...@@ -1884,17 +1882,13 @@ lock_rec_cancel( ...@@ -1884,17 +1882,13 @@ lock_rec_cancel(
lock_reset_lock_and_trx_wait(lock); lock_reset_lock_and_trx_wait(lock);
/* The following function releases the trx from lock wait */ /* The following releases the trx from lock wait */
trx_t *trx = lock->trx;
trx_mutex_enter(lock->trx); trx_mutex_enter(trx);
if (que_thr_t* thr = que_thr_end_lock_wait(trx)) {
thr = que_thr_end_lock_wait(lock->trx);
if (thr != NULL) {
lock_wait_release_thread_if_suspended(thr); lock_wait_release_thread_if_suspended(thr);
} }
trx_mutex_exit(trx);
trx_mutex_exit(lock->trx);
} }
/** Remove a record lock request, waiting or granted, from the queue and /** Remove a record lock request, waiting or granted, from the queue and
...@@ -3755,7 +3749,6 @@ lock_rec_unlock( ...@@ -3755,7 +3749,6 @@ lock_rec_unlock(
heap_no = page_rec_get_heap_no(rec); heap_no = page_rec_get_heap_no(rec);
lock_mutex_enter(); lock_mutex_enter();
trx_mutex_enter(trx);
first_lock = lock_rec_get_first(&lock_sys.rec_hash, block, heap_no); first_lock = lock_rec_get_first(&lock_sys.rec_hash, block, heap_no);
...@@ -3770,7 +3763,6 @@ lock_rec_unlock( ...@@ -3770,7 +3763,6 @@ lock_rec_unlock(
} }
lock_mutex_exit(); lock_mutex_exit();
trx_mutex_exit(trx);
{ {
ib::error err; ib::error err;
...@@ -3809,7 +3801,6 @@ lock_rec_unlock( ...@@ -3809,7 +3801,6 @@ lock_rec_unlock(
} }
lock_mutex_exit(); lock_mutex_exit();
trx_mutex_exit(trx);
} }
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
...@@ -3925,7 +3916,8 @@ lock_trx_table_locks_remove( ...@@ -3925,7 +3916,8 @@ lock_trx_table_locks_remove(
ut_ad(lock_mutex_own()); ut_ad(lock_mutex_own());
/* It is safe to read this because we are holding the lock mutex */ /* It is safe to read this because we are holding the lock mutex */
if (!trx->lock.cancel) { const bool have_mutex = trx->lock.cancel;
if (!have_mutex) {
trx_mutex_enter(trx); trx_mutex_enter(trx);
} else { } else {
ut_ad(trx_mutex_own(trx)); ut_ad(trx_mutex_own(trx));
...@@ -3942,7 +3934,7 @@ lock_trx_table_locks_remove( ...@@ -3942,7 +3934,7 @@ lock_trx_table_locks_remove(
if (lock == lock_to_remove) { if (lock == lock_to_remove) {
*it = NULL; *it = NULL;
if (!trx->lock.cancel) { if (!have_mutex) {
trx_mutex_exit(trx); trx_mutex_exit(trx);
} }
...@@ -3950,10 +3942,6 @@ lock_trx_table_locks_remove( ...@@ -3950,10 +3942,6 @@ lock_trx_table_locks_remove(
} }
} }
if (!trx->lock.cancel) {
trx_mutex_exit(trx);
}
/* Lock must exist in the vector. */ /* Lock must exist in the vector. */
ut_error; ut_error;
} }
......
...@@ -920,20 +920,14 @@ lock_place_prdt_page_lock( ...@@ -920,20 +920,14 @@ lock_place_prdt_page_lock(
trx_t* trx = thr_get_trx(thr); trx_t* trx = thr_get_trx(thr);
if (lock != NULL) { if (lock != NULL) {
trx_mutex_enter(trx);
/* Find a matching record lock owned by this transaction. */ /* Find a matching record lock owned by this transaction. */
while (lock != NULL && lock->trx != trx) { while (lock != NULL && lock->trx != trx) {
lock = lock_rec_get_next_on_page_const(lock); lock = lock_rec_get_next_on_page_const(lock);
} }
ut_ad(lock == NULL || lock->type_mode == (mode | LOCK_REC)); ut_ad(lock == NULL || lock->type_mode == (mode | LOCK_REC));
ut_ad(lock == NULL || lock_rec_get_n_bits(lock) != 0); ut_ad(lock == NULL || lock_rec_get_n_bits(lock) != 0);
trx_mutex_exit(trx);
} }
if (lock == NULL) { if (lock == NULL) {
......
...@@ -459,24 +459,21 @@ lock_wait_check_and_cancel( ...@@ -459,24 +459,21 @@ lock_wait_check_and_cancel(
lock_mutex_enter(); lock_mutex_enter();
trx_mutex_enter(trx);
if (trx->lock.wait_lock != NULL) { if (trx->lock.wait_lock != NULL) {
ut_a(trx->lock.que_state == TRX_QUE_LOCK_WAIT); ut_a(trx->lock.que_state == TRX_QUE_LOCK_WAIT);
#ifdef WITH_WSREP #ifdef WITH_WSREP
if (!wsrep_is_BF_lock_timeout(trx)) { if (!wsrep_is_BF_lock_timeout(trx)) {
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
mutex_enter(&trx->mutex);
lock_cancel_waiting_and_release(trx->lock.wait_lock); lock_cancel_waiting_and_release(trx->lock.wait_lock);
mutex_exit(&trx->mutex);
#ifdef WITH_WSREP #ifdef WITH_WSREP
} }
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
} }
lock_mutex_exit(); lock_mutex_exit();
trx_mutex_exit(trx);
} }
} }
......
...@@ -590,22 +590,18 @@ que_thr_node_step( ...@@ -590,22 +590,18 @@ que_thr_node_step(
return(thr); return(thr);
} }
trx_mutex_enter(thr_get_trx(thr)); auto mutex = &thr->graph->trx->mutex;
if (que_thr_peek_stop(thr)) { mutex_enter(mutex);
trx_mutex_exit(thr_get_trx(thr)); if (!que_thr_peek_stop(thr)) {
/* Thread execution completed */
return(thr); thr->state = QUE_THR_COMPLETED;
thr = NULL;
} }
/* Thread execution completed */ mutex_exit(mutex);
return(thr);
thr->state = QUE_THR_COMPLETED;
trx_mutex_exit(thr_get_trx(thr));
return(NULL);
} }
/**********************************************************************//** /**********************************************************************//**
...@@ -728,27 +724,24 @@ que_thr_stop_for_mysql( ...@@ -728,27 +724,24 @@ que_thr_stop_for_mysql(
trx_mutex_enter(trx); trx_mutex_enter(trx);
if (thr->state == QUE_THR_RUNNING) { if (thr->state == QUE_THR_RUNNING) {
switch (trx->error_state) {
if (trx->error_state != DB_SUCCESS default:
&& trx->error_state != DB_LOCK_WAIT) { /* Error handling built for the MariaDB interface */
/* Error handling built for the MySQL interface */
thr->state = QUE_THR_COMPLETED; thr->state = QUE_THR_COMPLETED;
} else { break;
case DB_SUCCESS:
case DB_LOCK_WAIT:
/* It must have been a lock wait but the lock was /* It must have been a lock wait but the lock was
already released, or this transaction was chosen already released, or this transaction was chosen
as a victim in selective deadlock resolution */ as a victim in selective deadlock resolution */
goto func_exit;
trx_mutex_exit(trx);
return;
} }
} }
ut_ad(thr->is_active); ut_ad(thr->is_active);
ut_d(thr->set_active(false)); ut_d(thr->set_active(false));
thr->is_active= false; thr->is_active= false;
func_exit:
trx_mutex_exit(trx); trx_mutex_exit(trx);
} }
...@@ -1009,28 +1002,23 @@ que_run_threads_low( ...@@ -1009,28 +1002,23 @@ que_run_threads_low(
next_thr = que_thr_step(thr); next_thr = que_thr_step(thr);
/*-------------------------*/ /*-------------------------*/
trx_mutex_enter(trx); if (next_thr) {
ut_a(trx->error_state == DB_SUCCESS);
ut_a(next_thr == NULL || trx->error_state == DB_SUCCESS); ut_a(next_thr == thr);
} else {
if (next_thr != thr) {
ut_a(next_thr == NULL);
/* This can change next_thr to a non-NULL value /* This can change next_thr to a non-NULL value
if there was a lock wait that already completed. */ if there was a lock wait that already completed. */
mutex_enter(&trx->mutex);
que_thr_dec_refer_count(thr, &next_thr); que_thr_dec_refer_count(thr, &next_thr);
mutex_exit(&trx->mutex);
if (next_thr != NULL) { if (next_thr != NULL) {
thr = next_thr; thr = next_thr;
} }
} }
ut_ad(trx == thr_get_trx(thr)); ut_ad(trx == thr_get_trx(thr));
trx_mutex_exit(trx);
} while (next_thr != NULL); } while (next_thr != NULL);
} }
...@@ -1049,6 +1037,12 @@ que_run_threads( ...@@ -1049,6 +1037,12 @@ que_run_threads(
que_run_threads_low(thr); que_run_threads_low(thr);
switch (thr->state) { switch (thr->state) {
default:
ut_error;
case QUE_THR_COMPLETED:
case QUE_THR_COMMAND_WAIT:
/* Do nothing */
break;
case QUE_THR_RUNNING: case QUE_THR_RUNNING:
/* There probably was a lock wait, but it already ended /* There probably was a lock wait, but it already ended
...@@ -1058,30 +1052,21 @@ que_run_threads( ...@@ -1058,30 +1052,21 @@ que_run_threads(
case QUE_THR_LOCK_WAIT: case QUE_THR_LOCK_WAIT:
lock_wait_suspend_thread(thr); lock_wait_suspend_thread(thr);
trx_t* trx = thr->graph->trx;
trx_mutex_enter(thr_get_trx(thr)); trx_mutex_enter(trx);
ut_ad(trx->id);
ut_a(thr_get_trx(thr)->id != 0); const dberr_t err = trx->error_state;
if (err != DB_SUCCESS) {
if (thr_get_trx(thr)->error_state != DB_SUCCESS) {
/* thr was chosen as a deadlock victim or there was /* thr was chosen as a deadlock victim or there was
a lock wait timeout */ a lock wait timeout */
que_thr_dec_refer_count(thr, NULL); que_thr_dec_refer_count(thr, NULL);
trx_mutex_exit(thr_get_trx(thr));
break;
} }
trx_mutex_exit(trx);
trx_mutex_exit(thr_get_trx(thr)); if (err == DB_SUCCESS) {
goto loop; goto loop;
}
case QUE_THR_COMPLETED:
case QUE_THR_COMMAND_WAIT:
/* Do nothing */
break;
default:
ut_error;
} }
} }
......
...@@ -959,14 +959,14 @@ trx_rollback_step( ...@@ -959,14 +959,14 @@ trx_rollback_step(
trx = thr_get_trx(thr); trx = thr_get_trx(thr);
trx_mutex_enter(trx);
node->state = ROLL_NODE_WAIT; node->state = ROLL_NODE_WAIT;
ut_a(node->undo_thr == NULL); ut_a(node->undo_thr == NULL);
roll_limit = node->savept ? node->savept->least_undo_no : 0; roll_limit = node->savept ? node->savept->least_undo_no : 0;
trx_mutex_enter(trx);
trx_commit_or_rollback_prepare(trx); trx_commit_or_rollback_prepare(trx);
node->undo_thr = trx_rollback_start(trx, roll_limit); node->undo_thr = trx_rollback_start(trx, roll_limit);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment