Skip to content

Commit 950ceea

Browse files
author
Jakub Łopuszański
committedJan 3, 2019
WL#12616 Make number of PAUSES in spin loops configurable
Introduced new dynamic sysvar @@innodb_spin_wait_pause_multiplier which lets you replace the default value of 50, with any number in range 0 to 100. It controls how many times in a row to use a PAUSE instruction to achieve one unit of delay in a spin lock (see @@innodb_spin_wait_delay), defaults to 50, which is backward-compatible. RB: 20851 Reviewed-by: Sunny Bains <Sunny.Bains@oracle.com> Reviewed-by: Dimitri Kravtchuk <dimitri.kravtchuk@oracle.com>
1 parent 6e8a1a3 commit 950ceea

File tree

7 files changed

+264
-17
lines changed

7 files changed

+264
-17
lines changed
 

‎mysql-test/r/all_persisted_variables.result

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,17 @@ include/assert.inc ['Expect 554 variables in the table. Due to open Bugs, we are
4343

4444
# Test SET PERSIST
4545

46-
include/assert.inc [Expect 373 persisted variables in the table. Due to open Bugs, we are checking for 368]
46+
include/assert.inc [Expect 374 persisted variables in the table. Due to open Bugs, we are checking for 369]
4747

4848
************************************************************
4949
* 3. Restart server, it must preserve the persisted variable
5050
* settings. Verify persisted configuration.
5151
************************************************************
5252
# restart
5353

54-
include/assert.inc [Expect 368 persisted variables in persisted_variables table.]
55-
include/assert.inc [Expect 368 persisted variables shown as PERSISTED in variables_info table.]
56-
include/assert.inc [Expect 368 persisted variables with matching peristed and global values.]
54+
include/assert.inc [Expect 369 persisted variables in persisted_variables table.]
55+
include/assert.inc [Expect 369 persisted variables shown as PERSISTED in variables_info table.]
56+
include/assert.inc [Expect 369 persisted variables with matching peristed and global values.]
5757

5858
************************************************************
5959
* 4. Test RESET PERSIST IF EXISTS. Verify persisted variable
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
SET @start_global_value = @@global.innodb_spin_wait_pause_multiplier;
2+
SELECT @start_global_value;
3+
@start_global_value
4+
50
5+
Valid values are zero or above
6+
select @@global.innodb_spin_wait_pause_multiplier >=0;
7+
@@global.innodb_spin_wait_pause_multiplier >=0
8+
1
9+
select @@global.innodb_spin_wait_pause_multiplier;
10+
@@global.innodb_spin_wait_pause_multiplier
11+
50
12+
select @@session.innodb_spin_wait_pause_multiplier;
13+
ERROR HY000: Variable 'innodb_spin_wait_pause_multiplier' is a GLOBAL variable
14+
show global variables like 'innodb_spin_wait_pause_multiplier';
15+
Variable_name Value
16+
innodb_spin_wait_pause_multiplier 50
17+
show session variables like 'innodb_spin_wait_pause_multiplier';
18+
Variable_name Value
19+
innodb_spin_wait_pause_multiplier 50
20+
select * from performance_schema.global_variables where variable_name='innodb_spin_wait_pause_multiplier';
21+
VARIABLE_NAME VARIABLE_VALUE
22+
innodb_spin_wait_pause_multiplier 50
23+
select * from performance_schema.session_variables where variable_name='innodb_spin_wait_pause_multiplier';
24+
VARIABLE_NAME VARIABLE_VALUE
25+
innodb_spin_wait_pause_multiplier 50
26+
set global innodb_spin_wait_pause_multiplier=10;
27+
select @@global.innodb_spin_wait_pause_multiplier;
28+
@@global.innodb_spin_wait_pause_multiplier
29+
10
30+
select * from performance_schema.global_variables where variable_name='innodb_spin_wait_pause_multiplier';
31+
VARIABLE_NAME VARIABLE_VALUE
32+
innodb_spin_wait_pause_multiplier 10
33+
select * from performance_schema.session_variables where variable_name='innodb_spin_wait_pause_multiplier';
34+
VARIABLE_NAME VARIABLE_VALUE
35+
innodb_spin_wait_pause_multiplier 10
36+
set session innodb_spin_wait_pause_multiplier=1;
37+
ERROR HY000: Variable 'innodb_spin_wait_pause_multiplier' is a GLOBAL variable and should be set with SET GLOBAL
38+
set global innodb_spin_wait_pause_multiplier=DEFAULT;
39+
select @@global.innodb_spin_wait_pause_multiplier;
40+
@@global.innodb_spin_wait_pause_multiplier
41+
50
42+
set global innodb_spin_wait_pause_multiplier=0;
43+
select @@global.innodb_spin_wait_pause_multiplier;
44+
@@global.innodb_spin_wait_pause_multiplier
45+
0
46+
set global innodb_spin_wait_pause_multiplier=3;
47+
select @@global.innodb_spin_wait_pause_multiplier;
48+
@@global.innodb_spin_wait_pause_multiplier
49+
3
50+
set global innodb_spin_wait_pause_multiplier=100;
51+
select @@global.innodb_spin_wait_pause_multiplier;
52+
@@global.innodb_spin_wait_pause_multiplier
53+
100
54+
set global innodb_spin_wait_pause_multiplier=101;
55+
Warnings:
56+
Warning 1292 Truncated incorrect innodb_spin_wait_pause_multiplie value: '101'
57+
select @@global.innodb_spin_wait_pause_multiplier;
58+
@@global.innodb_spin_wait_pause_multiplier
59+
100
60+
set global innodb_spin_wait_pause_multiplier=65535;
61+
Warnings:
62+
Warning 1292 Truncated incorrect innodb_spin_wait_pause_multiplie value: '65535'
63+
select @@global.innodb_spin_wait_pause_multiplier;
64+
@@global.innodb_spin_wait_pause_multiplier
65+
100
66+
set global innodb_spin_wait_pause_multiplier=4294967295;
67+
Warnings:
68+
Warning 1292 Truncated incorrect innodb_spin_wait_pause_multiplie value: '4294967295'
69+
select @@global.innodb_spin_wait_pause_multiplier;
70+
@@global.innodb_spin_wait_pause_multiplier
71+
100
72+
set global innodb_spin_wait_pause_multiplier=1.1;
73+
ERROR 42000: Incorrect argument type to variable 'innodb_spin_wait_pause_multiplier'
74+
set global innodb_spin_wait_pause_multiplier=1e1;
75+
ERROR 42000: Incorrect argument type to variable 'innodb_spin_wait_pause_multiplier'
76+
set global innodb_spin_wait_pause_multiplier="foo";
77+
ERROR 42000: Incorrect argument type to variable 'innodb_spin_wait_pause_multiplier'
78+
set global innodb_spin_wait_pause_multiplier=' ';
79+
ERROR 42000: Incorrect argument type to variable 'innodb_spin_wait_pause_multiplier'
80+
select @@global.innodb_spin_wait_pause_multiplier;
81+
@@global.innodb_spin_wait_pause_multiplier
82+
100
83+
set global innodb_spin_wait_pause_multiplier=" ";
84+
ERROR 42000: Incorrect argument type to variable 'innodb_spin_wait_pause_multiplier'
85+
select @@global.innodb_spin_wait_pause_multiplier;
86+
@@global.innodb_spin_wait_pause_multiplier
87+
100
88+
set global innodb_spin_wait_pause_multiplier=-7;
89+
Warnings:
90+
Warning 1292 Truncated incorrect innodb_spin_wait_pause_multiplie value: '-7'
91+
select @@global.innodb_spin_wait_pause_multiplier;
92+
@@global.innodb_spin_wait_pause_multiplier
93+
0
94+
set global innodb_spin_wait_pause_multiplier=-1024;
95+
Warnings:
96+
Warning 1292 Truncated incorrect innodb_spin_wait_pause_multiplie value: '-1024'
97+
select @@global.innodb_spin_wait_pause_multiplier;
98+
@@global.innodb_spin_wait_pause_multiplier
99+
0
100+
select * from performance_schema.global_variables where variable_name='innodb_spin_wait_pause_multiplier';
101+
VARIABLE_NAME VARIABLE_VALUE
102+
innodb_spin_wait_pause_multiplier 0
103+
SET @@global.innodb_spin_wait_pause_multiplier = 4294967296;
104+
SELECT @@global.innodb_spin_wait_pause_multiplier IN (4294967296,4294967295);
105+
@@global.innodb_spin_wait_pause_multiplier IN (4294967296,4294967295)
106+
0
107+
SET @@global.innodb_spin_wait_pause_multiplier = 12345678901;
108+
SELECT @@global.innodb_spin_wait_pause_multiplier IN (12345678901,4294967295);
109+
@@global.innodb_spin_wait_pause_multiplier IN (12345678901,4294967295)
110+
0
111+
SET @@global.innodb_spin_wait_pause_multiplier = 18446744073709551615;
112+
SELECT @@global.innodb_spin_wait_pause_multiplier IN (18446744073709551615,4294967295);
113+
@@global.innodb_spin_wait_pause_multiplier IN (18446744073709551615,4294967295)
114+
0
115+
SET @@global.innodb_spin_wait_pause_multiplier = @start_global_value;
116+
SELECT @@global.innodb_spin_wait_pause_multiplier;
117+
@@global.innodb_spin_wait_pause_multiplier
118+
50
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
SET @start_global_value = @@global.innodb_spin_wait_pause_multiplier;
2+
SELECT @start_global_value;
3+
4+
#
5+
# exists as global only
6+
#
7+
--echo Valid values are zero or above
8+
select @@global.innodb_spin_wait_pause_multiplier >=0;
9+
select @@global.innodb_spin_wait_pause_multiplier;
10+
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
11+
select @@session.innodb_spin_wait_pause_multiplier;
12+
show global variables like 'innodb_spin_wait_pause_multiplier';
13+
show session variables like 'innodb_spin_wait_pause_multiplier';
14+
--disable_warnings
15+
select * from performance_schema.global_variables where variable_name='innodb_spin_wait_pause_multiplier';
16+
select * from performance_schema.session_variables where variable_name='innodb_spin_wait_pause_multiplier';
17+
--enable_warnings
18+
19+
#
20+
# show that it's writable
21+
#
22+
set global innodb_spin_wait_pause_multiplier=10;
23+
select @@global.innodb_spin_wait_pause_multiplier;
24+
--disable_warnings
25+
select * from performance_schema.global_variables where variable_name='innodb_spin_wait_pause_multiplier';
26+
select * from performance_schema.session_variables where variable_name='innodb_spin_wait_pause_multiplier';
27+
--enable_warnings
28+
--error ER_GLOBAL_VARIABLE
29+
set session innodb_spin_wait_pause_multiplier=1;
30+
31+
#
32+
# check the default value
33+
#
34+
set global innodb_spin_wait_pause_multiplier=DEFAULT;
35+
select @@global.innodb_spin_wait_pause_multiplier;
36+
37+
#
38+
# valid values
39+
#
40+
set global innodb_spin_wait_pause_multiplier=0;
41+
select @@global.innodb_spin_wait_pause_multiplier;
42+
set global innodb_spin_wait_pause_multiplier=3;
43+
select @@global.innodb_spin_wait_pause_multiplier;
44+
set global innodb_spin_wait_pause_multiplier=100;
45+
select @@global.innodb_spin_wait_pause_multiplier;
46+
#
47+
# values of valid type by too large
48+
#
49+
set global innodb_spin_wait_pause_multiplier=101;
50+
select @@global.innodb_spin_wait_pause_multiplier;
51+
set global innodb_spin_wait_pause_multiplier=65535;
52+
select @@global.innodb_spin_wait_pause_multiplier;
53+
set global innodb_spin_wait_pause_multiplier=4294967295;
54+
select @@global.innodb_spin_wait_pause_multiplier;
55+
56+
#
57+
# incorrect types
58+
#
59+
--error ER_WRONG_TYPE_FOR_VAR
60+
set global innodb_spin_wait_pause_multiplier=1.1;
61+
--error ER_WRONG_TYPE_FOR_VAR
62+
set global innodb_spin_wait_pause_multiplier=1e1;
63+
--error ER_WRONG_TYPE_FOR_VAR
64+
set global innodb_spin_wait_pause_multiplier="foo";
65+
--error ER_WRONG_TYPE_FOR_VAR
66+
set global innodb_spin_wait_pause_multiplier=' ';
67+
select @@global.innodb_spin_wait_pause_multiplier;
68+
--error ER_WRONG_TYPE_FOR_VAR
69+
set global innodb_spin_wait_pause_multiplier=" ";
70+
select @@global.innodb_spin_wait_pause_multiplier;
71+
set global innodb_spin_wait_pause_multiplier=-7;
72+
select @@global.innodb_spin_wait_pause_multiplier;
73+
set global innodb_spin_wait_pause_multiplier=-1024;
74+
select @@global.innodb_spin_wait_pause_multiplier;
75+
--disable_warnings
76+
select * from performance_schema.global_variables where variable_name='innodb_spin_wait_pause_multiplier';
77+
--enable_warnings
78+
79+
#
80+
# Check for out of bounds
81+
#
82+
83+
# With a 64 bit mysqld:18446744073709551615,with a 32 bit mysqld: 4294967295
84+
--disable_warnings
85+
SET @@global.innodb_spin_wait_pause_multiplier = 4294967296;
86+
--enable_warnings
87+
SELECT @@global.innodb_spin_wait_pause_multiplier IN (4294967296,4294967295);
88+
89+
--disable_warnings
90+
SET @@global.innodb_spin_wait_pause_multiplier = 12345678901;
91+
--enable_warnings
92+
SELECT @@global.innodb_spin_wait_pause_multiplier IN (12345678901,4294967295);
93+
94+
--disable_warnings
95+
SET @@global.innodb_spin_wait_pause_multiplier = 18446744073709551615;
96+
--enable_warnings
97+
SELECT @@global.innodb_spin_wait_pause_multiplier IN (18446744073709551615,4294967295);
98+
99+
#
100+
# cleanup
101+
#
102+
SET @@global.innodb_spin_wait_pause_multiplier = @start_global_value;
103+
SELECT @@global.innodb_spin_wait_pause_multiplier;

‎mysql-test/t/all_persisted_variables.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
call mtr.add_suppression("Failed to set up SSL because of the following SSL library error");
4040

4141
let $total_global_vars=`SELECT COUNT(*) FROM performance_schema.global_variables where variable_name NOT LIKE 'ndb_%'`;
42-
let $total_persistent_vars=373;
42+
let $total_persistent_vars=374;
4343

4444
--echo ***************************************************************
4545
--echo * 0. Verify that variables present in performance_schema.global

‎storage/innobase/handler/ha_innodb.cc

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*****************************************************************************
22

3-
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All Rights Reserved.
3+
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All Rights Reserved.
44
Copyright (c) 2008, 2009 Google Inc.
55
Copyright (c) 2009, Percona Inc.
66
Copyright (c) 2012, Facebook Inc.
@@ -21169,6 +21169,13 @@ static MYSQL_SYSVAR_ULONG(
2116921169
"Maximum delay between polling for a spin lock (6 by default)", NULL, NULL,
2117021170
6L, 0L, 1000, 0);
2117121171

21172+
static MYSQL_SYSVAR_ULONG(spin_wait_pause_multiplier,
21173+
ut::spin_wait_pause_multiplier, PLUGIN_VAR_RQCMDARG,
21174+
"Controls how many times in a row to use a PAUSE "
21175+
"instruction to achieve one unit of delay in a spin "
21176+
"lock (see @@innodb_spin_wait_delay), defaults to 50",
21177+
NULL, NULL, 50, 0, 100, 0);
21178+
2117221179
static MYSQL_SYSVAR_ULONGLONG(
2117321180
fsync_threshold, os_fsync_threshold, PLUGIN_VAR_RQCMDARG,
2117421181
"The value of this variable determines how often InnoDB calls fsync when "
@@ -21649,6 +21656,7 @@ static SYS_VAR *innobase_system_variables[] = {
2164921656
MYSQL_SYSVAR(directories),
2165021657
MYSQL_SYSVAR(sync_spin_loops),
2165121658
MYSQL_SYSVAR(spin_wait_delay),
21659+
MYSQL_SYSVAR(spin_wait_pause_multiplier),
2165221660
MYSQL_SYSVAR(fsync_threshold),
2165321661
MYSQL_SYSVAR(table_locks),
2165421662
MYSQL_SYSVAR(thread_concurrency),

‎storage/innobase/include/ut0ut.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*****************************************************************************
22
3-
Copyright (c) 1994, 2018, Oracle and/or its affiliates. All Rights Reserved.
3+
Copyright (c) 1994, 2019, Oracle and/or its affiliates. All Rights Reserved.
44
55
This program is free software; you can redistribute it and/or modify it under
66
the terms of the GNU General Public License, version 2.0, as published by the
@@ -262,11 +262,25 @@ struct ut_strcmp_functor {
262262
}
263263
};
264264

265+
namespace ut {
266+
/** The current value of @@innodb_spin_wait_pause_multiplier. Determines
267+
how many PAUSE instructions to emit for each requested unit of delay
268+
when calling `ut_delay(delay)`. The default value of 50 causes `delay*50` PAUSES
269+
which was equivalent to `delay` microseconds on 100 MHz Pentium + Visual C++.
270+
Useful on processors which have "non-standard" duration of a single PAUSE
271+
instruction - one can compensate for longer PAUSES by setting the
272+
spin_wait_pause_multiplier to a smaller value on such machine */
273+
extern ulong spin_wait_pause_multiplier;
274+
} // namespace ut
275+
265276
/** Runs an idle loop on CPU. The argument gives the desired delay
266277
in microseconds on 100 MHz Pentium + Visual C++.
278+
The actual duration depends on a product of `delay` and the current value of
279+
@@innodb_spin_wait_pause_multiplier.
280+
@param[in] delay delay in microseconds on 100 MHz Pentium, assuming
281+
spin_wait_pause_multiplier is 50 (default).
267282
@return dummy value */
268-
ulint ut_delay(
269-
ulint delay); /*!< in: delay in microseconds on 100 MHz Pentium */
283+
ulint ut_delay(ulint delay);
270284

271285
/* Forward declaration of transaction handle */
272286
struct trx_t;

‎storage/innobase/ut/ut0ut.cc

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*****************************************************************************
22
3-
Copyright (c) 1994, 2018, Oracle and/or its affiliates. All Rights Reserved.
3+
Copyright (c) 1994, 2019, Oracle and/or its affiliates. All Rights Reserved.
44
55
This program is free software; you can redistribute it and/or modify it under
66
the terms of the GNU General Public License, version 2.0, as published by the
@@ -58,6 +58,10 @@ this program; if not, write to the Free Software Foundation, Inc.,
5858
#include "mysql/components/services/log_builtins.h"
5959
#include "sql/derror.h"
6060

61+
namespace ut {
62+
ulong spin_wait_pause_multiplier = 50;
63+
}
64+
6165
#ifdef _WIN32
6266
using time_fn = VOID(WINAPI *)(_Out_ LPFILETIME);
6367
static time_fn ut_get_system_time_as_file_time = GetSystemTimeAsFileTime;
@@ -253,18 +257,18 @@ void meb_sprintf_timestamp_without_extra_chars(
253257

254258
#else /* UNIV_HOTBACKUP */
255259

256-
/** Runs an idle loop on CPU. The argument gives the desired delay
257-
in microseconds on 100 MHz Pentium + Visual C++.
258-
@return dummy value */
259-
ulint ut_delay(ulint delay) /*!< in: delay in microseconds on 100 MHz Pentium */
260-
{
260+
ulint ut_delay(ulint delay) {
261261
ulint i, j;
262-
262+
/* We don't expect overflow here, as ut::spin_wait_pause_multiplier is limited
263+
to 100, and values of delay are not larger than @@innodb_spin_wait_delay
264+
which is limited by 1 000. Anyway, in case an overflow happened, the program
265+
would still work (as iterations is unsigned). */
266+
const ulint iterations = delay * ut::spin_wait_pause_multiplier;
263267
UT_LOW_PRIORITY_CPU();
264268

265269
j = 0;
266270

267-
for (i = 0; i < delay * 50; i++) {
271+
for (i = 0; i < iterations; i++) {
268272
j += i;
269273
UT_RELAX_CPU();
270274
}

0 commit comments

Comments
 (0)