Skip to content

Commit 92d05db

Browse files
committed
wl#13115 : InnoDB: Add new option to control write IOPs when idle
Added a new server variable : Name : innodb_idle_flush_pct Default : 100 Scope : global Dynamic : yes Using this server variable user can configure how much dirty pages to be flushed during idle period. Before this WL, all the dirty pages were tried to be flushed. RB : 22166 Reviewd By : yasufumi.kinoshita@oracle.com
1 parent 3618671 commit 92d05db

10 files changed

+310
-7
lines changed

mysql-test/r/all_persisted_variables.result

+4-4
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,17 @@ include/assert.inc [Expect 500+ variables in the table. Due to open Bugs, we are
3737

3838
# Test SET PERSIST
3939

40-
include/assert.inc [Expect 380 persisted variables in the table.]
40+
include/assert.inc [Expect 381 persisted variables in the table.]
4141

4242
************************************************************
4343
* 3. Restart server, it must preserve the persisted variable
4444
* settings. Verify persisted configuration.
4545
************************************************************
4646
# restart
4747

48-
include/assert.inc [Expect 380 persisted variables in persisted_variables table.]
49-
include/assert.inc [Expect 380 persisted variables shown as PERSISTED in variables_info table.]
50-
include/assert.inc [Expect 380 persisted variables with matching peristed and global values.]
48+
include/assert.inc [Expect 381 persisted variables in persisted_variables table.]
49+
include/assert.inc [Expect 381 persisted variables shown as PERSISTED in variables_info table.]
50+
include/assert.inc [Expect 381 persisted variables with matching peristed and global values.]
5151

5252
************************************************************
5353
* 4. Test RESET PERSIST IF EXISTS. Verify persisted variable
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#########
2+
# Setup #
3+
#########
4+
CREATE TABLE t1 (c INT);
5+
INSERT INTO t1 VALUES (1), (2), (3), (4);
6+
SET @innodb_io_capacity_saved = @@global.innodb_io_capacity;
7+
SET @innodb_idle_flush_pct_saved = @@global.innodb_idle_flush_pct;
8+
SET GLOBAL innodb_io_capacity = 200;
9+
SHOW VARIABLES LIKE "%innodb_io_capacity%";
10+
Variable_name Value
11+
innodb_io_capacity 200
12+
innodb_io_capacity_max 2000
13+
SET GLOBAL innodb_page_cleaner_disabled_debug = 1;
14+
set global innodb_idle_flush_pct=0;
15+
SET GLOBAL innodb_monitor_enable = all;
16+
SELECT COUNT=0 FROM INFORMATION_SCHEMA.INNODB_METRICS
17+
WHERE NAME='buffer_flush_batch_total_pages';
18+
COUNT=0
19+
1
20+
SET GLOBAL innodb_limit_optimistic_insert_debug=2;
21+
insert into t1 select * from t1;
22+
insert into t1 select * from t1;
23+
insert into t1 select * from t1;
24+
insert into t1 select * from t1;
25+
insert into t1 select * from t1;
26+
insert into t1 select * from t1;
27+
SELECT COUNT>0 FROM INFORMATION_SCHEMA.INNODB_METRICS
28+
WHERE NAME='buffer_pool_pages_dirty';
29+
COUNT>0
30+
1
31+
SELECT COUNT=0 FROM INFORMATION_SCHEMA.INNODB_METRICS
32+
WHERE NAME='buffer_flush_batch_total_pages';
33+
COUNT=0
34+
1
35+
SET GLOBAL innodb_page_cleaner_disabled_debug = 0;
36+
SET GLOBAL innodb_idle_flush_pct=25;
37+
# Waiting for buffer pool pages to get flushed
38+
SELECT COUNT>0 FROM INFORMATION_SCHEMA.INNODB_METRICS
39+
WHERE NAME='buffer_flush_background_total_pages';
40+
COUNT>0
41+
1
42+
###########
43+
# Cleanup #
44+
###########
45+
SET GLOBAL innodb_io_capacity = @innodb_io_capacity_saved;
46+
SET GLOBAL innodb_idle_flush_pct = @innodb_idle_flush_pct_saved;
47+
SET GLOBAL innodb_limit_optimistic_insert_debug=0;
48+
SET GLOBAL innodb_monitor_disable = all;
49+
SET GLOBAL innodb_monitor_reset_all = all;
50+
SELECT COUNT>0 FROM INFORMATION_SCHEMA.INNODB_METRICS
51+
WHERE NAME='buffer_flush_background_total_pages';
52+
COUNT>0
53+
0
54+
SET GLOBAL innodb_monitor_disable = default;
55+
SET GLOBAL innodb_monitor_enable = default;
56+
SET GLOBAL innodb_monitor_reset_all = default;
57+
DROP TABLE t1;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
################################################################################
2+
# Test script to test working of innodb_idle_flush_pct.
3+
################################################################################
4+
5+
--source include/have_debug.inc
6+
7+
--echo #########
8+
--echo # Setup #
9+
--echo #########
10+
CREATE TABLE t1 (c INT);
11+
INSERT INTO t1 VALUES (1), (2), (3), (4);
12+
13+
SET @innodb_io_capacity_saved = @@global.innodb_io_capacity;
14+
SET @innodb_idle_flush_pct_saved = @@global.innodb_idle_flush_pct;
15+
16+
# Set io capacity to 200
17+
SET GLOBAL innodb_io_capacity = 200;
18+
SHOW VARIABLES LIKE "%innodb_io_capacity%";
19+
20+
# Disable page cleaner
21+
SET GLOBAL innodb_page_cleaner_disabled_debug = 1;
22+
23+
# Set varaible to 0 so no flush happens
24+
set global innodb_idle_flush_pct=0;
25+
26+
# Enable monitoring of Innodb
27+
SET GLOBAL innodb_monitor_enable = all;
28+
29+
# Make sure counter are 0
30+
SELECT COUNT=0 FROM INFORMATION_SCHEMA.INNODB_METRICS
31+
WHERE NAME='buffer_flush_batch_total_pages';
32+
33+
# Every page keeps 2 recods max
34+
SET GLOBAL innodb_limit_optimistic_insert_debug=2;
35+
36+
# Insert multiple rows to make sure we have enough pages dirty
37+
insert into t1 select * from t1;
38+
insert into t1 select * from t1;
39+
insert into t1 select * from t1;
40+
insert into t1 select * from t1;
41+
insert into t1 select * from t1;
42+
insert into t1 select * from t1;
43+
44+
# Till now we must have some dirty pages in Buffer Pool
45+
--sleep 2
46+
47+
# Total dirty pages in buffer pool
48+
SELECT COUNT>0 FROM INFORMATION_SCHEMA.INNODB_METRICS
49+
WHERE NAME='buffer_pool_pages_dirty';
50+
51+
# Noting would have flushed yet, so counter should be 0
52+
SELECT COUNT=0 FROM INFORMATION_SCHEMA.INNODB_METRICS
53+
WHERE NAME='buffer_flush_batch_total_pages';
54+
55+
# Enable page cleaner
56+
SET GLOBAL innodb_page_cleaner_disabled_debug = 0;
57+
58+
# Set varaible to value > 0 so that flush happens
59+
SET GLOBAL innodb_idle_flush_pct=25;
60+
61+
# Let flush happen
62+
--echo # Waiting for buffer pool pages to get flushed
63+
let $wait_condition=SELECT COUNT=0 FROM INFORMATION_SCHEMA.INNODB_METRICS
64+
WHERE NAME='buffer_pool_pages_dirty';
65+
--source include/wait_condition.inc
66+
67+
# Pages should have been flushed now
68+
SELECT COUNT>0 FROM INFORMATION_SCHEMA.INNODB_METRICS
69+
WHERE NAME='buffer_flush_background_total_pages';
70+
71+
--echo ###########
72+
--echo # Cleanup #
73+
--echo ###########
74+
SET GLOBAL innodb_io_capacity = @innodb_io_capacity_saved;
75+
SET GLOBAL innodb_idle_flush_pct = @innodb_idle_flush_pct_saved;
76+
SET GLOBAL innodb_limit_optimistic_insert_debug=0;
77+
SET GLOBAL innodb_monitor_disable = all;
78+
SET GLOBAL innodb_monitor_reset_all = all;
79+
SELECT COUNT>0 FROM INFORMATION_SCHEMA.INNODB_METRICS
80+
WHERE NAME='buffer_flush_background_total_pages';
81+
--disable_warnings
82+
SET GLOBAL innodb_monitor_disable = default;
83+
SET GLOBAL innodb_monitor_enable = default;
84+
SET GLOBAL innodb_monitor_reset_all = default;
85+
--enable_warnings
86+
DROP TABLE t1;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
SET @start_global_value = @@global.innodb_idle_flush_pct;
2+
SELECT @start_global_value;
3+
@start_global_value
4+
100
5+
Valid values are between 0 and 100
6+
select @@global.innodb_idle_flush_pct between 0 and 100;
7+
@@global.innodb_idle_flush_pct between 0 and 100
8+
1
9+
select @@global.innodb_idle_flush_pct;
10+
@@global.innodb_idle_flush_pct
11+
100
12+
select @@session.innodb_idle_flush_pct;
13+
ERROR HY000: Variable 'innodb_idle_flush_pct' is a GLOBAL variable
14+
show global variables like 'innodb_idle_flush_pct';
15+
Variable_name Value
16+
innodb_idle_flush_pct 100
17+
show session variables like 'innodb_idle_flush_pct';
18+
Variable_name Value
19+
innodb_idle_flush_pct 100
20+
select * from performance_schema.global_variables where variable_name='innodb_idle_flush_pct';
21+
VARIABLE_NAME VARIABLE_VALUE
22+
innodb_idle_flush_pct 100
23+
select * from performance_schema.session_variables where variable_name='innodb_idle_flush_pct';
24+
VARIABLE_NAME VARIABLE_VALUE
25+
innodb_idle_flush_pct 100
26+
set global innodb_idle_flush_pct=10;
27+
select @@global.innodb_idle_flush_pct;
28+
@@global.innodb_idle_flush_pct
29+
10
30+
select * from performance_schema.global_variables where variable_name='innodb_idle_flush_pct';
31+
VARIABLE_NAME VARIABLE_VALUE
32+
innodb_idle_flush_pct 10
33+
select * from performance_schema.session_variables where variable_name='innodb_idle_flush_pct';
34+
VARIABLE_NAME VARIABLE_VALUE
35+
innodb_idle_flush_pct 10
36+
set session innodb_idle_flush_pct=1;
37+
ERROR HY000: Variable 'innodb_idle_flush_pct' is a GLOBAL variable and should be set with SET GLOBAL
38+
set global innodb_idle_flush_pct=1.1;
39+
ERROR 42000: Incorrect argument type to variable 'innodb_idle_flush_pct'
40+
set global innodb_idle_flush_pct=1e1;
41+
ERROR 42000: Incorrect argument type to variable 'innodb_idle_flush_pct'
42+
set global innodb_idle_flush_pct="bar";
43+
ERROR 42000: Incorrect argument type to variable 'innodb_idle_flush_pct'
44+
set global innodb_idle_flush_pct=ON;
45+
ERROR 42000: Incorrect argument type to variable 'innodb_idle_flush_pct'
46+
set global innodb_idle_flush_pct=OFF;
47+
ERROR 42000: Incorrect argument type to variable 'innodb_idle_flush_pct'
48+
set global innodb_idle_flush_pct=-7;
49+
Warnings:
50+
Warning 1292 Truncated incorrect innodb_idle_flush_pct value: '-7'
51+
select @@global.innodb_idle_flush_pct;
52+
@@global.innodb_idle_flush_pct
53+
0
54+
select * from performance_schema.global_variables where variable_name='innodb_idle_flush_pct';
55+
VARIABLE_NAME VARIABLE_VALUE
56+
innodb_idle_flush_pct 0
57+
set global innodb_idle_flush_pct=101;
58+
Warnings:
59+
Warning 1292 Truncated incorrect innodb_idle_flush_pct value: '101'
60+
select @@global.innodb_idle_flush_pct;
61+
@@global.innodb_idle_flush_pct
62+
100
63+
select * from performance_schema.global_variables where variable_name='innodb_idle_flush_pct';
64+
VARIABLE_NAME VARIABLE_VALUE
65+
innodb_idle_flush_pct 100
66+
set global innodb_idle_flush_pct=0;
67+
select @@global.innodb_idle_flush_pct;
68+
@@global.innodb_idle_flush_pct
69+
0
70+
set global innodb_idle_flush_pct=100;
71+
select @@global.innodb_idle_flush_pct;
72+
@@global.innodb_idle_flush_pct
73+
100
74+
set global innodb_idle_flush_pct=DEFAULT;
75+
select @@global.innodb_idle_flush_pct;
76+
@@global.innodb_idle_flush_pct
77+
100
78+
SET @@global.innodb_idle_flush_pct = @start_global_value;
79+
SELECT @@global.innodb_idle_flush_pct;
80+
@@global.innodb_idle_flush_pct
81+
100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#
2+
# Basic test for innodb_idle_flush_pct
3+
#
4+
5+
SET @start_global_value = @@global.innodb_idle_flush_pct;
6+
SELECT @start_global_value;
7+
8+
#
9+
# exists as global only
10+
#
11+
--echo Valid values are between 0 and 100
12+
select @@global.innodb_idle_flush_pct between 0 and 100;
13+
select @@global.innodb_idle_flush_pct;
14+
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
15+
select @@session.innodb_idle_flush_pct;
16+
show global variables like 'innodb_idle_flush_pct';
17+
show session variables like 'innodb_idle_flush_pct';
18+
select * from performance_schema.global_variables where variable_name='innodb_idle_flush_pct';
19+
select * from performance_schema.session_variables where variable_name='innodb_idle_flush_pct';
20+
21+
#
22+
# show that it's writable
23+
#
24+
set global innodb_idle_flush_pct=10;
25+
select @@global.innodb_idle_flush_pct;
26+
select * from performance_schema.global_variables where variable_name='innodb_idle_flush_pct';
27+
select * from performance_schema.session_variables where variable_name='innodb_idle_flush_pct';
28+
--error ER_GLOBAL_VARIABLE
29+
set session innodb_idle_flush_pct=1;
30+
31+
#
32+
# incorrect types
33+
#
34+
--error ER_WRONG_TYPE_FOR_VAR
35+
set global innodb_idle_flush_pct=1.1;
36+
--error ER_WRONG_TYPE_FOR_VAR
37+
set global innodb_idle_flush_pct=1e1;
38+
--error ER_WRONG_TYPE_FOR_VAR
39+
set global innodb_idle_flush_pct="bar";
40+
--error ER_WRONG_TYPE_FOR_VAR
41+
set global innodb_idle_flush_pct=ON;
42+
--error ER_WRONG_TYPE_FOR_VAR
43+
set global innodb_idle_flush_pct=OFF;
44+
45+
set global innodb_idle_flush_pct=-7;
46+
select @@global.innodb_idle_flush_pct;
47+
select * from performance_schema.global_variables where variable_name='innodb_idle_flush_pct';
48+
set global innodb_idle_flush_pct=101;
49+
select @@global.innodb_idle_flush_pct;
50+
select * from performance_schema.global_variables where variable_name='innodb_idle_flush_pct';
51+
52+
#
53+
# min/max/DEFAULT values
54+
#
55+
set global innodb_idle_flush_pct=0;
56+
select @@global.innodb_idle_flush_pct;
57+
set global innodb_idle_flush_pct=100;
58+
select @@global.innodb_idle_flush_pct;
59+
set global innodb_idle_flush_pct=DEFAULT;
60+
select @@global.innodb_idle_flush_pct;
61+
62+
# Cleanup
63+
SET @@global.innodb_idle_flush_pct = @start_global_value;
64+
SELECT @@global.innodb_idle_flush_pct;

mysql-test/t/all_persisted_variables.test

+1-1
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=380;
42+
let $total_persistent_vars=381;
4343

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

storage/innobase/buf/buf0flu.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -3199,9 +3199,9 @@ static void buf_flush_page_coordinator_thread(size_t n_page_cleaners) {
31993199
MONITOR_FLUSH_ADAPTIVE_PAGES, n_flushed_list);
32003200
}
32013201

3202-
} else if (ret_sleep == OS_SYNC_TIME_EXCEEDED) {
3202+
} else if (ret_sleep == OS_SYNC_TIME_EXCEEDED && srv_idle_flush_pct) {
32033203
/* no activity, slept enough */
3204-
buf_flush_lists(PCT_IO(100), LSN_MAX, &n_flushed);
3204+
buf_flush_lists(PCT_IO(srv_idle_flush_pct), LSN_MAX, &n_flushed);
32053205

32063206
n_flushed_last += n_flushed;
32073207

storage/innobase/handler/ha_innodb.cc

+7
Original file line numberDiff line numberDiff line change
@@ -21442,6 +21442,12 @@ static MYSQL_SYSVAR_ULONG(
2144221442
"Dump only the hottest N% of each buffer pool, defaults to 25", NULL, NULL,
2144321443
25, 1, 100, 0);
2144421444

21445+
static MYSQL_SYSVAR_ULONG(
21446+
idle_flush_pct, srv_idle_flush_pct, PLUGIN_VAR_RQCMDARG,
21447+
"Up to what percentage of dirty pages to be flushed when server is found"
21448+
" idle.",
21449+
NULL, NULL, srv_idle_flush_pct_default, 0, 100, 0);
21450+
2144521451
#ifdef UNIV_DEBUG
2144621452
static MYSQL_SYSVAR_STR(buffer_pool_evict, srv_buffer_pool_evict,
2144721453
PLUGIN_VAR_RQCMDARG, "Evict pages from the buffer pool",
@@ -22340,6 +22346,7 @@ static SYS_VAR *innobase_system_variables[] = {
2234022346

2234122347
MYSQL_SYSVAR(io_capacity),
2234222348
MYSQL_SYSVAR(io_capacity_max),
22349+
MYSQL_SYSVAR(idle_flush_pct),
2234322350
MYSQL_SYSVAR(page_cleaners),
2234422351
MYSQL_SYSVAR(monitor_enable),
2234522352
MYSQL_SYSVAR(monitor_disable),

storage/innobase/include/srv0srv.h

+5
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,11 @@ extern ulong srv_n_write_io_threads;
566566

567567
extern uint srv_change_buffer_max_size;
568568

569+
/** Default value of srv_idle_flush_pct */
570+
extern const ulong srv_idle_flush_pct_default;
571+
/** How much flush to be done in case of server is idle */
572+
extern ulong srv_idle_flush_pct;
573+
569574
/* Number of IO operations per second the server can do */
570575
extern ulong srv_io_capacity;
571576

storage/innobase/srv/srv0srv.cc

+3
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,9 @@ ulong srv_buf_pool_dump_pct;
405405
/** Lock table size in bytes */
406406
ulint srv_lock_table_size = ULINT_MAX;
407407

408+
const ulong srv_idle_flush_pct_default = 100;
409+
ulong srv_idle_flush_pct = srv_idle_flush_pct_default;
410+
408411
/* This parameter is deprecated. Use srv_n_io_[read|write]_threads
409412
instead. */
410413
ulong srv_n_read_io_threads;

0 commit comments

Comments
 (0)