Skip to content

Commit

Permalink
MDEV-6932: Enable Lazy Flushing
Browse files Browse the repository at this point in the history
Merge Facebook commit 4f3e0343fd2ac3fc7311d0ec9739a8f668274f0d
authored by Steaphan Greene from https://github.com/facebook/mysql-5.6

Adds innodb_idle_flush_pct to enable tuning of the page flushing rate
when the system is relatively idle. We care about this, since doing
extra unnecessary flash writes shortens the lifespan of the flash.
  • Loading branch information
Jan Lindström committed Oct 29, 2014
1 parent 58888e2 commit 2bf3e41
Show file tree
Hide file tree
Showing 11 changed files with 189 additions and 22 deletions.
77 changes: 77 additions & 0 deletions mysql-test/suite/sys_vars/r/innodb_idle_flush_pct_basic.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
SET @start_global_value = @@global.innodb_idle_flush_pct;
SELECT @start_global_value;
@start_global_value
100
Valid values are between 0 and 100
select @@global.innodb_idle_flush_pct between 0 and 100;
@@global.innodb_idle_flush_pct between 0 and 100
1
select @@global.innodb_idle_flush_pct;
@@global.innodb_idle_flush_pct
100
select @@session.innodb_idle_flush_pct;
ERROR HY000: Variable 'innodb_idle_flush_pct' is a GLOBAL variable
show global variables like 'innodb_idle_flush_pct';
Variable_name Value
innodb_idle_flush_pct 100
show session variables like 'innodb_idle_flush_pct';
Variable_name Value
innodb_idle_flush_pct 100
select * from information_schema.global_variables where variable_name='innodb_idle_flush_pct';
VARIABLE_NAME VARIABLE_VALUE
INNODB_IDLE_FLUSH_PCT 100
select * from information_schema.session_variables where variable_name='innodb_idle_flush_pct';
VARIABLE_NAME VARIABLE_VALUE
INNODB_IDLE_FLUSH_PCT 100
set global innodb_idle_flush_pct=10;
select @@global.innodb_idle_flush_pct;
@@global.innodb_idle_flush_pct
10
select * from information_schema.global_variables where variable_name='innodb_idle_flush_pct';
VARIABLE_NAME VARIABLE_VALUE
INNODB_IDLE_FLUSH_PCT 10
select * from information_schema.session_variables where variable_name='innodb_idle_flush_pct';
VARIABLE_NAME VARIABLE_VALUE
INNODB_IDLE_FLUSH_PCT 10
set session innodb_idle_flush_pct=1;
ERROR HY000: Variable 'innodb_idle_flush_pct' is a GLOBAL variable and should be set with SET GLOBAL
set global innodb_idle_flush_pct=1.1;
ERROR 42000: Incorrect argument type to variable 'innodb_idle_flush_pct'
set global innodb_idle_flush_pct=1e1;
ERROR 42000: Incorrect argument type to variable 'innodb_idle_flush_pct'
set global innodb_idle_flush_pct="bar";
ERROR 42000: Incorrect argument type to variable 'innodb_idle_flush_pct'
set global innodb_idle_flush_pct=-7;
Warnings:
Warning 1292 Truncated incorrect innodb_idle_flush_pct value: '-7'
select @@global.innodb_idle_flush_pct;
@@global.innodb_idle_flush_pct
0
select * from information_schema.global_variables where variable_name='innodb_idle_flush_pct';
VARIABLE_NAME VARIABLE_VALUE
INNODB_IDLE_FLUSH_PCT 0
set global innodb_idle_flush_pct=106;
Warnings:
Warning 1292 Truncated incorrect innodb_idle_flush_pct value: '106'
select @@global.innodb_idle_flush_pct;
@@global.innodb_idle_flush_pct
100
select * from information_schema.global_variables where variable_name='innodb_idle_flush_pct';
VARIABLE_NAME VARIABLE_VALUE
INNODB_IDLE_FLUSH_PCT 100
set global innodb_idle_flush_pct=0;
select @@global.innodb_idle_flush_pct;
@@global.innodb_idle_flush_pct
0
set global innodb_idle_flush_pct=100;
select @@global.innodb_idle_flush_pct;
@@global.innodb_idle_flush_pct
100
set global innodb_idle_flush_pct=DEFAULT;
select @@global.innodb_idle_flush_pct;
@@global.innodb_idle_flush_pct
100
SET @@global.innodb_idle_flush_pct = @start_global_value;
SELECT @@global.innodb_idle_flush_pct;
@@global.innodb_idle_flush_pct
100
14 changes: 14 additions & 0 deletions mysql-test/suite/sys_vars/r/sysvars_innodb.result
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,20 @@ NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME INNODB_IDLE_FLUSH_PCT
SESSION_VALUE NULL
GLOBAL_VALUE 100
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE 100
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Up to what percentage of dirty pages should be flushed when innodb finds it has spare resources to do so.
NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 100
NUMERIC_BLOCK_SIZE 0
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME INNODB_IO_CAPACITY
SESSION_VALUE NULL
GLOBAL_VALUE 200
Expand Down
63 changes: 63 additions & 0 deletions mysql-test/suite/sys_vars/t/innodb_idle_flush_pct_basic.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@

#
# 2013-04-01 - Added
#

--source include/have_innodb.inc

SET @start_global_value = @@global.innodb_idle_flush_pct;
SELECT @start_global_value;

#
# exists as global only
#
--echo Valid values are between 0 and 100
select @@global.innodb_idle_flush_pct between 0 and 100;
select @@global.innodb_idle_flush_pct;
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
select @@session.innodb_idle_flush_pct;
show global variables like 'innodb_idle_flush_pct';
show session variables like 'innodb_idle_flush_pct';
select * from information_schema.global_variables where variable_name='innodb_idle_flush_pct';
select * from information_schema.session_variables where variable_name='innodb_idle_flush_pct';

#
# show that it's writable
#
set global innodb_idle_flush_pct=10;
select @@global.innodb_idle_flush_pct;
select * from information_schema.global_variables where variable_name='innodb_idle_flush_pct';
select * from information_schema.session_variables where variable_name='innodb_idle_flush_pct';
--error ER_GLOBAL_VARIABLE
set session innodb_idle_flush_pct=1;

#
# incorrect types
#
--error ER_WRONG_TYPE_FOR_VAR
set global innodb_idle_flush_pct=1.1;
--error ER_WRONG_TYPE_FOR_VAR
set global innodb_idle_flush_pct=1e1;
--error ER_WRONG_TYPE_FOR_VAR
set global innodb_idle_flush_pct="bar";

set global innodb_idle_flush_pct=-7;
select @@global.innodb_idle_flush_pct;
select * from information_schema.global_variables where variable_name='innodb_idle_flush_pct';
set global innodb_idle_flush_pct=106;
select @@global.innodb_idle_flush_pct;
select * from information_schema.global_variables where variable_name='innodb_idle_flush_pct';

#
# min/max/DEFAULT values
#
set global innodb_idle_flush_pct=0;
select @@global.innodb_idle_flush_pct;
set global innodb_idle_flush_pct=100;
select @@global.innodb_idle_flush_pct;
set global innodb_idle_flush_pct=DEFAULT;
select @@global.innodb_idle_flush_pct;


SET @@global.innodb_idle_flush_pct = @start_global_value;
SELECT @@global.innodb_idle_flush_pct;
17 changes: 5 additions & 12 deletions storage/innobase/buf/buf0flu.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2444,27 +2444,17 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(

while (srv_shutdown_state == SRV_SHUTDOWN_NONE) {

/* The page_cleaner skips sleep if the server is
idle and there are no pending IOs in the buffer pool
and there is work to do. */
if (srv_check_activity(last_activity)
|| buf_get_n_pending_read_ios()
|| n_flushed == 0) {
page_cleaner_sleep_if_needed(next_loop_time);
}
page_cleaner_sleep_if_needed(next_loop_time);

next_loop_time = ut_time_ms() + 1000;

if (srv_check_activity(last_activity)) {
last_activity = srv_get_activity_count();

/* Flush pages from end of LRU if required */
n_flushed = buf_flush_LRU_tail();

/* Flush pages from flush_list if required */
n_flushed += page_cleaner_flush_pages_if_needed();

} else {
} else if (srv_idle_flush_pct) {
n_flushed = page_cleaner_do_flush_batch(
PCT_IO(100),
LSN_MAX);
Expand All @@ -2477,6 +2467,9 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
n_flushed);
}
}

/* Flush pages from end of LRU if required */
buf_flush_LRU_tail();
}

ut_ad(srv_shutdown_state > 0);
Expand Down
8 changes: 8 additions & 0 deletions storage/innobase/handler/ha_innodb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17891,6 +17891,13 @@ static MYSQL_SYSVAR_ULONG(io_capacity_max, srv_max_io_capacity,
SRV_MAX_IO_CAPACITY_DUMMY_DEFAULT, 100,
SRV_MAX_IO_CAPACITY_LIMIT, 0);

static MYSQL_SYSVAR_ULONG(idle_flush_pct,
srv_idle_flush_pct,
PLUGIN_VAR_RQCMDARG,
"Up to what percentage of dirty pages should be flushed when innodb "
"finds it has spare resources to do so.",
NULL, NULL, 100, 0, 100, 0);

#ifdef UNIV_DEBUG
static MYSQL_SYSVAR_BOOL(purge_run_now, innodb_purge_run_now,
PLUGIN_VAR_OPCMDARG,
Expand Down Expand Up @@ -18920,6 +18927,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(read_only),
MYSQL_SYSVAR(io_capacity),
MYSQL_SYSVAR(io_capacity_max),
MYSQL_SYSVAR(idle_flush_pct),
MYSQL_SYSVAR(monitor_enable),
MYSQL_SYSVAR(monitor_disable),
MYSQL_SYSVAR(monitor_reset),
Expand Down
2 changes: 2 additions & 0 deletions storage/innobase/include/srv0srv.h
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,8 @@ extern double srv_defragment_fill_factor;
extern uint srv_defragment_frequency;
extern ulonglong srv_defragment_interval;

extern ulint srv_idle_flush_pct;

/* Number of IO operations per second the server can do */
extern ulong srv_io_capacity;

Expand Down
2 changes: 2 additions & 0 deletions storage/innobase/srv/srv0srv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ UNIV_INTERN ulint srv_buf_pool_curr_size = 0;
UNIV_INTERN ulint srv_mem_pool_size = ULINT_MAX;
UNIV_INTERN ulint srv_lock_table_size = ULINT_MAX;

UNIV_INTERN ulint srv_idle_flush_pct = 100;

/* This parameter is deprecated. Use srv_n_io_[read|write]_threads
instead. */
UNIV_INTERN ulint srv_n_file_io_threads = ULINT_MAX;
Expand Down
16 changes: 6 additions & 10 deletions storage/xtradb/buf/buf0flu.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2736,14 +2736,7 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(

srv_current_thread_priority = srv_cleaner_thread_priority;

/* The page_cleaner skips sleep if the server is
idle and there are no pending IOs in the buffer pool
and there is work to do. */
if (srv_check_activity(last_activity)
|| buf_get_n_pending_read_ios()
|| n_flushed == 0) {
page_cleaner_sleep_if_needed(next_loop_time);
}
page_cleaner_sleep_if_needed(next_loop_time);

page_cleaner_sleep_time
= page_cleaner_adapt_flush_sleep_time();
Expand All @@ -2761,8 +2754,8 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
}

/* Flush pages from flush_list if required */
n_flushed += page_cleaner_flush_pages_if_needed();
} else {
page_cleaner_flush_pages_if_needed();
} else if (srv_idle_flush_pct) {
n_flushed = page_cleaner_do_flush_batch(
PCT_IO(100),
LSN_MAX);
Expand All @@ -2775,6 +2768,9 @@ DECLARE_THREAD(buf_flush_page_cleaner_thread)(
n_flushed);
}
}

/* Flush pages from end of LRU if required */
buf_flush_LRU_tail();
}

ut_ad(srv_shutdown_state > 0);
Expand Down
8 changes: 8 additions & 0 deletions storage/xtradb/handler/ha_innodb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18970,6 +18970,13 @@ static MYSQL_SYSVAR_ULONG(io_capacity_max, srv_max_io_capacity,
SRV_MAX_IO_CAPACITY_DUMMY_DEFAULT, 100,
SRV_MAX_IO_CAPACITY_LIMIT, 0);

static MYSQL_SYSVAR_ULONG(idle_flush_pct,
srv_idle_flush_pct,
PLUGIN_VAR_RQCMDARG,
"Up to what percentage of dirty pages should be flushed when innodb "
"finds it has spare resources to do so.",
NULL, NULL, 100, 0, 100, 0);

#ifdef UNIV_DEBUG
static MYSQL_SYSVAR_BOOL(purge_run_now, innodb_purge_run_now,
PLUGIN_VAR_OPCMDARG,
Expand Down Expand Up @@ -20224,6 +20231,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(read_only),
MYSQL_SYSVAR(io_capacity),
MYSQL_SYSVAR(io_capacity_max),
MYSQL_SYSVAR(idle_flush_pct),
MYSQL_SYSVAR(monitor_enable),
MYSQL_SYSVAR(monitor_disable),
MYSQL_SYSVAR(monitor_reset),
Expand Down
2 changes: 2 additions & 0 deletions storage/xtradb/include/srv0srv.h
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,8 @@ extern double srv_defragment_fill_factor;
extern uint srv_defragment_frequency;
extern ulonglong srv_defragment_interval;

extern ulint srv_idle_flush_pct;

/* Number of IO operations per second the server can do */
extern ulong srv_io_capacity;

Expand Down
2 changes: 2 additions & 0 deletions storage/xtradb/srv/srv0srv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,8 @@ UNIV_INTERN ulong srv_cleaner_lsn_age_factor
UNIV_INTERN ulong srv_empty_free_list_algorithm
= SRV_EMPTY_FREE_LIST_BACKOFF;

UNIV_INTERN ulint srv_idle_flush_pct = 100;

/* This parameter is deprecated. Use srv_n_io_[read|write]_threads
instead. */
UNIV_INTERN ulint srv_n_file_io_threads = ULINT_MAX;
Expand Down

0 comments on commit 2bf3e41

Please sign in to comment.