summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKrunal Bauskar <krunalbauskar@gmail.com>2020-05-14 15:05:36 +0800
committerKrunal Bauskar <krunalbauskar@gmail.com>2020-05-14 15:27:15 +0800
commitdcb0bd59cedbd2e8fa4220986863549d614fb05e (patch)
tree57f6b75dedcb583e72a8b63da2ce3cd6c8575bc7
parentf827ba3b842d4bd18be37d4b983665b5840251bf (diff)
downloadmariadb-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.cc31
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;