diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2019-09-05 13:39:54 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2019-09-05 14:13:17 +0300 |
commit | d721643d0e568f866a550f4cf9bc4e84ed7150ef (patch) | |
tree | d936174647d0f190f59a24778dc120c15b8c3f3b | |
parent | 5e606183f15c7717f2ce413fcb435d71fcb958e8 (diff) | |
download | mariadb-git-d721643d0e568f866a550f4cf9bc4e84ed7150ef.tar.gz |
rw_trx_hash_t::find(): Remove redundant code, and avoid committer starvation
-rw-r--r-- | storage/innobase/include/trx0sys.h | 34 |
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); } |