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