Skip to content

Commit dcb0bd5

Browse files
committed
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.
1 parent f827ba3 commit dcb0bd5

File tree

1 file changed

+22
-9
lines changed

1 file changed

+22
-9
lines changed

storage/innobase/sync/sync0rw.cc

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -293,10 +293,13 @@ rw_lock_s_lock_spin(
293293

294294
ut_ad(rw_lock_validate(lock));
295295

296+
rw_lock_stats.rw_s_spin_wait_count.inc();
297+
296298
lock_loop:
297299

298300
/* Spin waiting for the writer field to become free */
299301
HMT_low();
302+
ulint j = i;
300303
while (i < srv_n_spin_wait_rounds && lock->lock_word <= 0) {
301304
ut_delay(srv_spin_wait_delay);
302305
i++;
@@ -307,7 +310,7 @@ rw_lock_s_lock_spin(
307310
os_thread_yield();
308311
}
309312

310-
++spin_count;
313+
spin_count += lint(i - j);
311314

312315
/* We try once again to obtain the lock */
313316
if (rw_lock_s_lock_low(lock, pass, file_name, line)) {
@@ -428,7 +431,7 @@ rw_lock_x_lock_wait_func(
428431
HMT_medium();
429432

430433
/* If there is still a reader, then go to sleep.*/
431-
++n_spins;
434+
n_spins += i;
432435

433436
sync_cell_t* cell;
434437

@@ -654,6 +657,12 @@ rw_lock_x_lock_func(
654657
ut_ad(rw_lock_validate(lock));
655658
ut_ad(!rw_lock_own(lock, RW_LOCK_S));
656659

660+
if (rw_lock_x_lock_low(lock, pass, file_name, line)) {
661+
/* Locking succeeded */
662+
return;
663+
}
664+
rw_lock_stats.rw_x_spin_wait_count.inc();
665+
657666
lock_loop:
658667

659668
if (rw_lock_x_lock_low(lock, pass, file_name, line)) {
@@ -673,6 +682,7 @@ rw_lock_x_lock_func(
673682

674683
/* Spin waiting for the lock_word to become free */
675684
HMT_low();
685+
ulint j = i;
676686
while (i < srv_n_spin_wait_rounds
677687
&& lock->lock_word <= X_LOCK_HALF_DECR) {
678688

@@ -681,7 +691,7 @@ rw_lock_x_lock_func(
681691
}
682692

683693
HMT_medium();
684-
spin_count += i;
694+
spin_count += lint(i - j);
685695

686696
if (i >= srv_n_spin_wait_rounds) {
687697

@@ -749,11 +759,17 @@ rw_lock_sx_lock_func(
749759
sync_array_t* sync_arr;
750760
ulint spin_count = 0;
751761
uint64_tcount_os_wait = 0;
752-
ulint spin_wait_count = 0;
753762

754763
ut_ad(rw_lock_validate(lock));
755764
ut_ad(!rw_lock_own(lock, RW_LOCK_S));
756765

766+
if (rw_lock_sx_lock_low(lock, pass, file_name, line)) {
767+
/* Locking succeeded */
768+
return;
769+
}
770+
771+
rw_lock_stats.rw_sx_spin_wait_count.inc();
772+
757773
lock_loop:
758774

759775
if (rw_lock_sx_lock_low(lock, pass, file_name, line)) {
@@ -765,24 +781,22 @@ rw_lock_sx_lock_func(
765781
}
766782

767783
rw_lock_stats.rw_sx_spin_round_count.add(spin_count);
768-
rw_lock_stats.rw_sx_spin_wait_count.add(spin_wait_count);
769784

770785
/* Locking succeeded */
771786
return;
772787

773788
} else {
774789

775-
++spin_wait_count;
776-
777790
/* Spin waiting for the lock_word to become free */
791+
ulint j = i;
778792
while (i < srv_n_spin_wait_rounds
779793
&& lock->lock_word <= X_LOCK_HALF_DECR) {
780794

781795
ut_delay(srv_spin_wait_delay);
782796
i++;
783797
}
784798

785-
spin_count += i;
799+
spin_count += lint(i - j);
786800

787801
if (i >= srv_n_spin_wait_rounds) {
788802

@@ -814,7 +828,6 @@ rw_lock_sx_lock_func(
814828
}
815829

816830
rw_lock_stats.rw_sx_spin_round_count.add(spin_count);
817-
rw_lock_stats.rw_sx_spin_wait_count.add(spin_wait_count);
818831

819832
/* Locking succeeded */
820833
return;

0 commit comments

Comments
 (0)