diff options
author | Krunal Bauskar <krunalbauskar@gmail.com> | 2020-05-14 15:05:36 +0800 |
---|---|---|
committer | Krunal Bauskar <krunalbauskar@gmail.com> | 2020-05-14 15:27:15 +0800 |
commit | dcb0bd59cedbd2e8fa4220986863549d614fb05e (patch) | |
tree | 57f6b75dedcb583e72a8b63da2ce3cd6c8575bc7 | |
parent | f827ba3b842d4bd18be37d4b983665b5840251bf (diff) | |
download | mariadb-git-dcb0bd59cedbd2e8fa4220986863549d614fb05e.tar.gz |
MDEV-22544: Inconsistent and Incorrect rw-lock stats
- There are multiple inconsistency and incorrect way in which rw-lock
stats are calculated.
- shared rw-lock stats:
"rounds" counter is incremented only once for N rounds done
in spin-cycle.
- all rw-lock stats:
If the spin-cycle is short-circuited then attempts are re-counted.
[If spin-cycle is interrupted, before it completes
srv_n_spin_wait_rounds (default 30) rounds, spin_count is incremented
to consider this. If thread resumes spin-cycle (due to unavailability
of the locks) and is again interrupted or completed, spin_count
is again incremented with the total count, failing to adjust the
previous attempt increment].
- s/x rw-lock stats:
spin_loop counter is not incremented at-all instead it is projected
as 0 (in show engine output) and division to calculate spin-round per
spin-loop is adjusted.
As per the original semantics spin_loop counter should be incremented
once per spin_loop execution.
- sx rw-lock stats:
sx locks increments spin_loop counter but instead of incrementing it
once for a spin_loop invocation it does it multiple times based on how
many time spin_loop flow is repeated for same instance post os-wait.
-rw-r--r-- | storage/innobase/sync/sync0rw.cc | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/storage/innobase/sync/sync0rw.cc b/storage/innobase/sync/sync0rw.cc index df710a53cf6..b46126bde58 100644 --- a/storage/innobase/sync/sync0rw.cc +++ b/storage/innobase/sync/sync0rw.cc @@ -293,10 +293,13 @@ rw_lock_s_lock_spin( ut_ad(rw_lock_validate(lock)); + rw_lock_stats.rw_s_spin_wait_count.inc(); + lock_loop: /* Spin waiting for the writer field to become free */ HMT_low(); + ulint j = i; while (i < srv_n_spin_wait_rounds && lock->lock_word <= 0) { ut_delay(srv_spin_wait_delay); i++; @@ -307,7 +310,7 @@ lock_loop: os_thread_yield(); } - ++spin_count; + spin_count += lint(i - j); /* We try once again to obtain the lock */ if (rw_lock_s_lock_low(lock, pass, file_name, line)) { @@ -428,7 +431,7 @@ rw_lock_x_lock_wait_func( HMT_medium(); /* If there is still a reader, then go to sleep.*/ - ++n_spins; + n_spins += i; sync_cell_t* cell; @@ -654,6 +657,12 @@ rw_lock_x_lock_func( ut_ad(rw_lock_validate(lock)); ut_ad(!rw_lock_own(lock, RW_LOCK_S)); + if (rw_lock_x_lock_low(lock, pass, file_name, line)) { + /* Locking succeeded */ + return; + } + rw_lock_stats.rw_x_spin_wait_count.inc(); + lock_loop: if (rw_lock_x_lock_low(lock, pass, file_name, line)) { @@ -673,6 +682,7 @@ lock_loop: /* Spin waiting for the lock_word to become free */ HMT_low(); + ulint j = i; while (i < srv_n_spin_wait_rounds && lock->lock_word <= X_LOCK_HALF_DECR) { @@ -681,7 +691,7 @@ lock_loop: } HMT_medium(); - spin_count += i; + spin_count += lint(i - j); if (i >= srv_n_spin_wait_rounds) { @@ -749,11 +759,17 @@ rw_lock_sx_lock_func( sync_array_t* sync_arr; ulint spin_count = 0; uint64_t count_os_wait = 0; - ulint spin_wait_count = 0; ut_ad(rw_lock_validate(lock)); ut_ad(!rw_lock_own(lock, RW_LOCK_S)); + if (rw_lock_sx_lock_low(lock, pass, file_name, line)) { + /* Locking succeeded */ + return; + } + + rw_lock_stats.rw_sx_spin_wait_count.inc(); + lock_loop: if (rw_lock_sx_lock_low(lock, pass, file_name, line)) { @@ -765,16 +781,14 @@ lock_loop: } rw_lock_stats.rw_sx_spin_round_count.add(spin_count); - rw_lock_stats.rw_sx_spin_wait_count.add(spin_wait_count); /* Locking succeeded */ return; } else { - ++spin_wait_count; - /* Spin waiting for the lock_word to become free */ + ulint j = i; while (i < srv_n_spin_wait_rounds && lock->lock_word <= X_LOCK_HALF_DECR) { @@ -782,7 +796,7 @@ lock_loop: i++; } - spin_count += i; + spin_count += lint(i - j); if (i >= srv_n_spin_wait_rounds) { @@ -814,7 +828,6 @@ lock_loop: } rw_lock_stats.rw_sx_spin_round_count.add(spin_count); - rw_lock_stats.rw_sx_spin_wait_count.add(spin_wait_count); /* Locking succeeded */ return; |