summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-09-05 13:39:54 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2019-09-05 14:13:17 +0300
commitd721643d0e568f866a550f4cf9bc4e84ed7150ef (patch)
treed936174647d0f190f59a24778dc120c15b8c3f3b
parent5e606183f15c7717f2ce413fcb435d71fcb958e8 (diff)
downloadmariadb-git-d721643d0e568f866a550f4cf9bc4e84ed7150ef.tar.gz
rw_trx_hash_t::find(): Remove redundant code, and avoid committer starvation
-rw-r--r--storage/innobase/include/trx0sys.h34
1 files changed, 26 insertions, 8 deletions
diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h
index c92907236e6..20dd14688a5 100644
--- a/storage/innobase/include/trx0sys.h
+++ b/storage/innobase/include/trx0sys.h
@@ -628,12 +628,7 @@ public:
The caller should already have handled trx_id==0 specially.
*/
ut_ad(trx_id);
- if (caller_trx && caller_trx->id == trx_id)
- {
- if (do_ref_count)
- caller_trx->reference();
- return caller_trx;
- }
+ ut_ad(!caller_trx || caller_trx->id != trx_id || !do_ref_count);
trx_t *trx= 0;
LF_PINS *pins= caller_trx ? get_pins(caller_trx) : lf_hash_get_pins(&hash);
@@ -649,8 +644,31 @@ public:
if ((trx= element->trx)) {
DBUG_ASSERT(trx_id == trx->id);
if (do_ref_count)
- trx->reference();
- ut_d(validate_element(trx));
+ {
+ TrxMutex *trx_mutex= &trx->mutex;
+ mutex_enter(trx_mutex);
+ ut_ad(!trx_state_eq(trx, TRX_STATE_NOT_STARTED));
+ if (trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY)) {
+ /* We have an early state check here to avoid committer
+ starvation in a wait loop for transaction references, when
+ there's a stream of trx_sys.find() calls from other
+ threads. The trx->state may change to COMMITTED after
+ trx_mutex is released, and it will have to be rechecked by
+ the caller after reacquiring the mutex. */
+ trx= NULL;
+ }
+ else
+ {
+ /* The reference could be safely incremented after
+ releasing one of trx_mutex or trx_sys->mutex. Holding
+ trx->mutex here may prevent a few false references that
+ could have a negative performance impact on
+ trx_commit_in_memory(). */
+ trx->reference();
+ }
+ mutex_exit(trx_mutex);
+ }
+ ut_d(if (trx) validate_element(trx));
}
mutex_exit(&element->mutex);
}